Add support for async signal handlers
[vala-lang.git] / vala / valaenum.vala
blobf5fca292f68d6e3c4f07afd71f3baa56524a1eea
1 /* valaenum.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 an enum declaration in the source code.
28 public class Vala.Enum : TypeSymbol {
29 /**
30 * Specifies whether this is a flags enum.
32 public bool is_flags { get; set; }
34 /**
35 * Specifies whether this enum has a registered GType.
37 public bool has_type_id { get; set; default = true; }
39 private List<EnumValue> values = new ArrayList<EnumValue> ();
40 private List<Method> methods = new ArrayList<Method> ();
41 private List<Constant> constants = new ArrayList<Constant> ();
42 private string cname;
43 private string cprefix;
44 private string lower_case_cprefix;
45 private string lower_case_csuffix;
46 private string type_id;
48 /**
49 * Creates a new enum.
51 * @param name type name
52 * @param source_reference reference to source code
53 * @return newly created enum
55 public Enum (string name, SourceReference? source_reference = null, Comment? comment = null) {
56 base (name, source_reference, comment);
59 /**
60 * Appends the specified enum value to the list of values.
62 * @param value an enum value
64 public void add_value (EnumValue value) {
65 value.access = SymbolAccessibility.PUBLIC;
67 values.add (value);
68 scope.add (value.name, value);
71 /**
72 * Adds the specified method as a member to this enum.
74 * @param m a method
76 public override void add_method (Method m) {
77 if (m is CreationMethod) {
78 Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
80 m.error = true;
81 return;
83 if (m.binding == MemberBinding.INSTANCE) {
84 m.this_parameter = new Parameter ("this", new EnumValueType (this));
85 m.scope.add (m.this_parameter.name, m.this_parameter);
87 if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
88 m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
89 m.result_var.is_result = true;
92 methods.add (m);
93 scope.add (m.name, m);
96 /**
97 * Adds the specified constant as a member to this enum.
99 * @param c a constant
101 public override void add_constant (Constant c) {
102 constants.add (c);
103 scope.add (c.name, c);
107 * Returns a copy of the list of enum values.
109 * @return list of enum values
111 public List<EnumValue> get_values () {
112 return values;
115 // used by vapigen
116 public void remove_all_values () {
117 values.clear ();
121 * Returns a copy of the list of methods.
123 * @return list of methods
125 public List<Method> get_methods () {
126 return methods;
130 * Returns a copy of the list of constants.
132 * @return list of constants
134 public List<Constant> get_constants () {
135 return constants;
138 public override void accept (CodeVisitor visitor) {
139 visitor.visit_enum (this);
142 public override void accept_children (CodeVisitor visitor) {
143 foreach (EnumValue value in values) {
144 value.accept (visitor);
147 foreach (Method m in methods) {
148 m.accept (visitor);
151 foreach (Constant c in constants) {
152 c.accept (visitor);
156 public override string get_cname (bool const_type = false) {
157 if (cname == null) {
158 var attr = get_attribute ("CCode");
159 if (attr != null) {
160 cname = attr.get_string ("cname");
162 if (cname == null) {
163 cname = "%s%s".printf (parent_symbol.get_cprefix (), name);
166 return cname;
169 public void set_cname (string cname) {
170 this.cname = cname;
173 public override string get_lower_case_cprefix () {
174 if (lower_case_cprefix == null) {
175 lower_case_cprefix = "%s_".printf (get_lower_case_cname (null));
177 return lower_case_cprefix;
180 private string get_lower_case_csuffix () {
181 if (lower_case_csuffix == null) {
182 lower_case_csuffix = camel_case_to_lower_case (name);
184 return lower_case_csuffix;
187 public override string? get_lower_case_cname (string? infix) {
188 if (infix == null) {
189 infix = "";
191 return "%s%s%s".printf (parent_symbol.get_lower_case_cprefix (), infix, get_lower_case_csuffix ());
194 public override string? get_upper_case_cname (string? infix = null) {
195 return get_lower_case_cname (infix).up ();
198 public override bool is_reference_type () {
199 return false;
202 public override string get_cprefix () {
203 if (cprefix == null) {
204 cprefix = "%s_".printf (get_upper_case_cname ());
206 return cprefix;
210 * Sets the string to be prepended to the name of members of this enum
211 * when used in C code.
213 * @param cprefix the prefix to be used in C code
215 public void set_cprefix (string? cprefix) {
216 this.cprefix = cprefix;
219 private void process_ccode_attribute (Attribute a) {
220 if (a.has_argument ("cprefix")) {
221 set_cprefix (a.get_string ("cprefix"));
223 if (a.has_argument ("lower_case_csuffix")) {
224 lower_case_csuffix = a.get_string ("lower_case_csuffix");
226 if (a.has_argument ("cheader_filename")) {
227 var val = a.get_string ("cheader_filename");
228 foreach (string filename in val.split (",")) {
229 add_cheader_filename (filename);
232 if (a.has_argument ("has_type_id")) {
233 has_type_id = a.get_bool ("has_type_id");
235 if (a.has_argument ("type_id")) {
236 type_id = a.get_string ("type_id");
241 * Process all associated attributes.
243 public void process_attributes () {
244 foreach (Attribute a in attributes) {
245 if (a.name == "CCode") {
246 process_ccode_attribute (a);
247 } else if (a.name == "Flags") {
248 is_flags = true;
249 } else if (a.name == "Deprecated") {
250 process_deprecated_attribute (a);
255 public void set_type_id (string? type_id) {
256 this.type_id = type_id;
259 public override string? get_type_id () {
260 if (type_id == null) {
261 if (has_type_id) {
262 type_id = get_upper_case_cname ("TYPE_");
263 } else {
264 type_id = is_flags ? "G_TYPE_UINT" : "G_TYPE_INT";
268 return type_id;
271 public override string? get_marshaller_type_name () {
272 if (has_type_id) {
273 if (is_flags) {
274 return "FLAGS";
275 } else {
276 return "ENUM";
278 } else {
279 if (is_flags) {
280 return "UINT";
281 } else {
282 return "INT";
287 public override string? get_get_value_function () {
288 if (has_type_id) {
289 if (is_flags) {
290 return "g_value_get_flags";
291 } else {
292 return "g_value_get_enum";
294 } else {
295 if (is_flags) {
296 return "g_value_get_uint";
297 } else {
298 return "g_value_get_int";
303 public override string? get_set_value_function () {
304 if (has_type_id) {
305 if (is_flags) {
306 return "g_value_set_flags";
307 } else {
308 return "g_value_set_enum";
310 } else {
311 if (is_flags) {
312 return "g_value_set_uint";
313 } else {
314 return "g_value_set_int";
319 public override string? get_default_value () {
320 return "0";
323 public override bool check (CodeContext context) {
324 if (checked) {
325 return !error;
328 checked = true;
330 process_attributes ();
332 var old_source_file = context.analyzer.current_source_file;
333 var old_symbol = context.analyzer.current_symbol;
335 if (source_reference != null) {
336 context.analyzer.current_source_file = source_reference.file;
338 context.analyzer.current_symbol = this;
340 foreach (EnumValue value in values) {
341 value.check (context);
344 foreach (Method m in methods) {
345 m.check (context);
348 foreach (Constant c in constants) {
349 c.check (context);
352 context.analyzer.current_source_file = old_source_file;
353 context.analyzer.current_symbol = old_symbol;
355 return !error;