gtk+-3.0: Update to 3.0.5
[vala-lang.git] / vala / valaparameter.vala
blobfaab5afe621742ccc2a861aaa37918de09feefa4
1 /* valaparameter.vala
3 * Copyright (C) 2006-2011 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 the position of the parameter in the C function.
48 public double cparameter_position { get; set; }
50 /**
51 * Specifies the position of the array length parameter in the C
52 * function.
54 public double carray_length_parameter_position { get; set; }
56 /**
57 * Specifies the position of the delegate target parameter in the C
58 * function.
60 public double cdelegate_target_parameter_position { get; set; }
62 public double cdestroy_notify_parameter_position { get; set; }
64 /**
65 * Specifies the type of the parameter in the C function.
67 public string? ctype { get; set; }
69 public bool captured { get; set; }
71 /**
72 * Creates a new formal parameter.
74 * @param name parameter name
75 * @param type parameter type
76 * @param source reference to source code
77 * @return newly created formal parameter
79 public Parameter (string name, DataType variable_type, SourceReference? source_reference = null) {
80 base (variable_type, name, null, source_reference);
82 access = SymbolAccessibility.PUBLIC;
85 /**
86 * Creates a new ellipsis parameter representing an indefinite number of
87 * parameters.
89 public Parameter.with_ellipsis (SourceReference? source_reference = null) {
90 base (null, null, null, source_reference);
91 ellipsis = true;
93 access = SymbolAccessibility.PUBLIC;
96 public override void accept (CodeVisitor visitor) {
97 visitor.visit_formal_parameter (this);
100 public override void accept_children (CodeVisitor visitor) {
101 if (!ellipsis) {
102 variable_type.accept (visitor);
104 if (initializer != null) {
105 initializer.accept (visitor);
110 public override void replace_type (DataType old_type, DataType new_type) {
111 if (variable_type == old_type) {
112 variable_type = new_type;
116 public override void replace_expression (Expression old_node, Expression new_node) {
117 if (initializer == old_node) {
118 initializer = new_node;
122 private void process_ccode_attribute (Attribute a) {
123 if (a.has_argument ("type")) {
124 ctype = a.get_string ("type");
126 if (a.has_argument ("pos")) {
127 cparameter_position = a.get_double ("pos");
129 if (a.has_argument ("array_length_pos")) {
130 carray_length_parameter_position = a.get_double ("array_length_pos");
132 if (a.has_argument ("delegate_target_pos")) {
133 cdelegate_target_parameter_position = a.get_double ("delegate_target_pos");
135 if (a.has_argument ("destroy_notify_pos")) {
136 cdestroy_notify_parameter_position = a.get_double ("destroy_notify_pos");
141 * Process all associated attributes.
143 public override void process_attributes () {
144 base.process_attributes ();
146 foreach (Attribute a in attributes) {
147 if (a.name == "CCode") {
148 process_ccode_attribute (a);
153 public Parameter copy () {
154 if (!ellipsis) {
155 var result = new Parameter (name, variable_type, source_reference);
156 result.params_array = params_array;
157 result.direction = this.direction;
158 result.initializer = this.initializer;
159 result.no_array_length = this.no_array_length;
160 result.no_delegate_target = this.no_delegate_target;
161 result.array_null_terminated = this.array_null_terminated;
162 return result;
163 } else {
164 return new Parameter.with_ellipsis ();
168 public override bool check (CodeContext context) {
169 if (checked) {
170 return !error;
173 checked = true;
175 process_attributes ();
177 var old_source_file = context.analyzer.current_source_file;
178 var old_symbol = context.analyzer.current_symbol;
180 if (source_reference != null) {
181 context.analyzer.current_source_file = source_reference.file;
183 context.analyzer.current_symbol = parent_symbol;
185 if (variable_type != null) {
186 if (variable_type is VoidType) {
187 error = true;
188 Report.error (source_reference, "'void' not supported as parameter type");
189 return false;
191 variable_type.check (context);
194 if (!ellipsis) {
195 variable_type.check (context);
197 if (params_array && !(variable_type is ArrayType)) {
198 error = true;
199 Report.error (source_reference, "parameter array expected");
200 return false;
203 if (initializer != null) {
204 initializer.target_type = variable_type.copy ();
205 initializer.check (context);
209 if (initializer != null) {
210 if (initializer is NullLiteral
211 && !variable_type.nullable
212 && direction != ParameterDirection.OUT) {
213 Report.warning (source_reference, "`null' incompatible with parameter type `%s`".printf (variable_type.to_string ()));
214 } else if (!(initializer is NullLiteral) && direction == ParameterDirection.OUT) {
215 Report.error (source_reference, "only `null' is allowed as default value for out parameters");
216 } else if (direction == ParameterDirection.REF) {
217 Report.error (source_reference, "default value not allowed for ref parameter");
221 if (!ellipsis) {
222 // check whether parameter type is at least as accessible as the method
223 if (!context.analyzer.is_type_accessible (this, variable_type)) {
224 error = true;
225 Report.error (source_reference, "parameter type `%s` is less accessible than method `%s`".printf (variable_type.to_string (), parent_symbol.get_full_name ()));
229 context.analyzer.current_source_file = old_source_file;
230 context.analyzer.current_symbol = old_symbol;
232 return !error;
236 public enum Vala.ParameterDirection {
238 OUT,