Line data Source code
1 : /* valatrystatement.vala
2 : *
3 : * Copyright (C) 2007-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 a try statement in the source code.
27 : */
28 9524 : public class Vala.TryStatement : CodeNode, Statement {
29 : /**
30 : * Specifies the body of the try statement.
31 : */
32 : public Block body {
33 11329 : get { return _body; }
34 3233 : private set {
35 6466 : _body = value;
36 3233 : _body.parent_node = this;
37 : }
38 : }
39 :
40 : /**
41 : * Specifies the body of the optional finally clause.
42 : */
43 : public Block? finally_body {
44 11830 : get { return _finally_body; }
45 3233 : private set {
46 3278 : _finally_body = value;
47 3233 : if (_finally_body != null)
48 45 : _finally_body.parent_node = this;
49 : }
50 : }
51 :
52 2104 : public bool after_try_block_reachable { get; set; default = true; }
53 :
54 3233 : private Block _body;
55 3233 : private Block _finally_body;
56 6466 : private List<CatchClause> catch_clauses = new ArrayList<CatchClause> ();
57 :
58 : /**
59 : * Creates a new try statement.
60 : *
61 : * @param body body of the try statement
62 : * @param finally_body body of the optional finally clause
63 : * @param source_reference reference to source code
64 : * @return newly created try statement
65 : */
66 9699 : public TryStatement (Block body, Block? finally_body, SourceReference? source_reference = null) {
67 3233 : this.body = body;
68 3233 : this.finally_body = finally_body;
69 3233 : this.source_reference = source_reference;
70 : }
71 :
72 : /**
73 : * Appends the specified clause to the list of catch clauses.
74 : *
75 : * @param clause a catch clause
76 : */
77 3203 : public void add_catch_clause (CatchClause clause) {
78 3203 : clause.parent_node = this;
79 3203 : catch_clauses.add (clause);
80 : }
81 :
82 : /**
83 : * Returns the list of catch clauses.
84 : *
85 : * @return list of catch clauses
86 : */
87 2594 : public unowned List<CatchClause> get_catch_clauses () {
88 2594 : return catch_clauses;
89 : }
90 :
91 5110 : public override void accept (CodeVisitor visitor) {
92 5110 : visitor.visit_try_statement (this);
93 : }
94 :
95 3014 : public override void accept_children (CodeVisitor visitor) {
96 3014 : body.accept (visitor);
97 :
98 9036 : foreach (CatchClause clause in catch_clauses) {
99 3011 : clause.accept (visitor);
100 : }
101 :
102 3014 : if (finally_body != null) {
103 22 : finally_body.accept (visitor);
104 : }
105 : }
106 :
107 6008 : public override void get_error_types (Collection<DataType> collection, SourceReference? source_reference = null) {
108 3004 : var error_types = new ArrayList<DataType> ();
109 3004 : body.get_error_types (error_types, source_reference);
110 :
111 8958 : foreach (CatchClause clause in catch_clauses) {
112 8979 : for (int i=0; i < error_types.size; i++) {
113 3001 : var error_type = error_types[i];
114 3001 : if (clause.error_type == null || error_type.compatible (clause.error_type)) {
115 2992 : error_types.remove_at (i);
116 2992 : i--;
117 : }
118 : }
119 :
120 2977 : clause.body.get_error_types (collection, source_reference);
121 : }
122 :
123 3004 : if (finally_body != null) {
124 44 : finally_body.get_error_types (collection, source_reference);
125 : }
126 :
127 3020 : foreach (var error_type in error_types) {
128 8 : collection.add (error_type);
129 : }
130 : }
131 :
132 3003 : public override bool check (CodeContext context) {
133 3003 : if (checked) {
134 0 : return !error;
135 : }
136 :
137 3003 : checked = true;
138 :
139 3003 : if (context.profile == Profile.POSIX) {
140 0 : Report.error (source_reference, "`try' is not supported in POSIX profile");
141 0 : error = true;
142 0 : return false;
143 : }
144 :
145 3003 : body.check (context);
146 :
147 8953 : foreach (CatchClause clause in catch_clauses) {
148 2975 : clause.check (context);
149 : }
150 :
151 3003 : if (finally_body != null) {
152 45 : finally_body.check (context);
153 : }
154 :
155 3003 : return !error;
156 : }
157 :
158 168 : public override void emit (CodeGenerator codegen) {
159 168 : codegen.visit_try_statement (this);
160 : }
161 : }
|