codegen: Limit scope of locals freed on errors thrown from catch clauses
[vala-lang.git] / vala / valaparameter.vala
blob7c52e9c683587f90c4ce876b7dd92c86c93cc788
1 /* valaparameter.vala
3 * Copyright (C) 2006-2010 Jürg Billeter
4 * Copyright (C) 2006-2008 Raffaele Sandrini
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Author:
21 * Jürg Billeter <j@bitron.ch>
22 * Raffaele Sandrini <raffaele@sandrini.ch>
25 using GLib;
27 /**
28 * Represents a formal parameter in method and callback signatures.
30 public class Vala.Parameter : Variable {
31 public ParameterDirection direction { get; set; default = ParameterDirection.IN; }
33 /**
34 * Specifies whether the methods accepts an indefinite number of
35 * parameters.
37 public bool ellipsis { get; set; }
39 /**
40 * Specifies whether the methods accepts an indefinite number of
41 * parameters.
43 public bool params_array { get; set; }
45 /**
46 * Specifies whether the array length should be passed implicitly
47 * if the parameter type is an array.
49 public bool no_array_length { get; set; }
51 /**
52 * Specifies whether the array is null terminated.
54 public bool array_null_terminated { get; set; }
56 /**
57 * Specifies whether the array length parameter uses a custom name in C.
59 public bool has_array_length_cname {
60 get { return (array_length_cname != null); }
63 /**
64 * Specifies a custom type for the array length.
66 public string? array_length_type { get; set; default = null; }
68 /**
69 * Specifies the position of the parameter in the C function.
71 public double cparameter_position { get; set; }
73 /**
74 * Specifies the position of the array length parameter in the C
75 * function.
77 public double carray_length_parameter_position { get; set; }
79 /**
80 * Specifies the position of the delegate target parameter in the C
81 * function.
83 public double cdelegate_target_parameter_position { get; set; }
85 public double cdestroy_notify_parameter_position { get; set; }
87 /**
88 * Specifies the type of the parameter in the C function.
90 public string? ctype { get; set; }
92 public bool captured { get; set; }
94 private string? array_length_cname;
96 /**
97 * Creates a new formal parameter.
99 * @param name parameter name
100 * @param type parameter type
101 * @param source reference to source code
102 * @return newly created formal parameter
104 public Parameter (string name, DataType variable_type, SourceReference? source_reference = null) {
105 base (variable_type, name, null, source_reference);
107 access = SymbolAccessibility.PUBLIC;
111 * Creates a new ellipsis parameter representing an indefinite number of
112 * parameters.
114 public Parameter.with_ellipsis (SourceReference? source_reference = null) {
115 base (null, null, null, source_reference);
116 ellipsis = true;
118 access = SymbolAccessibility.PUBLIC;
121 public override void accept (CodeVisitor visitor) {
122 visitor.visit_formal_parameter (this);
125 public override void accept_children (CodeVisitor visitor) {
126 if (!ellipsis) {
127 variable_type.accept (visitor);
129 if (initializer != null) {
130 initializer.accept (visitor);
135 public override void replace_type (DataType old_type, DataType new_type) {
136 if (variable_type == old_type) {
137 variable_type = new_type;
141 public override void replace_expression (Expression old_node, Expression new_node) {
142 if (initializer == old_node) {
143 initializer = new_node;
148 * Returns the name of the array length parameter as it is used in C code
150 * @return the name of the array length parameter to be used in C code
152 public string? get_array_length_cname () {
153 return this.array_length_cname;
157 * Sets the name of the array length parameter as it is used in C code
159 * @param array_length_cname the name of the array length parameter to be
160 * used in C code
162 public void set_array_length_cname (string? array_length_cname) {
163 this.array_length_cname = array_length_cname;
166 private void process_ccode_attribute (Attribute a) {
167 if (a.has_argument ("type")) {
168 ctype = a.get_string ("type");
170 if (a.has_argument ("pos")) {
171 cparameter_position = a.get_double ("pos");
173 if (a.has_argument ("array_length")) {
174 no_array_length = !a.get_bool ("array_length");
176 if (a.has_argument ("array_length_type")) {
177 array_length_type = a.get_string ("array_length_type");
179 if (a.has_argument ("array_null_terminated")) {
180 array_null_terminated = a.get_bool ("array_null_terminated");
182 if (a.has_argument ("array_length_pos")) {
183 carray_length_parameter_position = a.get_double ("array_length_pos");
185 if (a.has_argument ("array_length_cname")) {
186 set_array_length_cname (a.get_string ("array_length_cname"));
188 if (a.has_argument ("delegate_target_pos")) {
189 cdelegate_target_parameter_position = a.get_double ("delegate_target_pos");
191 if (a.has_argument ("destroy_notify_pos")) {
192 cdestroy_notify_parameter_position = a.get_double ("destroy_notify_pos");
197 * Process all associated attributes.
199 public void process_attributes () {
200 foreach (Attribute a in attributes) {
201 if (a.name == "CCode") {
202 process_ccode_attribute (a);
207 public Parameter copy () {
208 if (!ellipsis) {
209 var result = new Parameter (name, variable_type, source_reference);
210 result.params_array = params_array;
211 result.direction = this.direction;
212 result.initializer = this.initializer;
213 return result;
214 } else {
215 return new Parameter.with_ellipsis ();
219 public override bool check (CodeContext context) {
220 if (checked) {
221 return !error;
224 checked = true;
226 process_attributes ();
228 var old_source_file = context.analyzer.current_source_file;
229 var old_symbol = context.analyzer.current_symbol;
231 if (source_reference != null) {
232 context.analyzer.current_source_file = source_reference.file;
234 context.analyzer.current_symbol = parent_symbol;
236 if (variable_type != null) {
237 if (variable_type is VoidType) {
238 error = true;
239 Report.error (source_reference, "'void' not supported as parameter type");
240 return false;
242 variable_type.check (context);
245 if (!ellipsis) {
246 variable_type.check (context);
248 if (params_array && !(variable_type is ArrayType)) {
249 error = true;
250 Report.error (source_reference, "parameter array expected");
251 return false;
254 if (initializer != null) {
255 initializer.target_type = variable_type.copy ();
256 initializer.check (context);
260 if (initializer != null) {
261 if (initializer is NullLiteral
262 && !variable_type.nullable
263 && direction != ParameterDirection.OUT) {
264 Report.warning (source_reference, "`null' incompatible with parameter type `%s`".printf (variable_type.to_string ()));
265 } else if (!(initializer is NullLiteral) && direction == ParameterDirection.OUT) {
266 Report.error (source_reference, "only `null' is allowed as default value for out parameters");
267 } else if (direction == ParameterDirection.REF) {
268 Report.error (source_reference, "default value not allowed for ref parameter");
272 if (!ellipsis) {
273 // check whether parameter type is at least as accessible as the method
274 if (!context.analyzer.is_type_accessible (this, variable_type)) {
275 error = true;
276 Report.error (source_reference, "parameter type `%s` is less accessible than method `%s`".printf (variable_type.to_string (), parent_symbol.get_full_name ()));
280 context.analyzer.current_source_file = old_source_file;
281 context.analyzer.current_symbol = old_symbol;
283 return !error;
287 public enum Vala.ParameterDirection {
289 OUT,