posix.vapi: signal is allowed to be null (restoring the original handler)
[vala-lang.git] / vala / valablock.vala
blobd392c96ea66edfa40e85e96d816b6901b06bf3ed
1 /* valablock.vala
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
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 using GLib;
24 using Gee;
26 /**
27 * Represents a source code block.
29 public class Vala.Block : Symbol, Statement {
30 /**
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> ();
39 /**
40 * Creates a new block.
42 * @param source reference to source code
44 public Block (SourceReference source_reference) {
45 base (null, source_reference);
48 /**
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);
61 /**
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));
74 } else {
75 list.add (stmt);
78 return list;
81 /**
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));
91 break;
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) {
122 if (checked) {
123 return !error;
126 checked = true;
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;
150 return !error;
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);
160 break;
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);
179 break;
182 } else if (statement_list[i] == old_stmt) {
183 statement_list[i] = new_stmt;
184 break;