remove obsolete ref modifier and callback keyword
[vala-lang.git] / vala / valatypereference.vala
blob52371f5da8d84fdc4c85f75400dd3d1fb5269c04
1 /* valatypereference.vala
3 * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <rasa@gmx.ch>
24 using GLib;
26 /**
27 * A reference to a data type. This is used to specify static types of
28 * expressions.
30 public class Vala.TypeReference : CodeNode {
31 /**
32 * Specifies that the expression transfers ownership of its value.
34 public bool transfers_ownership { get; set; }
36 /**
37 * Specifies that the expression assumes ownership if used as an lvalue
38 * in an assignment.
40 public bool takes_ownership { get; set; }
42 /**
43 * Specifies that the expression is a reference used in out parameters.
45 public bool is_out { get; set; }
47 /**
48 * Specifies that the expression is guaranteed not to be null.
50 public bool non_null { get; set; }
52 /**
53 * Specifies that the expression is known to be null.
55 public bool is_null { get; set; }
57 /**
58 * The referred data type.
60 public weak DataType data_type { get; set; }
62 /**
63 * The referred generic type parameter.
65 public TypeParameter type_parameter { get; set; }
67 /**
68 * Specifies that the expression transfers a floating reference.
70 public bool floating_reference { get; set; }
72 /**
73 * The name of the namespace containing the referred data type. May only
74 * be used with unresolved type references.
76 public string namespace_name { get; set; }
78 /**
79 * The name of the referred data type. May only be used with unresolved
80 * type references.
82 public string type_name { get; set; }
84 /**
85 * Specifies the rank of the array this reference is possibly referring to. "0" indicates no array.
86 * WARNING: This property may only be set by the parser and only be read by the symbol resolver.
88 public int array_rank { get; set; }
90 /**
91 * Specifies the level of the pointer if this is a pointer-type. "0" indicates no pointer-type.
92 * WARNING: This property may only be set by the parser and only be read by the symbol resolver.
94 public int pointer_level { get; set; }
96 /**
97 * Specifies that the expression is a reference used in ref parameters.
99 public bool is_ref { get; set; }
102 * The weak modifier has been specified. May only be used with
103 * unresolved type references.
105 public bool is_weak { get; set; }
107 private List<TypeReference> type_argument_list;
109 public TypeReference () {
113 * Creates a new type reference.
115 * @param ns optional namespace name
116 * @param type_name type symbol name
117 * @param source reference to source code
118 * @return newly created type reference
120 public TypeReference.from_name (string ns, string! type, SourceReference source = null) {
121 namespace_name = ns;
122 type_name = type;
123 source_reference = source;
127 * Creates a new type reference from a code expression.
129 * @param expr member access expression
130 * @param source reference to source code
131 * @return newly created type reference
133 public static TypeReference new_from_expression (Expression! expr) {
134 string ns = null;
135 string type_name = null;
136 if (expr is MemberAccess) {
137 TypeReference type_ref = null;
139 MemberAccess ma = (MemberAccess) expr;
140 if (ma.inner != null) {
141 if (ma.inner is MemberAccess) {
142 var simple = (MemberAccess) ma.inner;
143 type_ref = new TypeReference.from_name (simple.member_name, ma.member_name, ma.source_reference);
145 } else {
146 type_ref = new TypeReference.from_name (null, ma.member_name, ma.source_reference);
149 if (type_ref != null) {
150 var type_args = ma.get_type_arguments ();
151 foreach (TypeReference arg in type_args) {
152 type_ref.add_type_argument (arg);
155 return type_ref;
159 Report.error (expr.source_reference, "Type reference must be simple name or member access expression");
160 return null;
164 * Appends the specified type as generic type argument.
166 * @param arg a type reference
168 public void add_type_argument (TypeReference! arg) {
169 type_argument_list.append (arg);
173 * Returns a copy of the list of generic type arguments.
175 * @return type argument list
177 public List<weak TypeReference> get_type_arguments () {
178 return type_argument_list.copy ();
182 * Removes all generic type arguments.
184 public void remove_all_type_arguments () {
185 type_argument_list = null;
188 public override void accept (CodeVisitor! visitor) {
189 foreach (TypeReference type_arg in type_argument_list) {
190 type_arg.accept (visitor);
193 visitor.visit_type_reference (this);
197 * Returns the name and qualifiers of this type as it is used in C code.
199 * @return the type string to be used in C code
201 public string get_cname (bool var_type = false, bool const_type = false) {
202 if (data_type == null && type_parameter == null) {
203 if (var_type) {
204 return "gpointer";
205 } else {
206 return "void";
210 string ptr;
211 string arr;
212 if (type_parameter != null || (!data_type.is_reference_type () && !is_ref && !is_out)) {
213 ptr = "";
214 } else if ((data_type.is_reference_type () && !is_ref && !is_out) || (!data_type.is_reference_type () && (is_ref || is_out))) {
215 ptr = "*";
216 } else {
217 ptr = "**";
219 if (data_type != null) {
220 return data_type.get_cname (const_type).concat (ptr, arr, null);
221 } else if (type_parameter != null) {
222 return "gpointer".concat (ptr, arr, null);
223 } else {
224 /* raise error */
225 Report.error (source_reference, "unresolved type reference");
226 return null;
231 * Returns the name and qualifiers of this type as it is used in C code
232 * in a const declaration.
234 * @return the type string to be used in C code const declarations
236 public string get_const_cname () {
237 string ptr;
238 DataType t;
239 /* FIXME: dirty hack to make constant arrays possible */
240 if (data_type is Array) {
241 t = ((Array) data_type).element_type;
242 } else {
243 t = data_type;
245 if (!t.is_reference_type ()) {
246 ptr = "";
247 } else {
248 ptr = "*";
251 return "const %s%s".printf (t.get_cname (), ptr);
255 * Returns a user-readable name of the type corresponding to this type
256 * reference.
258 * @return display name
260 public string! to_string () {
261 if (data_type != null) {
262 return data_type.symbol.get_full_name ();
263 } else if (type_parameter != null) {
264 return type_parameter.name;
265 } else {
266 return "null";
271 * Creates a shallow copy of this type reference.
273 * @return copy of this type reference
275 public TypeReference! copy () {
276 var result = new TypeReference ();
277 result.source_reference = source_reference;
278 result.transfers_ownership = transfers_ownership;
279 result.takes_ownership = takes_ownership;
280 result.is_out = is_out;
281 result.non_null = non_null;
282 result.data_type = data_type;
283 result.type_parameter = type_parameter;
284 result.floating_reference = floating_reference;
285 result.namespace_name = namespace_name;
286 result.type_name = type_name;
287 result.array_rank = array_rank;
288 result.pointer_level = pointer_level;
289 result.is_ref = is_ref;
290 result.is_weak = is_weak;
292 foreach (TypeReference arg in type_argument_list) {
293 result.type_argument_list.append (arg.copy ());
296 return result;
300 * Checks two type references for equality. May only be used with
301 * resolved type references.
303 * @param type2 a type reference
304 * @return true if this type reference is equal to type2, false
305 * otherwise
307 public bool equals (TypeReference! type2) {
308 if (type2.transfers_ownership != transfers_ownership) {
309 return false;
311 if (type2.takes_ownership != takes_ownership) {
312 return false;
314 if (type2.is_ref != is_ref) {
315 return false;
317 if (type2.is_out != is_out) {
318 return false;
320 if (type2.non_null != non_null) {
321 return false;
323 if (type2.data_type != data_type) {
324 return false;
326 if (type2.type_parameter != null || type_parameter != null) {
327 if (type2.type_parameter == null || type_parameter == null) {
328 return false;
330 if (!type2.type_parameter.equals (type_parameter)) {
331 return false;
334 if (type2.floating_reference != floating_reference) {
335 return false;
338 return true;
342 * Checks whether this type reference is at least as strict as the
343 * specified type reference type2.
345 * @param type2 a type reference
346 * @return true if this type reference is stricter or equal
348 public bool stricter (TypeReference! type2) {
349 if (type2.transfers_ownership != transfers_ownership) {
350 return false;
352 if (type2.takes_ownership != takes_ownership) {
353 return false;
355 if (type2.is_ref != is_ref) {
356 return false;
358 if (type2.is_out != is_out) {
359 return false;
362 if (type2.non_null && !non_null) {
363 return false;
366 if (type2.data_type != data_type) {
367 // FIXME: allow this type reference to refer to a
368 // subtype of the type type2 is referring to
369 return false;
371 if (type2.type_parameter != type_parameter) {
372 return false;
374 if (type2.floating_reference != floating_reference) {
375 return false;
378 return true;