Line data Source code
1 : /* valacatchclause.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 :
24 : /**
25 : * Represents a catch clause in a try statement in the source code.
26 : */
27 4732 : public class Vala.CatchClause : CodeNode {
28 : /**
29 : * Specifies the error type.
30 : */
31 : public DataType? error_type {
32 33776 : get { return _data_type; }
33 6189 : private set {
34 12316 : _data_type = value;
35 6189 : if (_data_type != null) {
36 6138 : _data_type.parent_node = this;
37 : }
38 : }
39 : }
40 :
41 : /**
42 : * Specifies the error variable name.
43 : */
44 9609 : public string? variable_name { get; private set; }
45 :
46 : /**
47 : * Specifies the error handler body.
48 : */
49 : public Block body {
50 17018 : get { return _body; }
51 3203 : private set {
52 6406 : _body = value;
53 3203 : _body.parent_node = this;
54 : }
55 : }
56 :
57 : /**
58 : * Specifies the declarator for the generated error variable.
59 : */
60 : public LocalVariable error_variable {
61 21711 : get { return _error_variable; }
62 2924 : private set {
63 5848 : _error_variable = value;
64 2924 : _error_variable.parent_node = this;
65 : }
66 : }
67 :
68 3203 : private DataType _data_type;
69 :
70 3203 : private Block _body;
71 3203 : private LocalVariable _error_variable;
72 :
73 : /**
74 : * Creates a new catch
75 : *
76 : * @param error_type error type
77 : * @param variable_name error variable name
78 : * @param body error handler body
79 : * @param source_reference reference to source code
80 : * @return newly created catch clause
81 : */
82 9609 : public CatchClause (DataType? error_type, string? variable_name, Block body, SourceReference? source_reference = null) {
83 3203 : this.error_type = error_type;
84 3203 : this.variable_name = variable_name;
85 3203 : this.body = body;
86 3203 : this.source_reference = source_reference;
87 : }
88 :
89 3011 : public override void accept (CodeVisitor visitor) {
90 3011 : visitor.visit_catch_clause (this);
91 : }
92 :
93 3011 : public override void accept_children (CodeVisitor visitor) {
94 3011 : if (error_type != null) {
95 2956 : error_type.accept (visitor);
96 : }
97 :
98 3011 : body.accept (visitor);
99 : }
100 :
101 2935 : public override void replace_type (DataType old_type, DataType new_type) {
102 2935 : if (error_type == old_type) {
103 2935 : error_type = new_type;
104 : }
105 : }
106 :
107 2975 : public override bool check (CodeContext context) {
108 2975 : if (checked) {
109 0 : return !error;
110 : }
111 :
112 2975 : checked = true;
113 :
114 2975 : if (context.profile == Profile.POSIX) {
115 0 : Report.error (source_reference, "`catch' is not supported in POSIX profile");
116 0 : error = true;
117 0 : return false;
118 : }
119 :
120 2975 : if (error_type != null) {
121 2924 : if (!(error_type is ErrorType)) {
122 1 : Report.error (source_reference, "clause must catch a valid error type, found `%s' instead", error_type.to_string ());
123 1 : error = true;
124 : }
125 :
126 2924 : if (variable_name != null) {
127 2924 : error_variable = new LocalVariable (error_type.copy (), variable_name, null, source_reference);
128 :
129 2924 : body.scope.add (variable_name, error_variable);
130 2924 : body.add_local_variable (error_variable);
131 :
132 2924 : error_variable.checked = true;
133 : }
134 : } else {
135 : // generic catch clause
136 51 : error_type = new ErrorType (null, null, source_reference);
137 : }
138 :
139 2975 : error_type.check (context);
140 2975 : body.check (context);
141 :
142 2975 : return !error;
143 : }
144 :
145 142 : public override void emit (CodeGenerator codegen) {
146 142 : if (error_variable != null) {
147 91 : error_variable.active = true;
148 : }
149 :
150 142 : codegen.visit_catch_clause (this);
151 : }
152 :
153 6195 : public override void get_defined_variables (Collection<Variable> collection) {
154 6195 : if (error_variable != null) {
155 6045 : collection.add (error_variable);
156 : }
157 : }
158 : }
|