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
20 * Rico Tzschichholz <ricotz@ubuntu.com>
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);
33 var new_attr = new CCodeAttribute (node);
34 node.set_attribute_cache (ccode_attribute_cache_index, 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 (ObjectTypeSymbol sym) {
49 return get_ccode_attribute (sym).type_name;
52 public static string get_ccode_type_cast_function (ObjectTypeSymbol sym) {
53 assert (!(sym is Class && ((Class) sym).is_compact));
54 return get_ccode_upper_case_name (sym);
57 public static string get_ccode_type_get_function (ObjectTypeSymbol sym) {
58 var func_name = sym.get_attribute_string ("CCode", "type_get_function");
59 if (func_name != null) {
63 assert (!((Class) sym).is_compact);
64 return "%s_GET_CLASS".printf (get_ccode_upper_case_name (sym));
65 } else if (sym is Interface) {
66 return "%s_GET_INTERFACE".printf (get_ccode_upper_case_name (sym));
68 Report.error (sym.source_reference, "`CCode.type_get_function' not supported");
73 public static string get_ccode_class_get_private_function (Class cl) {
74 assert (!cl.is_compact);
75 return "%s_GET_CLASS_PRIVATE".printf (get_ccode_upper_case_name (cl));
78 public static string get_ccode_class_type_function (Class cl) {
79 assert (!cl.is_compact);
80 return "%s_CLASS".printf (get_ccode_upper_case_name (cl));
83 public static string get_ccode_lower_case_name (CodeNode node, string? infix = null) {
84 unowned Symbol? sym = node as Symbol;
89 if (sym is Delegate) {
90 return "%s%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), infix, Symbol.camel_case_to_lower_case (sym.name));
91 } else if (sym is Signal) {
92 return get_ccode_attribute (sym).name.replace ("-", "_");
93 } else if (sym is ErrorCode) {
94 return get_ccode_name (sym).ascii_down ();
96 return "%s%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), infix, get_ccode_lower_case_suffix (sym));
98 } else if (node is ErrorType) {
99 unowned ErrorType type = (ErrorType) node;
100 if (type.error_domain == null) {
104 return "g_%s_error".printf (infix);
106 } else if (type.error_code == null) {
107 return get_ccode_lower_case_name (type.error_domain, infix);
109 return get_ccode_lower_case_name (type.error_code, infix);
111 } else if (node is DelegateType) {
112 unowned DelegateType type = (DelegateType) node;
113 return get_ccode_lower_case_name (type.delegate_symbol, infix);
114 } else if (node is PointerType) {
115 unowned PointerType type = (PointerType) node;
116 return get_ccode_lower_case_name (type.base_type, infix);
117 } else if (node is GenericType) {
118 return "valageneric";
119 } else if (node is VoidType) {
122 unowned DataType type = (DataType) node;
123 return get_ccode_lower_case_name (type.type_symbol, infix);
127 public static string get_ccode_upper_case_name (Symbol sym, string? infix = null) {
128 if (sym is Property) {
129 return "%s_%s".printf (get_ccode_lower_case_name (sym.parent_symbol), Symbol.camel_case_to_lower_case (sym.name)).ascii_up ();
131 return get_ccode_lower_case_name (sym, infix).ascii_up ();
135 public static string get_ccode_header_filenames (Symbol sym) {
136 return get_ccode_attribute(sym).header_filenames;
139 public static string get_ccode_feature_test_macros (Symbol sym) {
140 return get_ccode_attribute(sym).feature_test_macros;
143 public static string get_ccode_prefix (Symbol sym) {
144 return get_ccode_attribute(sym).prefix;
147 public static string get_ccode_lower_case_prefix (Symbol sym) {
148 return get_ccode_attribute(sym).lower_case_prefix;
151 public static string get_ccode_lower_case_suffix (Symbol sym) {
152 return get_ccode_attribute(sym).lower_case_suffix;
155 public static string get_ccode_ref_function (TypeSymbol sym) {
156 return get_ccode_attribute(sym).ref_function;
159 public static string get_ccode_quark_name (ErrorDomain edomain) {
160 return "%s-quark".printf (get_ccode_lower_case_name (edomain).replace ("_", "-"));
163 public static bool is_reference_counting (TypeSymbol sym) {
165 return get_ccode_ref_function (sym) != null;
166 } else if (sym is Interface) {
173 public static bool is_ref_function_void (DataType type) {
174 unowned Class? cl = type.type_symbol as Class;
176 return get_ccode_ref_function_void (cl);
182 public static bool is_free_function_address_of (DataType type) {
183 unowned Class? cl = type.type_symbol as Class;
185 return get_ccode_free_function_address_of (cl);
191 public static bool get_ccode_ref_function_void (Class cl) {
192 return get_ccode_attribute(cl).ref_function_void;
195 public static bool get_ccode_free_function_address_of (Class cl) {
196 return get_ccode_attribute(cl).free_function_address_of;
199 public static string get_ccode_unref_function (ObjectTypeSymbol sym) {
200 return get_ccode_attribute(sym).unref_function;
203 public static string get_ccode_ref_sink_function (ObjectTypeSymbol sym) {
204 return get_ccode_attribute(sym).ref_sink_function;
207 public static string get_ccode_copy_function (TypeSymbol sym) {
208 return get_ccode_attribute(sym).copy_function;
211 public static string get_ccode_destroy_function (TypeSymbol sym) {
212 return get_ccode_attribute(sym).destroy_function;
215 public static string? get_ccode_dup_function (TypeSymbol sym) {
217 return get_ccode_attribute (sym).dup_function;
219 return get_ccode_copy_function (sym);
222 public static string get_ccode_free_function (TypeSymbol sym) {
223 return get_ccode_attribute(sym).free_function;
226 public static bool get_ccode_is_gboxed (TypeSymbol sym) {
227 return get_ccode_free_function (sym) == "g_boxed_free";
230 public static bool get_ccode_finish_instance (Method m) {
231 assert (m.coroutine);
232 return get_ccode_attribute (m).finish_instance;
235 public static string get_ccode_type_id (CodeNode node) {
236 return get_ccode_attribute(node).type_id;
239 public static string get_ccode_type_function (TypeSymbol sym) {
240 assert (!((sym is Class && ((Class) sym).is_compact) || sym is ErrorCode || sym is ErrorDomain || sym is Delegate));
241 return "%s_get_type".printf (get_ccode_lower_case_name (sym));
244 public static string get_ccode_marshaller_type_name (CodeNode node) {
245 return get_ccode_attribute(node).marshaller_type_name;
248 public static string get_ccode_get_value_function (CodeNode sym) {
249 return get_ccode_attribute(sym).get_value_function;
252 public static string get_ccode_set_value_function (CodeNode sym) {
253 return get_ccode_attribute(sym).set_value_function;
256 public static string get_ccode_take_value_function (CodeNode sym) {
257 return get_ccode_attribute(sym).take_value_function;
260 public static string get_ccode_param_spec_function (CodeNode sym) {
261 return get_ccode_attribute(sym).param_spec_function;
264 public static string get_ccode_type_check_function (TypeSymbol sym) {
265 unowned Class? cl = sym as Class;
266 var a = sym.get_attribute_string ("CCode", "type_check_function");
267 if (cl != null && a != null) {
269 } else if ((cl != null && cl.is_compact) || sym is Struct || sym is Enum || sym is Delegate) {
272 return get_ccode_upper_case_name (sym, "IS_");
276 public static string get_ccode_class_type_check_function (Class cl) {
277 assert (!cl.is_compact);
278 return "%s_CLASS".printf (get_ccode_type_check_function (cl));
281 public static string get_ccode_default_value (TypeSymbol sym) {
282 return get_ccode_attribute(sym).default_value;
285 public static string get_ccode_default_value_on_error (TypeSymbol sym) {
286 return get_ccode_attribute (sym).default_value_on_error;
289 public static bool get_ccode_has_copy_function (Struct st) {
290 return st.get_attribute_bool ("CCode", "has_copy_function", true);
293 public static bool get_ccode_has_destroy_function (Struct st) {
294 return st.get_attribute_bool ("CCode", "has_destroy_function", true);
297 public static double get_ccode_instance_pos (CodeNode node) {
298 if (node is Delegate) {
299 return node.get_attribute_double ("CCode", "instance_pos", -2);
301 return node.get_attribute_double ("CCode", "instance_pos", 0);
305 public static double get_ccode_error_pos (Callable c) {
306 return c.get_attribute_double ("CCode", "error_pos", -1);
309 public static bool get_ccode_array_length (CodeNode node) {
310 return get_ccode_attribute(node).array_length;
313 public static string get_ccode_array_length_type (CodeNode node) {
314 if (node is ArrayType) {
315 return get_ccode_name (((ArrayType) node).length_type);
316 } else if (node is DataType) {
317 Report.error (node.source_reference, "`CCode.array_length_type' not supported");
320 assert (node is Method || node is Parameter || node is Delegate || node is Property || node is Field);
321 return get_ccode_attribute(node).array_length_type;
325 public static bool get_ccode_array_null_terminated (CodeNode node) {
326 return get_ccode_attribute(node).array_null_terminated;
329 public static string? get_ccode_array_length_name (CodeNode node) {
330 return get_ccode_attribute(node).array_length_name;
333 public static string? get_ccode_array_length_expr (CodeNode node) {
334 return get_ccode_attribute(node).array_length_expr;
337 public static double get_ccode_array_length_pos (CodeNode node) {
338 var a = node.get_attribute ("CCode");
339 if (a != null && a.has_argument ("array_length_pos")) {
340 return a.get_double ("array_length_pos");
342 if (node is Parameter) {
343 unowned Parameter param = (Parameter) node;
344 return get_ccode_pos (param) + 0.1;
350 public static double get_ccode_delegate_target_pos (CodeNode node) {
351 var a = node.get_attribute ("CCode");
352 if (a != null && a.has_argument ("delegate_target_pos")) {
353 return a.get_double ("delegate_target_pos");
355 if (node is Parameter) {
356 unowned Parameter param = (Parameter) node;
357 return get_ccode_pos (param) + 0.1;
363 public static double get_ccode_destroy_notify_pos (CodeNode node) {
364 var a = node.get_attribute ("CCode");
365 if (a != null && a.has_argument ("destroy_notify_pos")) {
366 return a.get_double ("destroy_notify_pos");
368 return get_ccode_delegate_target_pos (node) + 0.01;
371 public static bool get_ccode_delegate_target (CodeNode node) {
372 return get_ccode_attribute(node).delegate_target;
375 public static string get_ccode_delegate_target_name (Variable variable) {
376 return get_ccode_attribute(variable).delegate_target_name;
379 public static string get_ccode_delegate_target_destroy_notify_name (Variable variable) {
380 return get_ccode_attribute(variable).delegate_target_destroy_notify_name;
383 public static double get_ccode_pos (Parameter param) {
384 return get_ccode_attribute(param).pos;
387 public static string? get_ccode_type (CodeNode node) {
388 return get_ccode_attribute(node).ctype;
391 public static bool get_ccode_simple_generics (Method m) {
392 return m.get_attribute_bool ("CCode", "simple_generics");
395 public static string get_ccode_real_name (Symbol sym) {
396 return get_ccode_attribute(sym).real_name;
399 public static string get_ccode_constructv_name (CreationMethod m) {
400 const string infix = "constructv";
402 unowned Class parent = (Class) m.parent_symbol;
404 if (m.name == ".new") {
405 return "%s%s".printf (get_ccode_lower_case_prefix (parent), infix);
407 return "%s%s_%s".printf (get_ccode_lower_case_prefix (parent), infix, m.name);
411 public static string get_ccode_vfunc_name (Method m) {
412 return get_ccode_attribute(m).vfunc_name;
415 public static double get_ccode_async_result_pos (Method m) {
416 assert (m.coroutine);
417 return m.get_attribute_double ("CCode", "async_result_pos", 0.1);
420 public static string get_ccode_finish_name (Method m) {
421 assert (m.coroutine);
422 return get_ccode_attribute(m).finish_name;
425 public static string get_ccode_finish_vfunc_name (Method m) {
426 assert (m.coroutine);
427 return get_ccode_attribute(m).finish_vfunc_name;
430 public static string get_ccode_finish_real_name (Method m) {
431 assert (m.coroutine);
432 return get_ccode_attribute(m).finish_real_name;
435 public static bool get_ccode_no_accessor_method (Property p) {
436 return p.get_attribute ("NoAccessorMethod") != null;
439 public static bool get_ccode_concrete_accessor (Property p) {
440 return p.get_attribute ("ConcreteAccessor") != null;
443 public static bool get_ccode_has_emitter (Signal sig) {
444 return sig.get_attribute ("HasEmitter") != null;
447 public static bool get_ccode_has_type_id (TypeSymbol sym) {
448 return sym.get_attribute_bool ("CCode", "has_type_id", true);
451 public static bool get_ccode_has_new_function (Method m) {
452 return m.get_attribute_bool ("CCode", "has_new_function", true);
455 public static bool get_ccode_has_generic_type_parameter (Method m) {
456 var a = m.get_attribute ("CCode");
457 return a != null && a.has_argument ("generic_type_pos");
460 public static double get_ccode_generic_type_pos (Method m) {
461 return m.get_attribute_double ("CCode", "generic_type_pos");
464 public static bool get_ccode_no_wrapper (Method m) {
465 return m.get_attribute ("NoWrapper") != null;
468 public static string get_ccode_sentinel (Method m) {
469 return get_ccode_attribute(m).sentinel;