Line data Source code
1 : /* valaifstatement.vala
2 : *
3 : * Copyright (C) 2006-2010 Jürg Billeter
4 : *
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.
9 :
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.
14 :
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
18 : *
19 : * Author:
20 : * Jürg Billeter <j@bitron.ch>
21 : */
22 :
23 : using GLib;
24 :
25 : /**
26 : * Represents an if selection statement in the source code.
27 : */
28 144411 : public class Vala.IfStatement : CodeNode, Statement {
29 : /**
30 : * The boolean condition to evaluate.
31 : */
32 : public Expression condition {
33 1429182 : get {
34 1429182 : return _condition;
35 : }
36 157481 : private set {
37 440155 : _condition = value;
38 157481 : _condition.parent_node = this;
39 : }
40 : }
41 :
42 : /**
43 : * The statement to be evaluated if the condition holds.
44 : */
45 : public Block true_statement {
46 452306 : get { return _true_statement; }
47 141337 : private set {
48 282674 : _true_statement = value;
49 141337 : _true_statement.parent_node = this;
50 : }
51 : }
52 :
53 : /**
54 : * The optional statement to be evaluated if the condition doesn't hold.
55 : */
56 : public Block? false_statement {
57 797014 : get { return _false_statement; }
58 141337 : private set {
59 239340 : _false_statement = value;
60 141337 : if (_false_statement != null)
61 98003 : _false_statement.parent_node = this;
62 : }
63 : }
64 :
65 141337 : private Expression _condition;
66 141337 : private Block _true_statement;
67 141337 : private Block _false_statement;
68 :
69 : /**
70 : * Creates a new if statement.
71 : *
72 : * @param cond a boolean condition
73 : * @param true_stmt statement to be evaluated if condition is true
74 : * @param false_stmt statement to be evaluated if condition is false
75 : * @return newly created if statement
76 : */
77 424011 : public IfStatement (Expression cond, Block true_stmt, Block? false_stmt, SourceReference? source = null) {
78 141337 : condition = cond;
79 141337 : true_statement = true_stmt;
80 141337 : false_statement = false_stmt;
81 141337 : source_reference = source;
82 : }
83 :
84 168990 : public override void accept (CodeVisitor visitor) {
85 168990 : visitor.visit_if_statement (this);
86 : }
87 :
88 73251 : public override void accept_children (CodeVisitor visitor) {
89 73251 : condition.accept (visitor);
90 :
91 73251 : visitor.visit_end_full_expression (condition);
92 :
93 73251 : true_statement.accept (visitor);
94 73251 : if (false_statement != null) {
95 49442 : false_statement.accept (visitor);
96 : }
97 : }
98 :
99 16144 : public override void replace_expression (Expression old_node, Expression new_node) {
100 16144 : if (condition == old_node) {
101 16144 : condition = new_node;
102 : }
103 : }
104 :
105 136706 : public override void get_error_types (Collection<DataType> collection, SourceReference? source_reference = null) {
106 136706 : condition.get_error_types (collection, source_reference);
107 136706 : true_statement.get_error_types (collection, source_reference);
108 136706 : if (false_statement != null) {
109 94646 : false_statement.get_error_types (collection, source_reference);
110 : }
111 : }
112 :
113 135978 : public override bool check (CodeContext context) {
114 135978 : if (checked) {
115 0 : return !error;
116 : }
117 :
118 135978 : checked = true;
119 :
120 135978 : condition.target_type = context.analyzer.bool_type.copy ();
121 :
122 135978 : condition.check (context);
123 :
124 135978 : true_statement.check (context);
125 135978 : if (false_statement != null) {
126 94241 : false_statement.check (context);
127 : }
128 :
129 135978 : if (condition.error) {
130 : /* if there was an error in the condition, skip this check */
131 4 : error = true;
132 4 : return false;
133 : }
134 :
135 135974 : if (condition.value_type == null || !condition.value_type.compatible (context.analyzer.bool_type)) {
136 1 : error = true;
137 1 : Report.error (condition.source_reference, "Condition must be boolean");
138 1 : return false;
139 : }
140 :
141 135973 : return !error;
142 : }
143 :
144 10633 : public override void emit (CodeGenerator codegen) {
145 10633 : condition.emit (codegen);
146 :
147 10633 : codegen.visit_end_full_expression (condition);
148 :
149 10633 : codegen.visit_if_statement (this);
150 : }
151 : }
|