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
21 * Jürg Billeter <j@bitron.ch>
22 * Raffaele Sandrini <raffaele@sandrini.ch>
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
; }
34 * Specifies whether the methods accepts an indefinite number of
37 public bool ellipsis
{ get; set; }
40 * Specifies whether the methods accepts an indefinite number of
43 public bool params_array
{ get; set; }
46 * Specifies the position of the parameter in the C function.
48 public double cparameter_position
{ get; set; }
51 * Specifies the position of the array length parameter in the C
54 public double carray_length_parameter_position
{ get; set; }
57 * Specifies the position of the delegate target parameter in the C
60 public double cdelegate_target_parameter_position
{ get; set; }
62 public double cdestroy_notify_parameter_position
{ get; set; }
65 * Specifies the type of the parameter in the C function.
67 public string? ctype
{ get; set; }
69 public bool captured
{ get; set; }
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
;
86 * Creates a new ellipsis parameter representing an indefinite number of
89 public Parameter
.with_ellipsis (SourceReference? source_reference
= null) {
90 base (null, null, null, source_reference
);
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
) {
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 () {
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
;
164 return new Parameter
.with_ellipsis ();
168 public override bool check (CodeContext context
) {
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
) {
188 Report
.error (source_reference
, "'void' not supported as parameter type");
191 variable_type
.check (context
);
195 variable_type
.check (context
);
197 if (params_array
&& !(variable_type is ArrayType
)) {
199 Report
.error (source_reference
, "parameter array expected");
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");
222 // check whether parameter type is at least as accessible as the method
223 if (!context
.analyzer
.is_type_accessible (this
, variable_type
)) {
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
;
236 public enum Vala
.ParameterDirection
{