vala r894 - in trunk: . compiler gobject tests vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r894 - in trunk: . compiler gobject tests vala
- Date: Wed, 23 Jan 2008 15:26:08 +0000 (GMT)
Author: juergbi
Date: Wed Jan 23 15:26:07 2008
New Revision: 894
URL: http://svn.gnome.org/viewvc/vala?rev=894&view=rev
Log:
2008-01-23 Juerg Billeter <j bitron ch>
* vala/Makefile.am, vala/valabasicblock.vala, vala/valacfgbuilder.vala,
vala/valadostatement.vala, vala/valaforstatement.vala,
vala/valaifstatement.vala, vala/valamemorymanager.vala,
vala/valamethod.vala, vala/valasemanticanalyzer.vala,
vala/valasymbolresolver.vala, vala/valawhilestatement.vala,
gobject/valaccodegenerator.vala, compiler/valacompiler.vala: build
control flow graph, report error for missing return statement in
non-void methods, and report warning for unreachable code,
fixes bug 508480
* tests/exceptions.vala: add missing return statement
Added:
trunk/vala/valabasicblock.vala
trunk/vala/valacfgbuilder.vala
Modified:
trunk/ChangeLog
trunk/compiler/valacompiler.vala
trunk/gobject/valaccodegenerator.vala
trunk/tests/exceptions.vala
trunk/vala/Makefile.am
trunk/vala/valadostatement.vala
trunk/vala/valaforstatement.vala
trunk/vala/valaifstatement.vala
trunk/vala/valamemorymanager.vala
trunk/vala/valamethod.vala
trunk/vala/valasemanticanalyzer.vala
trunk/vala/valasymbolresolver.vala
trunk/vala/valawhilestatement.vala
Modified: trunk/compiler/valacompiler.vala
==============================================================================
--- trunk/compiler/valacompiler.vala (original)
+++ trunk/compiler/valacompiler.vala Wed Jan 23 15:26:07 2008
@@ -269,6 +269,13 @@
return quit ();
}
+ var cfg_builder = new CFGBuilder ();
+ cfg_builder.build_cfg (context);
+
+ if (Report.get_errors () > 0) {
+ return quit ();
+ }
+
var memory_manager = new MemoryManager ();
memory_manager.analyze (context);
Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala (original)
+++ trunk/gobject/valaccodegenerator.vala Wed Jan 23 15:26:07 2008
@@ -1341,6 +1341,8 @@
}
public override void visit_if_statement (IfStatement! stmt) {
+ stmt.accept_children (this);
+
if (stmt.false_statement != null) {
stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
} else {
@@ -1496,18 +1498,24 @@
}
public override void visit_while_statement (WhileStatement! stmt) {
+ stmt.accept_children (this);
+
stmt.ccodenode = new CCodeWhileStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.body.ccodenode);
create_temp_decl (stmt, stmt.condition.temp_vars);
}
public override void visit_do_statement (DoStatement! stmt) {
+ stmt.accept_children (this);
+
stmt.ccodenode = new CCodeDoStatement ((CCodeStatement) stmt.body.ccodenode, (CCodeExpression) stmt.condition.ccodenode);
create_temp_decl (stmt, stmt.condition.temp_vars);
}
public override void visit_for_statement (ForStatement! stmt) {
+ stmt.accept_children (this);
+
var cfor = new CCodeForStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.body.ccodenode);
stmt.ccodenode = cfor;
Modified: trunk/tests/exceptions.vala
==============================================================================
--- trunk/tests/exceptions.vala (original)
+++ trunk/tests/exceptions.vala Wed Jan 23 15:26:07 2008
@@ -23,6 +23,8 @@
foo ();
stdout.printf (" BAD");
+
+ return 0;
}
public void good () throws BarError {
Modified: trunk/vala/Makefile.am
==============================================================================
--- trunk/vala/Makefile.am (original)
+++ trunk/vala/Makefile.am Wed Jan 23 15:26:07 2008
@@ -24,6 +24,7 @@
valaattribute.vala \
valaattributeprocessor.vala \
valabaseaccess.vala \
+ valabasicblock.vala \
valabinaryexpression.vala \
valabindingprovider.vala \
valablock.vala \
@@ -31,6 +32,7 @@
valabreakstatement.vala \
valacastexpression.vala \
valacatchclause.vala \
+ valacfgbuilder.vala \
valacharacterliteral.vala \
valaclass.vala \
valaclasstype.vala \
Added: trunk/vala/valabasicblock.vala
==============================================================================
--- (empty file)
+++ trunk/vala/valabasicblock.vala Wed Jan 23 15:26:07 2008
@@ -0,0 +1,65 @@
+/* valabasicblock.vala
+ *
+ * Copyright (C) 2008 JÃrg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * JÃrg Billeter <j bitron ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * Represents a basic block, i.e. a straight-line piece of code without any
+ * jumps or jump targets.
+ */
+public class Vala.BasicBlock : Object {
+ private Gee.List<CodeNode> nodes = new ArrayList<CodeNode> ();
+
+ private Gee.List<weak BasicBlock> predecessors = new ArrayList<weak BasicBlock> ();
+ private Gee.List<BasicBlock> successors = new ArrayList<BasicBlock> ();
+
+ public BasicBlock () {
+ }
+
+ public BasicBlock.entry () {
+ }
+
+ public BasicBlock.exit () {
+ }
+
+ public void add_node (CodeNode node) {
+ nodes.add (node);
+ }
+
+ public void connect (BasicBlock target) {
+ if (!successors.contains (target)) {
+ successors.add (target);
+ }
+ if (!target.predecessors.contains (this)) {
+ target.predecessors.add (this);
+ }
+ }
+
+ public Gee.List<weak BasicBlock> get_predecessors () {
+ return new ReadOnlyList<weak BasicBlock> (predecessors);
+ }
+
+ public Gee.List<weak BasicBlock> get_successors () {
+ return new ReadOnlyList<weak BasicBlock> (successors);
+ }
+}
Added: trunk/vala/valacfgbuilder.vala
==============================================================================
--- (empty file)
+++ trunk/vala/valacfgbuilder.vala Wed Jan 23 15:26:07 2008
@@ -0,0 +1,395 @@
+/* valacfgbuilder.vala
+ *
+ * Copyright (C) 2008 JÃrg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * JÃrg Billeter <j bitron ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * Code visitor building the control flow graph.
+ */
+public class Vala.CFGBuilder : CodeVisitor {
+ private CodeContext context;
+ private BasicBlock current_block;
+ private bool unreachable_reported;
+ private Method current_method;
+ private Gee.List<BasicBlock> breakable_stack = new ArrayList<BasicBlock> ();
+ private Gee.List<BasicBlock> continuable_stack = new ArrayList<BasicBlock> ();
+
+ public CFGBuilder () {
+ }
+
+ /**
+ * Build control flow graph in the specified context.
+ *
+ * @param context a code context
+ */
+ public void build_cfg (CodeContext! context) {
+ this.context = context;
+
+ /* we're only interested in non-pkg source files */
+ var source_files = context.get_source_files ();
+ foreach (SourceFile file in source_files) {
+ if (!file.pkg) {
+ file.accept (this);
+ }
+ }
+ }
+
+ public override void visit_source_file (SourceFile! source_file) {
+ source_file.accept_children (this);
+ }
+
+ public override void visit_class (Class! cl) {
+ cl.accept_children (this);
+ }
+
+ public override void visit_struct (Struct! st) {
+ st.accept_children (this);
+ }
+
+ public override void visit_interface (Interface! iface) {
+ iface.accept_children (this);
+ }
+
+ public override void visit_enum (Enum! en) {
+ en.accept_children (this);
+ }
+
+ public override void visit_method (Method! m) {
+ if (m.body == null) {
+ return;
+ }
+
+ var old_method = current_method;
+ current_method = m;
+
+ m.entry_block = new BasicBlock.entry ();
+ m.exit_block = new BasicBlock.exit ();
+
+ current_block = new BasicBlock ();
+ m.entry_block.connect (current_block);
+
+ m.accept_children (this);
+
+ if (current_block != null) {
+ // end of method body reachable
+
+ if (!(m.return_type is VoidType)) {
+ Report.error (m.source_reference, "missing return statement at end of method body");
+ m.error = true;
+ }
+
+ current_block.connect (m.exit_block);
+ }
+
+ current_method = old_method;
+ }
+
+ public override void visit_block (Block! b) {
+ b.accept_children (this);
+ }
+
+ public override void visit_declaration_statement (DeclarationStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ current_block.add_node (stmt);
+ }
+
+ public override void visit_expression_statement (ExpressionStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ current_block.add_node (stmt);
+ }
+
+ public override void visit_if_statement (IfStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ // condition
+ current_block.add_node (stmt.condition);
+
+ // true block
+ var last_block = current_block;
+ current_block = new BasicBlock ();
+ last_block.connect (current_block);
+ stmt.true_statement.accept (this);
+
+ // false block
+ var last_true_block = current_block;
+ current_block = new BasicBlock ();
+ last_block.connect (current_block);
+ if (stmt.false_statement != null) {
+ stmt.false_statement.accept (this);
+ }
+
+ // after if/else
+ var last_false_block = current_block;
+ // reachable?
+ if (last_true_block != null || last_false_block != null) {
+ current_block = new BasicBlock ();
+ if (last_true_block != null) {
+ last_true_block.connect (current_block);
+ }
+ if (last_false_block != null) {
+ last_false_block.connect (current_block);
+ }
+ }
+ }
+
+ public override void visit_while_statement (WhileStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ var condition_block = new BasicBlock ();
+ continuable_stack.add (condition_block);
+ var after_loop_block = new BasicBlock ();
+ breakable_stack.add (after_loop_block);
+
+ // condition
+ var last_block = current_block;
+ last_block.connect (condition_block);
+ condition_block.add_node (stmt.condition);
+
+ // loop block
+ current_block = new BasicBlock ();
+ condition_block.connect (current_block);
+ stmt.body.accept (this);
+ // end of loop block reachable?
+ if (current_block != null) {
+ current_block.connect (condition_block);
+ }
+
+ // after loop
+ condition_block.connect (after_loop_block);
+ current_block = after_loop_block;
+
+ continuable_stack.remove_at (continuable_stack.size - 1);
+ breakable_stack.remove_at (breakable_stack.size - 1);
+ }
+
+ public override void visit_do_statement (DoStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ var condition_block = new BasicBlock ();
+ continuable_stack.add (condition_block);
+ var after_loop_block = new BasicBlock ();
+ breakable_stack.add (after_loop_block);
+
+ // loop block
+ var last_block = current_block;
+ var loop_block = new BasicBlock ();
+ last_block.connect (loop_block);
+ current_block = loop_block;
+ stmt.body.accept (this);
+
+ // condition
+ // reachable?
+ if (current_block != null || condition_block.get_predecessors ().size > 0) {
+ if (current_block != null) {
+ last_block = current_block;
+ last_block.connect (condition_block);
+ }
+ condition_block.add_node (stmt.condition);
+ condition_block.connect (loop_block);
+ current_block = condition_block;
+ }
+
+ // after loop
+ // reachable?
+ if (current_block != null || after_loop_block.get_predecessors ().size > 0) {
+ if (current_block != null) {
+ last_block = current_block;
+ last_block.connect (after_loop_block);
+ }
+ current_block = after_loop_block;
+ }
+
+ continuable_stack.remove_at (continuable_stack.size - 1);
+ breakable_stack.remove_at (breakable_stack.size - 1);
+ }
+
+ public override void visit_for_statement (ForStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ // initializer
+ foreach (Expression init_expr in stmt.get_initializer ()) {
+ current_block.add_node (init_expr);
+ }
+
+ var iterator_block = new BasicBlock ();
+ continuable_stack.add (iterator_block);
+ var after_loop_block = new BasicBlock ();
+ breakable_stack.add (after_loop_block);
+
+ // condition
+ var condition_block = new BasicBlock ();
+ current_block.connect (condition_block);
+ condition_block.add_node (stmt.condition);
+
+ // loop block
+ current_block = new BasicBlock ();
+ condition_block.connect (current_block);
+ stmt.body.accept (this);
+
+ // iterator
+ // reachable?
+ if (current_block != null || iterator_block.get_predecessors ().size > 0) {
+ if (current_block != null) {
+ current_block.connect (iterator_block);
+ }
+ foreach (Expression it_expr in stmt.get_iterator ()) {
+ iterator_block.add_node (it_expr);
+ }
+ iterator_block.connect (condition_block);
+ }
+
+ // after loop
+ condition_block.connect (after_loop_block);
+ current_block = after_loop_block;
+
+ continuable_stack.remove_at (continuable_stack.size - 1);
+ breakable_stack.remove_at (breakable_stack.size - 1);
+ }
+
+ public override void visit_foreach_statement (ForeachStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ var loop_block = new BasicBlock ();
+ continuable_stack.add (loop_block);
+ var after_loop_block = new BasicBlock ();
+ breakable_stack.add (after_loop_block);
+
+ // loop block
+ var last_block = current_block;
+ last_block.connect (loop_block);
+ current_block = loop_block;
+ stmt.body.accept (this);
+ if (current_block != null) {
+ current_block.connect (loop_block);
+ }
+
+ // after loop
+ last_block.connect (after_loop_block);
+ if (current_block != null) {
+ current_block.connect (after_loop_block);
+ }
+ current_block = after_loop_block;
+
+ continuable_stack.remove_at (continuable_stack.size - 1);
+ breakable_stack.remove_at (breakable_stack.size - 1);
+ }
+
+ public override void visit_break_statement (BreakStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ current_block.add_node (stmt);
+ current_block.connect (top_breakable ());
+ current_block = null;
+ unreachable_reported = false;
+ }
+
+ public override void visit_continue_statement (ContinueStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ current_block.add_node (stmt);
+ current_block.connect (top_continuable ());
+ current_block = null;
+ unreachable_reported = false;
+ }
+
+ public override void visit_return_statement (ReturnStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ current_block.add_node (stmt);
+ current_block.connect (current_method.exit_block);
+ current_block = null;
+ unreachable_reported = false;
+ }
+
+ public override void visit_throw_statement (ThrowStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ current_block.add_node (stmt);
+ // TODO connect to catch blocks instead of exit block if appropriate
+ current_block.connect (current_method.exit_block);
+ current_block = null;
+ unreachable_reported = false;
+ }
+
+ public override void visit_try_statement (TryStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ stmt.body.accept (this);
+
+ // TODO exceptional control flow
+ }
+
+ public override void visit_lock_statement (LockStatement! stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ stmt.body.accept (this);
+ }
+
+ private bool unreachable (CodeNode node) {
+ if (current_block == null) {
+ if (!unreachable_reported) {
+ Report.warning (node.source_reference, "unreachable code detected");
+ unreachable_reported = true;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ private BasicBlock top_breakable () {
+ return breakable_stack.get (breakable_stack.size - 1);
+ }
+
+ private BasicBlock top_continuable () {
+ return continuable_stack.get (continuable_stack.size - 1);
+ }
+}
Modified: trunk/vala/valadostatement.vala
==============================================================================
--- trunk/vala/valadostatement.vala (original)
+++ trunk/vala/valadostatement.vala Wed Jan 23 15:26:07 2008
@@ -1,6 +1,6 @@
/* valadostatement.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 JÃrg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -65,15 +65,17 @@
*/
public DoStatement (construct Block! body, construct Expression! condition, construct SourceReference source_reference = null) {
}
-
+
public override void accept (CodeVisitor! visitor) {
+ visitor.visit_do_statement (this);
+ }
+
+ public override void accept_children (CodeVisitor! visitor) {
body.accept (visitor);
condition.accept (visitor);
visitor.visit_end_full_expression (condition);
-
- visitor.visit_do_statement (this);
}
public override void replace_expression (Expression! old_node, Expression! new_node) {
Modified: trunk/vala/valaforstatement.vala
==============================================================================
--- trunk/vala/valaforstatement.vala (original)
+++ trunk/vala/valaforstatement.vala Wed Jan 23 15:26:07 2008
@@ -1,6 +1,6 @@
/* valaforstatement.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 JÃrg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -109,6 +109,10 @@
}
public override void accept (CodeVisitor! visitor) {
+ visitor.visit_for_statement (this);
+ }
+
+ public override void accept_children (CodeVisitor! visitor) {
foreach (Expression init_expr in initializer) {
init_expr.accept (visitor);
visitor.visit_end_full_expression (init_expr);
@@ -124,8 +128,6 @@
}
body.accept (visitor);
-
- visitor.visit_for_statement (this);
}
public override void replace_expression (Expression! old_node, Expression! new_node) {
Modified: trunk/vala/valaifstatement.vala
==============================================================================
--- trunk/vala/valaifstatement.vala (original)
+++ trunk/vala/valaifstatement.vala Wed Jan 23 15:26:07 2008
@@ -1,6 +1,6 @@
/* valaifstatement.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 JÃrg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -67,6 +67,10 @@
}
public override void accept (CodeVisitor! visitor) {
+ visitor.visit_if_statement (this);
+ }
+
+ public override void accept_children (CodeVisitor! visitor) {
condition.accept (visitor);
visitor.visit_end_full_expression (condition);
@@ -75,8 +79,6 @@
if (false_statement != null) {
false_statement.accept (visitor);
}
-
- visitor.visit_if_statement (this);
}
public override void replace_expression (Expression! old_node, Expression! new_node) {
Modified: trunk/vala/valamemorymanager.vala
==============================================================================
--- trunk/vala/valamemorymanager.vala (original)
+++ trunk/vala/valamemorymanager.vala Wed Jan 23 15:26:07 2008
@@ -149,10 +149,26 @@
visit_possibly_leaked_expression (stmt.expression);
}
+ public override void visit_if_statement (IfStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
public override void visit_switch_section (SwitchSection! section) {
section.accept_children (this);
}
+ public override void visit_while_statement (WhileStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_do_statement (DoStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_for_statement (ForStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
public override void visit_foreach_statement (ForeachStatement! stmt) {
stmt.accept_children (this);
}
Modified: trunk/vala/valamethod.vala
==============================================================================
--- trunk/vala/valamethod.vala (original)
+++ trunk/vala/valamethod.vala Wed Jan 23 15:26:07 2008
@@ -42,7 +42,11 @@
}
public Block body { get; set; }
-
+
+ public BasicBlock entry_block { get; set; }
+
+ public BasicBlock exit_block { get; set; }
+
/**
* Specifies whether this method may only be called with an instance of
* the contained type.
Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala (original)
+++ trunk/vala/valasemanticanalyzer.vala Wed Jan 23 15:26:07 2008
@@ -858,6 +858,8 @@
}
public override void visit_if_statement (IfStatement! stmt) {
+ stmt.accept_children (this);
+
if (stmt.condition.error) {
/* if there was an error in the condition, skip this check */
stmt.error = true;
@@ -891,6 +893,24 @@
}
public override void visit_while_statement (WhileStatement! stmt) {
+ stmt.accept_children (this);
+
+ if (stmt.condition.error) {
+ /* if there was an error in the condition, skip this check */
+ stmt.error = true;
+ return;
+ }
+
+ if (!stmt.condition.static_type.compatible (bool_type)) {
+ stmt.error = true;
+ Report.error (stmt.condition.source_reference, "Condition must be boolean");
+ return;
+ }
+ }
+
+ public override void visit_do_statement (DoStatement! stmt) {
+ stmt.accept_children (this);
+
if (stmt.condition.error) {
/* if there was an error in the condition, skip this check */
stmt.error = true;
@@ -905,6 +925,8 @@
}
public override void visit_for_statement (ForStatement! stmt) {
+ stmt.accept_children (this);
+
if (stmt.condition.error) {
/* if there was an error in the condition, skip this check */
stmt.error = true;
Modified: trunk/vala/valasymbolresolver.vala
==============================================================================
--- trunk/vala/valasymbolresolver.vala (original)
+++ trunk/vala/valasymbolresolver.vala Wed Jan 23 15:26:07 2008
@@ -322,10 +322,26 @@
list.accept_children (this);
}
+ public override void visit_if_statement (IfStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
public override void visit_switch_section (SwitchSection! section) {
section.accept_children (this);
}
+ public override void visit_while_statement (WhileStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_do_statement (DoStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_for_statement (ForStatement! stmt) {
+ stmt.accept_children (this);
+ }
+
public override void visit_foreach_statement (ForeachStatement! stmt) {
stmt.accept_children (this);
}
Modified: trunk/vala/valawhilestatement.vala
==============================================================================
--- trunk/vala/valawhilestatement.vala (original)
+++ trunk/vala/valawhilestatement.vala Wed Jan 23 15:26:07 2008
@@ -1,6 +1,6 @@
/* valawhilestatement.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 JÃrg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -67,13 +67,15 @@
}
public override void accept (CodeVisitor! visitor) {
+ visitor.visit_while_statement (this);
+ }
+
+ public override void accept_children (CodeVisitor! visitor) {
condition.accept (visitor);
visitor.visit_end_full_expression (condition);
body.accept (visitor);
-
- visitor.visit_while_statement (this);
}
public override void replace_expression (Expression! old_node, Expression! new_node) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]