diff options
author | Luca Bruno <lucabru@src.gnome.org> | 2014-02-02 23:14:28 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2019-03-11 13:52:38 +0100 |
commit | 539680494f4c1fc2eff5efd6fae78296ba8d601e (patch) | |
tree | a1b6f8651bfeb226618de0f177591de0cbd44e90 | |
parent | e0586aacdf7611cc69a85c4a9cce72f5b064cc49 (diff) | |
download | vala-539680494f4c1fc2eff5efd6fae78296ba8d601e.tar.gz |
Factorize some common code with convenient api. Fix do-while loops
-rw-r--r-- | codegen/valaccodetransformer.vala | 109 | ||||
-rw-r--r-- | vala/valacodebuilder.vala | 2 | ||||
-rw-r--r-- | vala/valacodetransformer.vala | 52 |
3 files changed, 82 insertions, 81 deletions
diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala index 8504c489b..cca398826 100644 --- a/codegen/valaccodetransformer.vala +++ b/codegen/valaccodetransformer.vala @@ -165,12 +165,12 @@ public class Vala.CCodeTransformer : CodeTransformer { public override void visit_while_statement (WhileStatement stmt) { // convert to simple loop - push_builder (new CodeBuilder (context, stmt, stmt.source_reference)); - Expression cond = null; + begin_replace_statement (stmt); + if (!always_false (stmt.condition)) { b.open_loop (); if (!always_true (stmt.condition)) { - cond = expression (@"!$(stmt.condition)"); + var cond = expression (@"!$(stmt.condition)"); b.open_if (cond); b.add_break (); b.close (); @@ -179,18 +179,13 @@ public class Vala.CCodeTransformer : CodeTransformer { b.close (); } - var parent_block = context.analyzer.get_current_block (stmt); - context.analyzer.replaced_nodes.add (stmt); - parent_block.replace_statement (stmt, new EmptyStatement (stmt.source_reference)); - stmt.body.checked = false; - b.check (this); - pop_builder (); + end_replace_statement (); } public override void visit_do_statement (DoStatement stmt) { // convert to simple loop - push_builder (new CodeBuilder (context, stmt, stmt.source_reference)); + begin_replace_statement (stmt); b.open_loop (); // do not generate variable and if block if condition is always true @@ -204,21 +199,16 @@ public class Vala.CCodeTransformer : CodeTransformer { b.add_assignment (expression (notfirst), expression ("true")); b.close (); } + stmt.body.checked = false; b.add_statement (stmt.body); b.close (); - var parent_block = context.analyzer.get_current_block (stmt); - context.analyzer.replaced_nodes.add (stmt); - parent_block.replace_statement (stmt, new EmptyStatement (stmt.source_reference)); - - stmt.body.checked = false; - b.check (this); - pop_builder (); + end_replace_statement (); } public override void visit_for_statement (ForStatement stmt) { // convert to simple loop - push_builder (new CodeBuilder (context, stmt, stmt.source_reference)); + begin_replace_statement (stmt); // initializer foreach (var init_expr in stmt.get_initializer ()) { @@ -246,17 +236,13 @@ public class Vala.CCodeTransformer : CodeTransformer { b.close (); } - var parent_block = context.analyzer.get_current_block (stmt); - context.analyzer.replaced_nodes.add (stmt); - parent_block.replace_statement (stmt, new EmptyStatement (stmt.source_reference)); - stmt.body.checked = false; - b.check (this); - pop_builder (); + end_replace_statement (); } public override void visit_foreach_statement (ForeachStatement stmt) { - push_builder (new CodeBuilder (context, stmt, stmt.source_reference)); + begin_replace_statement (stmt); + var collection = b.add_temp_declaration (stmt.collection.value_type, stmt.collection); stmt.body.remove_local_variable (stmt.element_variable); @@ -311,13 +297,8 @@ public class Vala.CCodeTransformer : CodeTransformer { b.add_statement (stmt.body); b.close (); - var parent_block = context.analyzer.get_current_block (stmt); - context.analyzer.replaced_nodes.add (stmt); - parent_block.replace_statement (stmt, new EmptyStatement (stmt.source_reference)); - stmt.body.checked = false; - b.check (this); - pop_builder (); + end_replace_statement (); } public override void visit_break_statement (BreakStatement stmt) { @@ -372,20 +353,14 @@ public class Vala.CCodeTransformer : CodeTransformer { // can't handle errors in field initializers Report.error (expr.source_reference, "Field initializers must not throw errors"); } else { - // store parent_node as we need to replace the expression in the old parent node later on - var old_parent_node = expr.parent_node; var formal_target_type = copy_type (expr.target_type); var target_type = copy_type (expr.target_type); - push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); + begin_replace_expression (expr); var local = b.add_temp_declaration (copy_type (expr.value_type), expr); var replacement = return_temp_access (local, expr.value_type, target_type, formal_target_type); - context.analyzer.replaced_nodes.add (expr); - old_parent_node.replace_expression (expr, replacement); - b.check (this); - pop_builder (); - check (replacement); + end_replace_expression (replacement); } } } @@ -393,10 +368,9 @@ public class Vala.CCodeTransformer : CodeTransformer { public override void visit_conditional_expression (ConditionalExpression expr) { // convert to if statement Expression replacement = null; - var old_parent_node = expr.parent_node; var formal_target_type = copy_type (expr.target_type); var target_type = copy_type (expr.target_type); - push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); + begin_replace_expression (expr); var result = b.add_temp_declaration (expr.value_type); b.open_if (expr.condition); @@ -406,11 +380,7 @@ public class Vala.CCodeTransformer : CodeTransformer { b.close (); replacement = return_temp_access (result, expr.value_type, target_type, formal_target_type); - context.analyzer.replaced_nodes.add (expr); - old_parent_node.replace_expression (expr, replacement); - b.check (this); - pop_builder (); - check (replacement); + end_replace_expression (replacement); } public override void visit_binary_expression (BinaryExpression expr) { @@ -421,9 +391,8 @@ public class Vala.CCodeTransformer : CodeTransformer { } Expression replacement = null; - var old_parent_node = expr.parent_node; var target_type = copy_type (expr.target_type); - push_builder (new CodeBuilder (context, parent_statement, expr.source_reference)); + begin_replace_expression (expr); if (context.analyzer.get_current_non_local_symbol (expr) is Block && (expr.operator == BinaryOperator.AND || expr.operator == BinaryOperator.OR)) { @@ -460,13 +429,9 @@ public class Vala.CCodeTransformer : CodeTransformer { if (replacement != null) { replacement.target_type = target_type; - context.analyzer.replaced_nodes.add (expr); - old_parent_node.replace_expression (expr, replacement); - b.check (this); - pop_builder (); - check (replacement); + end_replace_expression (replacement); } else { - pop_builder (); + end_replace_expression (null); base.visit_binary_expression (expr); } } @@ -479,10 +444,9 @@ public class Vala.CCodeTransformer : CodeTransformer { } if (expr.operator == UnaryOperator.INCREMENT || expr.operator == UnaryOperator.DECREMENT) { - var old_parent_node = expr.parent_node; - var target_type = expr.target_type != null ? expr.target_type.copy () : null; + var target_type = copy_type (expr.target_type); + begin_replace_expression (expr); - push_builder (new CodeBuilder (context, parent_statement, expr.source_reference)); Expression replacement; if (expr.operator == UnaryOperator.INCREMENT) { replacement = expression (@"$(expr.inner) = $(expr.inner) + 1"); @@ -490,12 +454,8 @@ public class Vala.CCodeTransformer : CodeTransformer { replacement = expression (@"$(expr.inner) = $(expr.inner) - 1"); } replacement.target_type = target_type; - context.analyzer.replaced_nodes.add (expr); - old_parent_node.replace_expression (expr, replacement); - b.check (this); - pop_builder (); - check (replacement); + end_replace_expression (replacement); return; } @@ -510,19 +470,14 @@ public class Vala.CCodeTransformer : CodeTransformer { // can't handle errors in field initializers Report.error (expr.source_reference, "Field initializers must not throw errors"); } else { - var old_parent_node = expr.parent_node; var target_type = copy_type (expr.target_type); var formal_target_type = copy_type (expr.formal_target_type); - push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); + begin_replace_expression (expr); var local = b.add_temp_declaration (expr.value_type, expr); var replacement = return_temp_access (local, expr.value_type, target_type, formal_target_type); - context.analyzer.replaced_nodes.add (expr); - old_parent_node.replace_expression (expr, replacement); - b.check (this); - pop_builder (); - check (replacement); + end_replace_expression (replacement); } } } @@ -536,7 +491,7 @@ public class Vala.CCodeTransformer : CodeTransformer { } public override void visit_template (Template expr) { - push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); + begin_replace_expression (expr); Expression replacement; @@ -555,15 +510,11 @@ public class Vala.CCodeTransformer : CodeTransformer { } replacement.target_type = expr.target_type; - context.analyzer.replaced_nodes.add (expr); - expr.parent_node.replace_expression (expr, replacement); - b.check (this); - pop_builder (); - check (replacement); + end_replace_expression (replacement); } public override void visit_postfix_expression (PostfixExpression expr) { - push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); + begin_replace_expression (expr); var result = b.add_temp_declaration (copy_type (expr.value_type), expr.inner); var op = expr.increment ? "+ 1" : "- 1"; @@ -571,11 +522,7 @@ public class Vala.CCodeTransformer : CodeTransformer { var replacement = return_temp_access (result, expr.value_type, expr.target_type); - context.analyzer.replaced_nodes.add (expr); - expr.parent_node.replace_expression (expr, replacement); - b.check (this); - pop_builder (); - check (replacement); + end_replace_expression (replacement); } public override void visit_assignment (Assignment a) { diff --git a/vala/valacodebuilder.vala b/vala/valacodebuilder.vala index 2e52c8b6b..ab174ffb9 100644 --- a/vala/valacodebuilder.vala +++ b/vala/valacodebuilder.vala @@ -30,6 +30,8 @@ public class Vala.CodeBuilder { public ArrayList<CodeNode> decl_nodes = new ArrayList<CodeNode> (); public SourceReference source_reference; + public void* replaced = null; + public CodeBuilder (CodeContext context, Statement insert_statement, SourceReference source_reference) { this.source_reference = source_reference; diff --git a/vala/valacodetransformer.vala b/vala/valacodetransformer.vala index 5799ca2ef..b7b829737 100644 --- a/vala/valacodetransformer.vala +++ b/vala/valacodetransformer.vala @@ -46,6 +46,58 @@ public class Vala.CodeTransformer : CodeVisitor { builder_stack.remove_at (builder_stack.size - 1); } + class ReplaceStatementData { + internal Statement stmt; + internal Block parent_block; + } + + public void begin_replace_statement (Statement stmt) { + push_builder (new CodeBuilder (context, stmt, stmt.source_reference)); + + var data = new ReplaceStatementData (); + data.stmt = stmt; + data.parent_block = context.analyzer.get_current_block (stmt); + b.replaced = (owned) data; + } + + public void end_replace_statement () { + var data = (ReplaceStatementData) (owned) b.replaced; + + context.analyzer.replaced_nodes.add (data.stmt); + data.parent_block.replace_statement (data.stmt, new EmptyStatement (data.stmt.source_reference)); + + b.check (this); + pop_builder (); + } + + class ReplaceExpressionData { + internal Expression expr; + internal CodeNode parent_node; + } + + public void begin_replace_expression (owned Expression expr) { + push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); + + var data = new ReplaceExpressionData (); + data.expr = expr; + data.parent_node = expr.parent_node; + b.replaced = (owned) data; + } + + public void end_replace_expression (Expression? replacement) { + var data = (ReplaceExpressionData) (owned) b.replaced; + + if (replacement != null) { + context.analyzer.replaced_nodes.add (data.expr); + data.parent_node.replace_expression (data.expr, replacement); + b.check (this); + } + pop_builder (); + if (replacement != null) { + check (replacement); + } + } + /** * Transform the code tree for the specified code context. * |