codegen: Fix floating reference regression with Variants
[vala-gnome.git] / codegen / valaccode.vala
blob1bb92171ea1b331dfbbec88ccfa7d5c8b26cc047
1 /* valaccode.vala
3 * Copyright (C) 2017 Rico Tzschichholz
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 * Rico Tzschichholz <ricotz@ubuntu.com>
23 namespace Vala {
24 static int? ccode_attribute_cache_index = null;
26 static unowned CCodeAttribute get_ccode_attribute (CodeNode node) {
27 if (ccode_attribute_cache_index == null) {
28 ccode_attribute_cache_index = CodeNode.get_attribute_cache_index ();
31 unowned AttributeCache? attr = node.get_attribute_cache (ccode_attribute_cache_index);
32 if (attr == null) {
33 var new_attr = new CCodeAttribute (node);
34 node.set_attribute_cache (ccode_attribute_cache_index, new_attr);
35 attr = new_attr;
37 return (CCodeAttribute) attr;
40 public static string get_ccode_name (CodeNode node) {
41 return get_ccode_attribute(node).name;
44 public static string get_ccode_const_name (CodeNode node) {
45 return get_ccode_attribute(node).const_name;
48 public static string get_ccode_type_name (Interface iface) {
49 return get_ccode_attribute(iface).type_name;
52 public static string get_ccode_lower_case_name (CodeNode node, string? infix = null) {
53 unowned Symbol? sym = node as Symbol;
54 if (sym != null) {
55 if (infix == null) {
56 infix = "";
58 if (sym is Delegate) {
59 return "%s%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), infix, Symbol.camel_case_to_lower_case (sym.name));
60 } else if (sym is Signal) {
61 return get_ccode_attribute (sym).name.replace ("-", "_");
62 } else if (sym is ErrorCode) {
63 return get_ccode_name (sym).down ();
64 } else {
65 return "%s%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), infix, get_ccode_lower_case_suffix (sym));
67 } else if (node is ErrorType) {
68 unowned ErrorType type = (ErrorType) node;
69 if (type.error_domain == null) {
70 if (infix == null) {
71 return "g_error";
72 } else {
73 return "g_%s_error".printf (infix);
75 } else if (type.error_code == null) {
76 return get_ccode_lower_case_name (type.error_domain, infix);
77 } else {
78 return get_ccode_lower_case_name (type.error_code, infix);
80 } else if (node is DelegateType) {
81 unowned DelegateType type = (DelegateType) node;
82 return get_ccode_lower_case_name (type.delegate_symbol, infix);
83 } else if (node is PointerType) {
84 unowned PointerType type = (PointerType) node;
85 return get_ccode_lower_case_name (type.base_type, infix);
86 } else if (node is GenericType) {
87 return "valageneric";
88 } else if (node is VoidType) {
89 return "valavoid";
90 } else {
91 unowned DataType type = (DataType) node;
92 return get_ccode_lower_case_name (type.data_type, infix);
96 public static string get_ccode_upper_case_name (Symbol sym, string? infix = null) {
97 if (sym is Property) {
98 return "%s_%s".printf (get_ccode_lower_case_name (sym.parent_symbol), Symbol.camel_case_to_lower_case (sym.name)).ascii_up ();
99 } else {
100 return get_ccode_lower_case_name (sym, infix).ascii_up ();
104 public static string get_ccode_header_filenames (Symbol sym) {
105 return get_ccode_attribute(sym).header_filenames;
108 public static string get_ccode_feature_test_macros (Symbol sym) {
109 return get_ccode_attribute(sym).feature_test_macros;
112 public static string get_ccode_prefix (Symbol sym) {
113 return get_ccode_attribute(sym).prefix;
116 public static string get_ccode_lower_case_prefix (Symbol sym) {
117 return get_ccode_attribute(sym).lower_case_prefix;
120 public static string get_ccode_lower_case_suffix (Symbol sym) {
121 return get_ccode_attribute(sym).lower_case_suffix;
124 public static string get_ccode_ref_function (TypeSymbol sym) {
125 return get_ccode_attribute(sym).ref_function;
128 public static string get_ccode_quark_name (ErrorDomain edomain) {
129 return get_ccode_lower_case_name (edomain) + "-quark";
132 public static bool is_reference_counting (TypeSymbol sym) {
133 if (sym is Class) {
134 return get_ccode_ref_function (sym) != null;
135 } else if (sym is Interface) {
136 return true;
137 } else {
138 return false;
142 public static bool get_ccode_ref_function_void (Class cl) {
143 return get_ccode_attribute(cl).ref_function_void;
146 public static bool get_ccode_free_function_address_of (Class cl) {
147 return get_ccode_attribute(cl).free_function_address_of;
150 public static string get_ccode_unref_function (ObjectTypeSymbol sym) {
151 return get_ccode_attribute(sym).unref_function;
154 public static string get_ccode_ref_sink_function (ObjectTypeSymbol sym) {
155 return get_ccode_attribute(sym).ref_sink_function;
158 public static string get_ccode_copy_function (TypeSymbol sym) {
159 return get_ccode_attribute(sym).copy_function;
162 public static string get_ccode_destroy_function (TypeSymbol sym) {
163 return get_ccode_attribute(sym).destroy_function;
166 public static string? get_ccode_dup_function (TypeSymbol sym) {
167 if (sym is Struct) {
168 return get_ccode_attribute (sym).dup_function;
170 return get_ccode_copy_function (sym);
173 public static string get_ccode_free_function (TypeSymbol sym) {
174 return get_ccode_attribute(sym).free_function;
177 public static bool get_ccode_is_gboxed (TypeSymbol sym) {
178 return get_ccode_free_function (sym) == "g_boxed_free";
181 public static bool get_ccode_finish_instance (CodeNode node) {
182 return get_ccode_attribute (node).finish_instance;
185 public static string get_ccode_type_id (CodeNode node) {
186 return get_ccode_attribute(node).type_id;
189 public static string get_ccode_marshaller_type_name (CodeNode node) {
190 return get_ccode_attribute(node).marshaller_type_name;
193 public static string get_ccode_get_value_function (CodeNode sym) {
194 return get_ccode_attribute(sym).get_value_function;
197 public static string get_ccode_set_value_function (CodeNode sym) {
198 return get_ccode_attribute(sym).set_value_function;
201 public static string get_ccode_take_value_function (CodeNode sym) {
202 return get_ccode_attribute(sym).take_value_function;
205 public static string get_ccode_param_spec_function (CodeNode sym) {
206 return get_ccode_attribute(sym).param_spec_function;
209 public static string get_ccode_type_check_function (TypeSymbol sym) {
210 unowned Class? cl = sym as Class;
211 var a = sym.get_attribute_string ("CCode", "type_check_function");
212 if (cl != null && a != null) {
213 return a;
214 } else if ((cl != null && cl.is_compact) || sym is Struct || sym is Enum || sym is Delegate) {
215 return "";
216 } else {
217 return get_ccode_upper_case_name (sym, "IS_");
221 public static string get_ccode_default_value (TypeSymbol sym) {
222 return get_ccode_attribute(sym).default_value;
225 public static string get_ccode_default_value_on_error (TypeSymbol sym) {
226 return get_ccode_attribute (sym).default_value_on_error;
229 public static bool get_ccode_has_copy_function (Struct st) {
230 return st.get_attribute_bool ("CCode", "has_copy_function", true);
233 public static bool get_ccode_has_destroy_function (Struct st) {
234 return st.get_attribute_bool ("CCode", "has_destroy_function", true);
237 public static double get_ccode_instance_pos (CodeNode node) {
238 if (node is Delegate) {
239 return node.get_attribute_double ("CCode", "instance_pos", -2);
240 } else {
241 return node.get_attribute_double ("CCode", "instance_pos", 0);
245 public static bool get_ccode_array_length (CodeNode node) {
246 return get_ccode_attribute(node).array_length;
249 public static string? get_ccode_array_length_type (CodeNode node) {
250 return get_ccode_attribute(node).array_length_type;
253 public static bool get_ccode_array_null_terminated (CodeNode node) {
254 return get_ccode_attribute(node).array_null_terminated;
257 public static string? get_ccode_array_length_name (CodeNode node) {
258 return get_ccode_attribute(node).array_length_name;
261 public static string? get_ccode_array_length_expr (CodeNode node) {
262 return get_ccode_attribute(node).array_length_expr;
265 public static double get_ccode_array_length_pos (CodeNode node) {
266 var a = node.get_attribute ("CCode");
267 if (a != null && a.has_argument ("array_length_pos")) {
268 return a.get_double ("array_length_pos");
270 if (node is Parameter) {
271 unowned Parameter param = (Parameter) node;
272 return get_ccode_pos (param) + 0.1;
273 } else {
274 return -3;
278 public static double get_ccode_delegate_target_pos (CodeNode node) {
279 var a = node.get_attribute ("CCode");
280 if (a != null && a.has_argument ("delegate_target_pos")) {
281 return a.get_double ("delegate_target_pos");
283 if (node is Parameter) {
284 unowned Parameter param = (Parameter) node;
285 return get_ccode_pos (param) + 0.1;
286 } else {
287 return -3;
291 public static double get_ccode_destroy_notify_pos (CodeNode node) {
292 var a = node.get_attribute ("CCode");
293 if (a != null && a.has_argument ("destroy_notify_pos")) {
294 return a.get_double ("destroy_notify_pos");
296 if (node is Parameter) {
297 unowned Parameter param = (Parameter) node;
298 return get_ccode_pos (param) + 0.1;
299 } else {
300 return -3;
304 public static bool get_ccode_delegate_target (CodeNode node) {
305 return get_ccode_attribute(node).delegate_target;
308 public static string get_ccode_delegate_target_name (Variable variable) {
309 return get_ccode_attribute(variable).delegate_target_name;
312 public static double get_ccode_pos (Parameter param) {
313 return get_ccode_attribute(param).pos;
316 public static string? get_ccode_type (CodeNode node) {
317 return get_ccode_attribute(node).ctype;
320 public static bool get_ccode_simple_generics (Method m) {
321 return m.get_attribute_bool ("CCode", "simple_generics");
324 public static string get_ccode_real_name (Symbol sym) {
325 return get_ccode_attribute(sym).real_name;
328 public static string get_ccode_constructv_name (CreationMethod m) {
329 const string infix = "constructv";
331 unowned Class parent = (Class) m.parent_symbol;
333 if (m.name == ".new") {
334 return "%s%s".printf (get_ccode_lower_case_prefix (parent), infix);
335 } else {
336 return "%s%s_%s".printf (get_ccode_lower_case_prefix (parent), infix, m.name);
340 public static string get_ccode_vfunc_name (Method m) {
341 return get_ccode_attribute(m).vfunc_name;
344 public static string get_ccode_finish_name (Method m) {
345 return get_ccode_attribute(m).finish_name;
348 public static string get_ccode_finish_vfunc_name (Method m) {
349 return get_ccode_attribute(m).finish_vfunc_name;
352 public static string get_ccode_finish_real_name (Method m) {
353 return get_ccode_attribute(m).finish_real_name;
356 public static bool get_ccode_no_accessor_method (Property p) {
357 return p.get_attribute ("NoAccessorMethod") != null;
360 public static bool get_ccode_concrete_accessor (Property p) {
361 return p.get_attribute ("ConcreteAccessor") != null;
364 public static bool get_ccode_has_type_id (TypeSymbol sym) {
365 return sym.get_attribute_bool ("CCode", "has_type_id", true);
368 public static bool get_ccode_has_new_function (Method m) {
369 return m.get_attribute_bool ("CCode", "has_new_function", true);
372 public static bool get_ccode_has_generic_type_parameter (Method m) {
373 var a = m.get_attribute ("CCode");
374 return a != null && a.has_argument ("generic_type_pos");
377 public static double get_ccode_generic_type_pos (Method m) {
378 return m.get_attribute_double ("CCode", "generic_type_pos");
381 public static string get_ccode_sentinel (Method m) {
382 return get_ccode_attribute(m).sentinel;