3 * Copyright (C) 2006-2008 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
27 * Represents a source code block.
29 public class Vala
.Block
: Symbol
, Statement
{
31 * Specifies whether this block contains a jump statement. This
32 * information can be used to remove unreachable block cleanup code.
34 public bool contains_jump_statement
{ get; set; }
36 private Gee
.List
<Statement
> statement_list
= new ArrayList
<Statement
> ();
37 private Gee
.List
<LocalVariable
> local_variables
= new ArrayList
<LocalVariable
> ();
40 * Creates a new block.
42 * @param source reference to source code
44 public Block (SourceReference source_reference
) {
45 base (null, source_reference
);
49 * Append a statement to this block.
51 * @param stmt a statement
53 public void add_statement (Statement stmt
) {
54 statement_list
.add (stmt
);
57 public void insert_statement (int index
, Statement stmt
) {
58 statement_list
.insert (index
, stmt
);
62 * Returns a copy of the list of statements.
64 * @return statement list
66 public Gee
.List
<Statement
> get_statements () {
67 var list
= new ArrayList
<Statement
> ();
68 foreach (Statement stmt
in statement_list
) {
69 var stmt_list
= stmt as StatementList
;
70 if (stmt_list
!= null) {
71 for (int i
= 0; i
< stmt_list
.length
; i
++) {
72 list
.add (stmt_list
.get (i
));
82 * Add a local variable to this block.
84 * @param decl a variable declarator
86 public void add_local_variable (LocalVariable local
) {
87 var parent_block
= parent_symbol
;
88 while (parent_block is Block
|| parent_block is Method
) {
89 if (parent_block
.scope
.lookup (local
.name
) != null) {
90 Report
.error (local
.source_reference
, "Local variable `%s' conflicts with another local variable declared in a parent scope".printf (local
.name
));
93 parent_block
= parent_block
.parent_symbol
;
95 local_variables
.add (local
);
98 public void remove_local_variable (LocalVariable local
) {
99 local_variables
.remove (local
);
103 * Returns a copy of the list of local variables.
105 * @return variable declarator list
107 public Gee
.List
<LocalVariable
> get_local_variables () {
108 return new ReadOnlyList
<LocalVariable
> (local_variables
);
111 public override void accept (CodeVisitor visitor
) {
112 visitor
.visit_block (this
);
115 public override void accept_children (CodeVisitor visitor
) {
116 foreach (Statement stmt
in statement_list
) {
117 stmt
.accept (visitor
);
121 public override bool check (SemanticAnalyzer analyzer
) {
128 owner
= analyzer
.current_symbol
.scope
;
130 var old_symbol
= analyzer
.current_symbol
;
131 var old_insert_block
= analyzer
.insert_block
;
132 analyzer
.current_symbol
= this
;
133 analyzer
.insert_block
= this
;
135 for (int i
= 0; i
< statement_list
.size
; i
++) {
136 statement_list
[i
].check (analyzer
);
139 foreach (LocalVariable local
in get_local_variables ()) {
140 local
.active
= false;
143 foreach (Statement stmt
in statement_list
) {
144 add_error_types (stmt
.get_error_types ());
147 analyzer
.current_symbol
= old_symbol
;
148 analyzer
.insert_block
= old_insert_block
;
153 public void insert_before (Statement stmt
, Statement new_stmt
) {
154 for (int i
= 0; i
< statement_list
.size
; i
++) {
155 var stmt_list
= statement_list
[i
] as StatementList
;
156 if (stmt_list
!= null) {
157 for (int j
= 0; j
< stmt_list
.length
; j
++) {
158 if (stmt_list
.get (j
) == stmt
) {
159 stmt_list
.insert (j
, new_stmt
);
163 } else if (statement_list
[i
] == stmt
) {
164 stmt_list
= new
StatementList (source_reference
);
165 stmt_list
.add (new_stmt
);
166 stmt_list
.add (stmt
);
167 statement_list
[i
] = stmt_list
;
172 public void replace_statement (Statement old_stmt
, Statement new_stmt
) {
173 for (int i
= 0; i
< statement_list
.size
; i
++) {
174 var stmt_list
= statement_list
[i
] as StatementList
;
175 if (stmt_list
!= null) {
176 for (int j
= 0; j
< stmt_list
.length
; j
++) {
177 if (stmt_list
.get (j
) == old_stmt
) {
178 stmt_list
.set (j
, new_stmt
);
182 } else if (statement_list
[i
] == old_stmt
) {
183 statement_list
[i
] = new_stmt
;