3 * Copyright (C) 2006-2009 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>
26 * Represents a source code block.
28 public class Vala
.Block
: Symbol
, Statement
{
30 * Specifies whether this block contains a jump statement. This
31 * information can be used to remove unreachable block cleanup code.
33 public bool contains_jump_statement
{ get; set; }
35 public bool captured
{ get; set; }
37 private List
<Statement
> statement_list
= new ArrayList
<Statement
> ();
38 private List
<LocalVariable
> local_variables
= new ArrayList
<LocalVariable
> ();
41 * Creates a new block.
43 * @param source reference to source code
45 public Block (SourceReference source_reference
) {
46 base (null, source_reference
);
50 * Append a statement to this block.
52 * @param stmt a statement
54 public void add_statement (Statement stmt
) {
55 stmt
.parent_node
= this
;
56 statement_list
.add (stmt
);
59 public void insert_statement (int index
, Statement stmt
) {
60 stmt
.parent_node
= this
;
61 statement_list
.insert (index
, stmt
);
65 * Returns a copy of the list of statements.
67 * @return statement list
69 public List
<Statement
> get_statements () {
70 var list
= new ArrayList
<Statement
> ();
71 foreach (Statement stmt
in statement_list
) {
72 var stmt_list
= stmt as StatementList
;
73 if (stmt_list
!= null) {
74 for (int i
= 0; i
< stmt_list
.length
; i
++) {
75 list
.add (stmt_list
.get (i
));
85 * Add a local variable to this block.
87 * @param decl a variable declarator
89 public void add_local_variable (LocalVariable local
) {
90 var parent_block
= parent_symbol
;
91 while (parent_block is Block
|| parent_block is Method
) {
92 if (parent_block
.scope
.lookup (local
.name
) != null) {
93 Report
.error (local
.source_reference
, "Local variable `%s' conflicts with another local variable declared in a parent scope".printf (local
.name
));
96 parent_block
= parent_block
.parent_symbol
;
98 local_variables
.add (local
);
101 public void remove_local_variable (LocalVariable local
) {
102 local_variables
.remove (local
);
106 * Returns a copy of the list of local variables.
108 * @return variable declarator list
110 public List
<LocalVariable
> get_local_variables () {
111 return new ReadOnlyList
<LocalVariable
> (local_variables
);
114 public override void accept (CodeVisitor visitor
) {
115 visitor
.visit_block (this
);
118 public override void accept_children (CodeVisitor visitor
) {
119 foreach (Statement stmt
in statement_list
) {
120 stmt
.accept (visitor
);
124 public override bool check (SemanticAnalyzer analyzer
) {
131 owner
= analyzer
.current_symbol
.scope
;
133 var old_symbol
= analyzer
.current_symbol
;
134 var old_insert_block
= analyzer
.insert_block
;
135 analyzer
.current_symbol
= this
;
136 analyzer
.insert_block
= this
;
138 for (int i
= 0; i
< statement_list
.size
; i
++) {
139 statement_list
[i
].check (analyzer
);
142 foreach (LocalVariable local
in get_local_variables ()) {
143 local
.active
= false;
146 // use get_statements () instead of statement_list to not miss errors within StatementList objects
147 foreach (Statement stmt
in get_statements ()) {
148 add_error_types (stmt
.get_error_types ());
151 analyzer
.current_symbol
= old_symbol
;
152 analyzer
.insert_block
= old_insert_block
;
157 public void insert_before (Statement stmt
, Statement new_stmt
) {
158 for (int i
= 0; i
< statement_list
.size
; i
++) {
159 var stmt_list
= statement_list
[i
] as StatementList
;
160 if (stmt_list
!= null) {
161 for (int j
= 0; j
< stmt_list
.length
; j
++) {
162 if (stmt_list
.get (j
) == stmt
) {
163 stmt_list
.insert (j
, new_stmt
);
167 } else if (statement_list
[i
] == stmt
) {
168 stmt_list
= new
StatementList (source_reference
);
169 stmt_list
.add (new_stmt
);
170 stmt_list
.add (stmt
);
171 statement_list
[i
] = stmt_list
;
176 public void replace_statement (Statement old_stmt
, Statement new_stmt
) {
177 for (int i
= 0; i
< statement_list
.size
; i
++) {
178 var stmt_list
= statement_list
[i
] as StatementList
;
179 if (stmt_list
!= null) {
180 for (int j
= 0; j
< stmt_list
.length
; j
++) {
181 if (stmt_list
.get (j
) == old_stmt
) {
182 stmt_list
.set (j
, new_stmt
);
186 } else if (statement_list
[i
] == old_stmt
) {
187 statement_list
[i
] = new_stmt
;