gtk+-4.0: Update to 3.93.0+f4c1a404
[vala-gnome.git] / vala / valaparameter.vala
blob39820718ceb3a75c2b1c59efd930790a029df4ca
1 /* valaparameter.vala
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
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 public bool captured { get; set; }
47 public bool format_arg {
48 get {
49 return get_attribute ("FormatArg") != null;
53 /**
54 * The base parameter of this parameter relative to the base method.
56 public Parameter base_parameter { get; set; }
58 /**
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;
72 /**
73 * Creates a new ellipsis parameter representing an indefinite number of
74 * parameters.
76 public Parameter.with_ellipsis (SourceReference? source_reference = null) {
77 base (null, null, null, source_reference);
78 ellipsis = true;
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) {
88 if (!ellipsis) {
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 () {
110 if (!ellipsis) {
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);
122 return result;
123 } else {
124 return new Parameter.with_ellipsis ();
128 public override bool check (CodeContext context) {
129 if (checked) {
130 return !error;
133 checked = true;
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) {
145 error = true;
146 Report.error (source_reference, "'void' not supported as parameter type");
147 return false;
149 variable_type.check (context);
152 if (!ellipsis) {
153 variable_type.check (context);
155 if (params_array && !(variable_type is ArrayType)) {
156 error = true;
157 Report.error (source_reference, "parameter array expected");
158 return false;
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 ()));
188 if (!ellipsis) {
189 // check whether parameter type is at least as accessible as the method
190 if (!context.analyzer.is_type_accessible (this, variable_type)) {
191 error = true;
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;
197 if (m != null) {
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);
201 if (index >= 0) {
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;
210 return !error;
214 public enum Vala.ParameterDirection {
216 OUT,