Release 0.7.8
[vala-lang.git] / vala / valaformalparameter.vala
blob2dfa557b5170e87891d7e142e782462aeb035e3b
1 /* valaformalparameter.vala
3 * Copyright (C) 2006-2009 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.FormalParameter : Symbol {
31 /**
32 * The parameter type.
34 public DataType parameter_type {
35 get { return _data_type; }
36 set {
37 _data_type = value;
38 _data_type.parent_node = this;
42 public ParameterDirection direction { get; set; default = ParameterDirection.IN; }
44 /**
45 * Specifies whether the methods accepts an indefinite number of
46 * parameters.
48 public bool ellipsis { get; set; }
50 /**
51 * Specifies whether the methods accepts an indefinite number of
52 * parameters.
54 public bool params_array { get; set; }
56 /**
57 * Specifies the expression used when the caller doesn't supply an
58 * argument for this parameter.
60 public Expression? default_expression {
61 get { return _default_expression; }
62 set {
63 _default_expression = value;
64 if (_default_expression != null) {
65 _default_expression.parent_node = this;
70 /**
71 * Specifies whether the array length should be passed implicitly
72 * if the parameter type is an array.
74 public bool no_array_length { get; set; }
76 /**
77 * Specifies whether the array is null terminated.
79 public bool array_null_terminated { get; set; }
81 /**
82 * Specifies the position of the parameter in the C function.
84 public double cparameter_position { get; set; }
86 /**
87 * Specifies the position of the array length parameter in the C
88 * function.
90 public double carray_length_parameter_position { get; set; }
92 /**
93 * Specifies the position of the delegate target parameter in the C
94 * function.
96 public double cdelegate_target_parameter_position { get; set; }
98 /**
99 * Specifies the type of the parameter in the C function.
101 public string? ctype { get; set; }
103 public bool captured { get; set; }
105 private DataType _data_type;
106 private Expression? _default_expression;
109 * Creates a new formal parameter.
111 * @param name parameter name
112 * @param type parameter type
113 * @param source reference to source code
114 * @return newly created formal parameter
116 public FormalParameter (string name, DataType parameter_type, SourceReference? source_reference = null) {
117 base (name, source_reference);
118 this.parameter_type = parameter_type;
120 access = SymbolAccessibility.PUBLIC;
124 * Creates a new ellipsis parameter representing an indefinite number of
125 * parameters.
127 public FormalParameter.with_ellipsis (SourceReference? source_reference = null) {
128 base (null, source_reference);
129 ellipsis = true;
131 access = SymbolAccessibility.PUBLIC;
134 public override void accept (CodeVisitor visitor) {
135 visitor.visit_formal_parameter (this);
138 public override void accept_children (CodeVisitor visitor) {
139 if (!ellipsis) {
140 parameter_type.accept (visitor);
142 if (default_expression != null) {
143 default_expression.accept (visitor);
148 public override void replace_type (DataType old_type, DataType new_type) {
149 if (parameter_type == old_type) {
150 parameter_type = new_type;
154 public override void replace_expression (Expression old_node, Expression new_node) {
155 if (default_expression == old_node) {
156 default_expression = new_node;
160 private void process_ccode_attribute (Attribute a) {
161 if (a.has_argument ("type")) {
162 ctype = a.get_string ("type");
164 if (a.has_argument ("pos")) {
165 cparameter_position = a.get_double ("pos");
167 if (a.has_argument ("array_length")) {
168 no_array_length = !a.get_bool ("array_length");
170 if (a.has_argument ("array_null_terminated")) {
171 array_null_terminated = a.get_bool ("array_null_terminated");
173 if (a.has_argument ("array_length_pos")) {
174 carray_length_parameter_position = a.get_double ("array_length_pos");
176 if (a.has_argument ("delegate_target_pos")) {
177 cdelegate_target_parameter_position = a.get_double ("delegate_target_pos");
182 * Process all associated attributes.
184 public void process_attributes () {
185 foreach (Attribute a in attributes) {
186 if (a.name == "CCode") {
187 process_ccode_attribute (a);
192 public FormalParameter copy () {
193 if (!ellipsis) {
194 var result = new FormalParameter (name, parameter_type, source_reference);
195 result.params_array = params_array;
196 result.direction = this.direction;
197 return result;
198 } else {
199 return new FormalParameter.with_ellipsis ();
203 public override bool check (SemanticAnalyzer analyzer) {
204 if (checked) {
205 return !error;
208 checked = true;
210 process_attributes ();
212 var old_source_file = analyzer.current_source_file;
213 var old_symbol = analyzer.current_symbol;
215 if (source_reference != null) {
216 analyzer.current_source_file = source_reference.file;
218 analyzer.current_symbol = parent_symbol;
220 if (parameter_type != null) {
221 parameter_type.check (analyzer);
224 if (!ellipsis) {
225 parameter_type.check (analyzer);
227 if (params_array && !(parameter_type is ArrayType)) {
228 error = true;
229 Report.error (source_reference, "parameter array expected");
230 return false;
233 if (default_expression != null) {
234 default_expression.check (analyzer);
238 if (default_expression != null) {
239 if (default_expression is NullLiteral
240 && !parameter_type.nullable
241 && direction != ParameterDirection.OUT) {
242 Report.warning (source_reference, "`null' incompatible with parameter type `%s`".printf (parameter_type.to_string ()));
246 if (!ellipsis) {
247 // check whether parameter type is at least as accessible as the method
248 if (!analyzer.is_type_accessible (this, parameter_type)) {
249 error = true;
250 Report.error (source_reference, "parameter type `%s` is less accessible than method `%s`".printf (parameter_type.to_string (), parent_symbol.get_full_name ()));
254 analyzer.current_source_file = old_source_file;
255 analyzer.current_symbol = old_symbol;
257 return !error;
261 public enum Vala.ParameterDirection {
263 OUT,