3 * Copyright (C) 2006-2012 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; }
45 public bool captured
{ get; set; }
47 public bool format_arg
{
49 return get_attribute ("FormatArg") != null;
54 * The base parameter of this parameter relative to the base method.
56 public Parameter base_parameter
{ get; set; }
59 * Creates a new formal parameter.
61 * @param name parameter name
62 * @param variable_type parameter type
63 * @param source_reference reference to source code
64 * @return newly created formal parameter
66 public Parameter (string name
, DataType? variable_type
, SourceReference? source_reference
= null) {
67 base (variable_type
, name
, null, source_reference
);
69 access
= SymbolAccessibility
.PUBLIC
;
73 * Creates a new ellipsis parameter representing an indefinite number of
76 public Parameter
.with_ellipsis (SourceReference? source_reference
= null) {
77 base (null, null, null, source_reference
);
80 access
= SymbolAccessibility
.PUBLIC
;
83 public override void accept (CodeVisitor visitor
) {
84 visitor
.visit_formal_parameter (this
);
87 public override void accept_children (CodeVisitor visitor
) {
89 variable_type
.accept (visitor
);
91 if (initializer
!= null) {
92 initializer
.accept (visitor
);
97 public override void replace_type (DataType old_type
, DataType new_type
) {
98 if (variable_type
== old_type
) {
99 variable_type
= new_type
;
103 public override void replace_expression (Expression old_node
, Expression new_node
) {
104 if (initializer
== old_node
) {
105 initializer
= new_node
;
109 public Parameter
copy () {
111 var result
= new
Parameter (name
, variable_type
.copy (), source_reference
);
112 result
.params_array
= params_array
;
113 result
.direction
= this
.direction
;
114 result
.initializer
= this
.initializer
;
116 // cannot use List.copy()
117 // as it returns a list of unowned elements
118 foreach (Attribute a
in this
.attributes
) {
119 result
.attributes
.append (a
);
124 return new Parameter
.with_ellipsis ();
128 public override bool check (CodeContext context
) {
135 var old_source_file
= context
.analyzer
.current_source_file
;
136 var old_symbol
= context
.analyzer
.current_symbol
;
138 if (source_reference
!= null) {
139 context
.analyzer
.current_source_file
= source_reference
.file
;
141 context
.analyzer
.current_symbol
= parent_symbol
;
143 if (variable_type
!= null) {
144 if (variable_type is VoidType
) {
146 Report
.error (source_reference
, "'void' not supported as parameter type");
149 variable_type
.check (context
);
153 variable_type
.check (context
);
155 if (params_array
&& !(variable_type is ArrayType
)) {
157 Report
.error (source_reference
, "parameter array expected");
161 if (has_attribute_argument ("CCode", "scope") && variable_type is DelegateType
) {
162 var delegate_type
= (DelegateType
) variable_type
;
163 delegate_type
.is_called_once
= get_attribute_string ("CCode", "scope") == "async";
166 if (initializer
!= null) {
167 initializer
.target_type
= variable_type
.copy ();
168 initializer
.check (context
);
172 if (initializer
!= null) {
173 if (initializer is NullLiteral
174 && !variable_type
.nullable
175 && direction
!= ParameterDirection
.OUT
) {
176 Report
.warning (source_reference
, "`null' incompatible with parameter type `%s`".printf (variable_type
.to_string ()));
177 } else if (!(initializer is NullLiteral
) && direction
== ParameterDirection
.OUT
) {
178 Report
.error (source_reference
, "only `null' is allowed as default value for out parameters");
179 } else if (direction
== ParameterDirection
.IN
&& !initializer
.value_type
.compatible (variable_type
)) {
180 Report
.error (initializer
.source_reference
, "Cannot convert from `%s' to `%s'".printf (initializer
.value_type
.to_string (), variable_type
.to_string ()));
181 } else if (direction
== ParameterDirection
.REF
) {
182 Report
.error (source_reference
, "default value not allowed for ref parameter");
183 } else if (!initializer
.is_accessible (this
)) {
184 Report
.error (initializer
.source_reference
, "default value is less accessible than method `%s'".printf (parent_symbol
.get_full_name ()));
189 // check whether parameter type is at least as accessible as the method
190 if (!context
.analyzer
.is_type_accessible (this
, variable_type
)) {
192 Report
.error (source_reference
, "parameter type `%s` is less accessible than method `%s`".printf (variable_type
.to_string (), parent_symbol
.get_full_name ()));
196 var m
= parent_symbol as Method
;
198 Method base_method
= m
.base_method
!= null ? m
.base_method
: m
.base_interface_method
;
199 if (base_method
!= null && base_method
!= m
) {
200 int index
= m
.get_parameters ().index_of (this
);
202 base_parameter
= base_method
.get_parameters ().get (index
);
207 context
.analyzer
.current_source_file
= old_source_file
;
208 context
.analyzer
.current_symbol
= old_symbol
;
214 public enum Vala
.ParameterDirection
{