Insert "%s" argument in printf calls with non-literal format string
[vala-lang.git] / vala / valaenum.vala
blobb348f9c91eb3a6ea0acfa57c9a879e2cdb42cf1a
1 /* valaenum.vala
3 * Copyright (C) 2006-2009 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;
24 using Gee;
26 /**
27 * Represents an enum declaration in the source code.
29 public class Vala.Enum : TypeSymbol {
30 /**
31 * Specifies whether this is a flags enum.
33 public bool is_flags { get; set; }
35 /**
36 * Specifies whether this enum has a registered GType.
38 public bool has_type_id { get; set; default = true; }
40 private Gee.List<EnumValue> values = new ArrayList<EnumValue> ();
41 private Gee.List<Method> methods = new ArrayList<Method> ();
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 values.add (value);
66 scope.add (value.name, value);
69 /**
70 * Adds the specified method as a member to this enum.
72 * @param m a method
74 public void add_method (Method m) {
75 if (m is CreationMethod) {
76 Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
78 m.error = true;
79 return;
81 if (m.binding == MemberBinding.INSTANCE) {
82 m.this_parameter = new FormalParameter ("this", new EnumValueType (this));
83 m.scope.add (m.this_parameter.name, m.this_parameter);
86 methods.add (m);
87 scope.add (m.name, m);
90 /**
91 * Returns a copy of the list of enum values.
93 * @return list of enum values
95 public Gee.List<EnumValue> get_values () {
96 return new ReadOnlyList<EnumValue> (values);
99 /**
100 * Returns a copy of the list of methods.
102 * @return list of methods
104 public Gee.List<Method> get_methods () {
105 return new ReadOnlyList<Method> (methods);
108 public override void accept (CodeVisitor visitor) {
109 visitor.visit_enum (this);
112 public override void accept_children (CodeVisitor visitor) {
113 foreach (EnumValue value in values) {
114 value.accept (visitor);
117 foreach (Method m in methods) {
118 m.accept (visitor);
122 public override string get_cname (bool const_type = false) {
123 if (cname == null) {
124 var attr = get_attribute ("CCode");
125 if (attr != null) {
126 cname = attr.get_string ("cname");
128 if (cname == null) {
129 cname = "%s%s".printf (parent_symbol.get_cprefix (), name);
132 return cname;
135 public void set_cname (string cname) {
136 this.cname = cname;
139 public override string get_lower_case_cprefix () {
140 if (lower_case_cprefix == null) {
141 lower_case_cprefix = "%s_".printf (get_lower_case_cname (null));
143 return lower_case_cprefix;
146 private string get_lower_case_csuffix () {
147 if (lower_case_csuffix == null) {
148 lower_case_csuffix = camel_case_to_lower_case (name);
150 return lower_case_csuffix;
153 public override string? get_lower_case_cname (string? infix) {
154 if (infix == null) {
155 infix = "";
157 return "%s%s%s".printf (parent_symbol.get_lower_case_cprefix (), infix, get_lower_case_csuffix ());
160 public override string? get_upper_case_cname (string? infix = null) {
161 return get_lower_case_cname (infix).up ();
164 public override bool is_reference_type () {
165 return false;
168 public override string get_cprefix () {
169 if (cprefix == null) {
170 cprefix = "%s_".printf (get_upper_case_cname ());
172 return cprefix;
176 * Sets the string to be prepended to the name of members of this enum
177 * when used in C code.
179 * @param cprefix the prefix to be used in C code
181 public void set_cprefix (string? cprefix) {
182 this.cprefix = cprefix;
185 private void process_ccode_attribute (Attribute a) {
186 if (a.has_argument ("cprefix")) {
187 set_cprefix (a.get_string ("cprefix"));
189 if (a.has_argument ("lower_case_csuffix")) {
190 lower_case_csuffix = a.get_string ("lower_case_csuffix");
192 if (a.has_argument ("cheader_filename")) {
193 var val = a.get_string ("cheader_filename");
194 foreach (string filename in val.split (",")) {
195 add_cheader_filename (filename);
198 if (a.has_argument ("has_type_id")) {
199 has_type_id = a.get_bool ("has_type_id");
201 if (a.has_argument ("type_id")) {
202 type_id = a.get_string ("type_id");
207 * Process all associated attributes.
209 public void process_attributes () {
210 foreach (Attribute a in attributes) {
211 if (a.name == "CCode") {
212 process_ccode_attribute (a);
213 } else if (a.name == "Flags") {
214 is_flags = true;
219 public void set_type_id (string? type_id) {
220 this.type_id = type_id;
223 public override string? get_type_id () {
224 if (type_id == null) {
225 if (has_type_id) {
226 type_id = get_upper_case_cname ("TYPE_");
227 } else {
228 type_id = is_flags ? "G_TYPE_UINT" : "G_TYPE_INT";
232 return type_id;
235 public override string? get_marshaller_type_name () {
236 if (has_type_id) {
237 if (is_flags) {
238 return "FLAGS";
239 } else {
240 return "ENUM";
242 } else {
243 if (is_flags) {
244 return "UINT";
245 } else {
246 return "INT";
251 public override string? get_get_value_function () {
252 if (has_type_id) {
253 if (is_flags) {
254 return "g_value_get_flags";
255 } else {
256 return "g_value_get_enum";
258 } else {
259 if (is_flags) {
260 return "g_value_get_uint";
261 } else {
262 return "g_value_get_int";
267 public override string? get_set_value_function () {
268 if (has_type_id) {
269 if (is_flags) {
270 return "g_value_set_flags";
271 } else {
272 return "g_value_set_enum";
274 } else {
275 if (is_flags) {
276 return "g_value_set_uint";
277 } else {
278 return "g_value_set_int";
283 public override string? get_default_value () {
284 return "0";
287 public override string? get_type_signature () {
288 if (is_flags) {
289 return "u";
290 } else {
291 return "i";
295 public override bool check (SemanticAnalyzer analyzer) {
296 if (checked) {
297 return !error;
300 checked = true;
302 process_attributes ();
304 var old_source_file = analyzer.current_source_file;
306 if (source_reference != null) {
307 analyzer.current_source_file = source_reference.file;
310 foreach (EnumValue value in values) {
311 value.check (analyzer);
314 foreach (Method m in methods) {
315 m.check (analyzer);
318 analyzer.current_source_file = old_source_file;
320 return !error;