codegen: Custom abstract methods of GLib.Source are handled differently
[vala-gnome.git] / vala / valacodenode.vala
blob5413ed434ad0a698a9d0168ad0b8d4b3076cc140
1 /* valacodenode.vala
3 * Copyright (C) 2006-2010 Jürg Billeter
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.1 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>
23 using GLib;
25 /**
26 * Represents a part of the parsed source code.
28 * Code nodes get created by the parser and are used throughout the whole
29 * compilation process.
31 public abstract class Vala.CodeNode {
32 /**
33 * Parent of this code node.
35 public weak CodeNode? parent_node { get; set; }
37 /**
38 * References the location in the source file where this code node has
39 * been written.
41 public SourceReference? source_reference { get; set; }
43 public bool unreachable { get; set; }
45 /**
46 * Contains all attributes that have been specified for this code node.
48 public GLib.List<Attribute> attributes;
50 public string type_name {
51 get { return Type.from_instance (this).name (); }
54 public bool checked { get; set; }
56 /**
57 * Specifies whether a fatal error has been detected in this code node.
59 public bool error { get; set; }
61 /**
62 * Specifies that this node or a child node may throw an exception.
64 public bool tree_can_fail {
65 get { return _error_types != null && _error_types.size > 0; }
68 private List<DataType> _error_types;
69 private static List<DataType> _empty_type_list;
70 private AttributeCache[] attributes_cache;
72 static int last_temp_nr = 0;
73 static int next_attribute_cache_index = 0;
75 /**
76 * Specifies the exceptions that can be thrown by this node or a child node
78 public List<DataType> get_error_types () {
79 if (_error_types != null) {
80 return _error_types;
82 if (_empty_type_list == null) {
83 _empty_type_list = new ArrayList<DataType> ();
85 return _empty_type_list;
88 /**
89 * Adds an error type to the exceptions that can be thrown by this node
90 * or a child node
92 public void add_error_type (DataType error_type) {
93 if (_error_types == null) {
94 _error_types = new ArrayList<DataType> ();
96 _error_types.add (error_type);
97 error_type.parent_node = this;
101 * Adds a collection of error types to the exceptions that can be thrown by this node
102 * or a child node
104 public void add_error_types (List<DataType> error_types) {
105 foreach (DataType error_type in error_types) {
106 add_error_type (error_type);
111 * Visits this code node with the specified CodeVisitor.
113 * @param visitor the visitor to be called while traversing
115 public virtual void accept (CodeVisitor visitor) {
119 * Visits all children of this code node with the specified CodeVisitor.
121 * @param visitor the visitor to be called while traversing
123 public virtual void accept_children (CodeVisitor visitor) {
126 public virtual bool check (CodeContext context) {
127 return true;
130 public virtual void emit (CodeGenerator codegen) {
133 public virtual void replace_type (DataType old_type, DataType new_type) {
136 public virtual void replace_expression (Expression old_node, Expression new_node) {
140 * Returns the specified attribute.
142 * @param name attribute name
143 * @return attribute
145 public Attribute? get_attribute (string name) {
146 // FIXME: use hash table
147 foreach (Attribute a in attributes) {
148 if (a.name == name) {
149 return a;
153 return null;
157 * Returns true if the specified attribute argument is set.
159 * @param attribute attribute name
160 * @param argument argument name
161 * @return true if the attribute has the given argument
163 public bool has_attribute_argument (string attribute, string argument) {
164 var a = get_attribute (attribute);
165 if (a == null) {
166 return false;
168 return a.has_argument (argument);
172 * Sets the specified named attribute to this code node.
174 * @param name attribute name
175 * @param value true to add the attribute, false to remove it
177 public void set_attribute (string name, bool value, SourceReference? source_reference = null) {
178 var a = get_attribute (name);
179 if (value && a == null) {
180 attributes.append (new Attribute (name, source_reference));
181 } else if (!value && a != null) {
182 attributes.remove (a);
187 * Remove the specified named attribute argument
189 * @param attribute attribute name
190 * @param argument argument name
192 public void remove_attribute_argument (string attribute, string argument) {
193 var a = get_attribute (attribute);
194 if (a != null) {
195 a.args.remove (argument);
196 if (a.args.size == 0) {
197 attributes.remove (a);
203 * Returns the string value of the specified attribute argument.
205 * @param attribute attribute name
206 * @param argument argument name
207 * @return string value
209 public string? get_attribute_string (string attribute, string argument, string? default_value = null) {
210 var a = get_attribute (attribute);
211 if (a == null) {
212 return default_value;
214 return a.get_string (argument, default_value);
218 * Returns the integer value of the specified attribute argument.
220 * @param attribute attribute name
221 * @param argument argument name
222 * @return integer value
224 public int get_attribute_integer (string attribute, string argument, int default_value = 0) {
225 var a = get_attribute (attribute);
226 if (a == null) {
227 return default_value;
229 return a.get_integer (argument, default_value);
233 * Returns the double value of the specified attribute argument.
235 * @param attribute attribute name
236 * @param argument argument name
237 * @return double value
239 public double get_attribute_double (string attribute, string argument, double default_value = 0) {
240 if (attributes == null) {
241 return default_value;
243 var a = get_attribute (attribute);
244 if (a == null) {
245 return default_value;
247 return a.get_double (argument, default_value);
251 * Returns the bool value of the specified attribute argument.
253 * @param attribute attribute name
254 * @param argument argument name
255 * @return bool value
257 public bool get_attribute_bool (string attribute, string argument, bool default_value = false) {
258 if (attributes == null) {
259 return default_value;
261 var a = get_attribute (attribute);
262 if (a == null) {
263 return default_value;
265 return a.get_bool (argument, default_value);
269 * Sets the string value of the specified attribute argument.
271 * @param attribute attribute name
272 * @param argument argument name
273 * @param value string value
275 public void set_attribute_string (string attribute, string argument, string? value, SourceReference? source_reference = null) {
276 if (value == null) {
277 remove_attribute_argument (attribute, argument);
278 return;
281 var a = get_attribute (attribute);
282 if (a == null) {
283 a = new Attribute (attribute, source_reference);
284 attributes.append (a);
286 a.add_argument (argument, "\"%s\"".printf (value));
290 * Sets the integer value of the specified attribute argument.
292 * @param attribute attribute name
293 * @param argument argument name
294 * @param value integer value
296 public void set_attribute_integer (string attribute, string argument, int value, SourceReference? source_reference = null) {
297 var a = get_attribute (attribute);
298 if (a == null) {
299 a = new Attribute (attribute, source_reference);
300 attributes.append (a);
302 a.add_argument (argument, value.to_string ());
306 * Sets the integer value of the specified attribute argument.
308 * @param attribute attribute name
309 * @param argument argument name
310 * @param value double value
312 public void set_attribute_double (string attribute, string argument, double value, SourceReference? source_reference = null) {
313 var a = get_attribute (attribute);
314 if (a == null) {
315 a = new Attribute (attribute, source_reference);
316 attributes.append (a);
318 a.add_argument (argument, value.format (new char[double.DTOSTR_BUF_SIZE]));
322 * Sets the boolean value of the specified attribute argument.
324 * @param attribute attribute name
325 * @param argument argument name
326 * @param value bool value
328 public void set_attribute_bool (string attribute, string argument, bool value, SourceReference? source_reference = null) {
329 var a = get_attribute (attribute);
330 if (a == null) {
331 a = new Attribute (attribute, source_reference);
332 attributes.append (a);
334 a.add_argument (argument, value.to_string ());
338 * Returns the attribute cache at the specified index.
340 * @param index attribute cache index
341 * @return attribute cache
343 public AttributeCache? get_attribute_cache (int index) {
344 if (index >= attributes_cache.length) {
345 return null;
347 return attributes_cache[index];
351 * Sets the specified attribute cache to this code node.
353 * @param index attribute cache index
354 * @param cache attribute cache
356 public void set_attribute_cache (int index, AttributeCache cache) {
357 if (index >= attributes_cache.length) {
358 attributes_cache.resize (index * 2 + 1);
360 attributes_cache[index] = cache;
364 * Returns a string that represents this code node.
366 * @return a string representation
368 public virtual string to_string () {
369 var str = new StringBuilder ();
371 str.append ("/* ");
373 if (source_reference != null) {
374 str.append ("@").append (source_reference.to_string ());
377 return str.append (" */").str;
380 public virtual void get_defined_variables (Collection<Variable> collection) {
383 public virtual void get_used_variables (Collection<Variable> collection) {
386 public static string get_temp_name () {
387 return "." + (++last_temp_nr).to_string ();
391 * Returns a new cache index for accessing the attributes cache of code nodes
393 * @return a new cache index
395 public static int get_attribute_cache_index () {
396 return next_attribute_cache_index++;
400 public class Vala.AttributeCache {