Line data Source code
1 : /* valaccode.vala
2 : *
3 : * Copyright (C) 2017 Rico Tzschichholz
4 : *
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.
9 :
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.
14 :
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
18 : *
19 : * Author:
20 : * Rico Tzschichholz <ricotz@ubuntu.com>
21 : */
22 :
23 : namespace Vala {
24 : static int? ccode_attribute_cache_index = null;
25 :
26 1280429 : static unowned CCodeAttribute get_ccode_attribute (CodeNode node) {
27 1280429 : if (ccode_attribute_cache_index == null) {
28 1770 : ccode_attribute_cache_index = CodeNode.get_attribute_cache_index ();
29 :
30 : // make sure static collections are initialized
31 885 : CCodeBaseModule.init ();
32 : }
33 :
34 1280429 : unowned AttributeCache? attr = node.get_attribute_cache (ccode_attribute_cache_index);
35 1435833 : if (attr == null) {
36 155404 : var new_attr = new CCodeAttribute (node);
37 155404 : node.set_attribute_cache (ccode_attribute_cache_index, new_attr);
38 155404 : attr = new_attr;
39 : }
40 : return (CCodeAttribute) attr;
41 : }
42 :
43 583465 : public static string get_ccode_name (CodeNode node) {
44 583465 : return get_ccode_attribute(node).name;
45 : }
46 :
47 50513 : public static string get_ccode_const_name (CodeNode node) {
48 50513 : return get_ccode_attribute(node).const_name;
49 : }
50 :
51 17579 : public static string get_ccode_type_name (ObjectTypeSymbol sym) {
52 17579 : return get_ccode_attribute (sym).type_name;
53 : }
54 :
55 1765 : public static string get_ccode_type_cast_function (ObjectTypeSymbol sym) {
56 1765 : assert (!(sym is Class && ((Class) sym).is_compact));
57 1765 : return get_ccode_upper_case_name (sym);
58 : }
59 :
60 2809 : public static string get_ccode_type_get_function (ObjectTypeSymbol sym) {
61 2809 : var func_name = sym.get_attribute_string ("CCode", "type_get_function");
62 2809 : if (func_name != null) {
63 2809 : return func_name;
64 : }
65 2809 : if (sym is Class) {
66 2332 : assert (!((Class) sym).is_compact);
67 2332 : return "%s_GET_CLASS".printf (get_ccode_upper_case_name (sym));
68 477 : } else if (sym is Interface) {
69 477 : return "%s_GET_INTERFACE".printf (get_ccode_upper_case_name (sym));
70 : } else {
71 0 : Report.error (sym.source_reference, "`CCode.type_get_function' not supported");
72 0 : return "";
73 : }
74 : }
75 :
76 63 : public static string get_ccode_class_get_private_function (Class cl) {
77 63 : assert (!cl.is_compact);
78 63 : return "%s_GET_CLASS_PRIVATE".printf (get_ccode_upper_case_name (cl));
79 : }
80 :
81 1867 : public static string get_ccode_class_type_function (Class cl) {
82 1867 : assert (!cl.is_compact);
83 1867 : return "%s_CLASS".printf (get_ccode_upper_case_name (cl));
84 : }
85 :
86 51612 : public static string get_ccode_lower_case_name (CodeNode node, string? infix = null) {
87 51612 : unowned Symbol? sym = node as Symbol;
88 51440 : if (sym != null) {
89 51440 : if (infix == null) {
90 37878 : infix = "";
91 : }
92 51440 : if (sym is Delegate) {
93 2 : return "%s%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), infix, Symbol.camel_case_to_lower_case (sym.name));
94 51438 : } else if (sym is Signal) {
95 615 : return get_ccode_attribute (sym).name.replace ("-", "_");
96 50823 : } else if (sym is ErrorCode) {
97 7 : return get_ccode_name (sym).ascii_down ();
98 : } else {
99 50816 : return "%s%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), infix, get_ccode_lower_case_suffix (sym));
100 : }
101 172 : } else if (node is ErrorType) {
102 138 : unowned ErrorType type = (ErrorType) node;
103 138 : if (type.error_domain == null) {
104 80 : if (infix == null) {
105 80 : return "g_error";
106 : } else {
107 0 : return "g_%s_error".printf (infix);
108 : }
109 58 : } else if (type.error_code == null) {
110 51 : return get_ccode_lower_case_name (type.error_domain, infix);
111 : } else {
112 7 : return get_ccode_lower_case_name (type.error_code, infix);
113 : }
114 34 : } else if (node is DelegateType) {
115 2 : unowned DelegateType type = (DelegateType) node;
116 2 : return get_ccode_lower_case_name (type.delegate_symbol, infix);
117 32 : } else if (node is PointerType) {
118 2 : unowned PointerType type = (PointerType) node;
119 2 : return get_ccode_lower_case_name (type.base_type, infix);
120 30 : } else if (node is GenericType) {
121 1 : return "valageneric";
122 29 : } else if (node is VoidType) {
123 2 : return "valavoid";
124 : } else {
125 27 : unowned DataType type = (DataType) node;
126 27 : return get_ccode_lower_case_name (type.type_symbol, infix);
127 : }
128 : }
129 :
130 17496 : public static string get_ccode_upper_case_name (Symbol sym, string? infix = null) {
131 17496 : if (sym is Property) {
132 1971 : return "%s_%s".printf (get_ccode_lower_case_name (sym.parent_symbol), Symbol.camel_case_to_lower_case (sym.name)).ascii_up ();
133 : } else {
134 15525 : return get_ccode_lower_case_name (sym, infix).ascii_up ();
135 : }
136 : }
137 :
138 22971 : public static string get_ccode_header_filenames (Symbol sym) {
139 22971 : return get_ccode_attribute(sym).header_filenames;
140 : }
141 :
142 16838 : public static string get_ccode_feature_test_macros (Symbol sym) {
143 16838 : return get_ccode_attribute(sym).feature_test_macros;
144 : }
145 :
146 8341 : public static string get_ccode_prefix (Symbol sym) {
147 8341 : return get_ccode_attribute(sym).prefix;
148 : }
149 :
150 66515 : public static string get_ccode_lower_case_prefix (Symbol sym) {
151 66515 : return get_ccode_attribute(sym).lower_case_prefix;
152 : }
153 :
154 50840 : public static string get_ccode_lower_case_suffix (Symbol sym) {
155 50840 : return get_ccode_attribute(sym).lower_case_suffix;
156 : }
157 :
158 36861 : public static string get_ccode_ref_function (TypeSymbol sym) {
159 36861 : return get_ccode_attribute(sym).ref_function;
160 : }
161 :
162 44 : public static string get_ccode_quark_name (ErrorDomain edomain) {
163 44 : return "%s-quark".printf (get_ccode_lower_case_name (edomain).replace ("_", "-"));
164 : }
165 :
166 32768 : public static bool is_reference_counting (TypeSymbol sym) {
167 32768 : if (sym is Class) {
168 31799 : return get_ccode_ref_function (sym) != null;
169 969 : } else if (sym is Interface) {
170 32768 : return true;
171 : } else {
172 519 : return false;
173 : }
174 : }
175 :
176 4074 : public static bool is_ref_function_void (DataType type) {
177 4074 : unowned Class? cl = type.type_symbol as Class;
178 3606 : if (cl != null) {
179 3606 : return get_ccode_ref_function_void (cl);
180 : } else {
181 468 : return false;
182 : }
183 : }
184 :
185 5077 : public static bool is_free_function_address_of (DataType type) {
186 5077 : unowned Class? cl = type.type_symbol as Class;
187 5077 : if (cl != null) {
188 5077 : return get_ccode_free_function_address_of (cl);
189 : } else {
190 0 : return false;
191 : }
192 : }
193 :
194 3850 : public static bool get_ccode_ref_function_void (Class cl) {
195 3850 : return get_ccode_attribute(cl).ref_function_void;
196 : }
197 :
198 5088 : public static bool get_ccode_free_function_address_of (Class cl) {
199 5088 : return get_ccode_attribute(cl).free_function_address_of;
200 : }
201 :
202 16088 : public static string get_ccode_unref_function (ObjectTypeSymbol sym) {
203 16088 : return get_ccode_attribute(sym).unref_function;
204 : }
205 :
206 44 : public static string get_ccode_ref_sink_function (ObjectTypeSymbol sym) {
207 44 : return get_ccode_attribute(sym).ref_sink_function;
208 : }
209 :
210 2875 : public static string get_ccode_copy_function (TypeSymbol sym) {
211 2875 : return get_ccode_attribute(sym).copy_function;
212 : }
213 :
214 1527 : public static string get_ccode_destroy_function (TypeSymbol sym) {
215 1527 : return get_ccode_attribute(sym).destroy_function;
216 : }
217 :
218 2901 : public static string? get_ccode_dup_function (TypeSymbol sym) {
219 2901 : if (sym is Struct) {
220 2290 : return get_ccode_attribute (sym).dup_function;
221 : }
222 1756 : return get_ccode_copy_function (sym);
223 : }
224 :
225 12903 : public static string get_ccode_free_function (TypeSymbol sym) {
226 12903 : return get_ccode_attribute(sym).free_function;
227 : }
228 :
229 5697 : public static bool get_ccode_is_gboxed (TypeSymbol sym) {
230 5697 : return get_ccode_free_function (sym) == "g_boxed_free";
231 : }
232 :
233 418 : public static bool get_ccode_finish_instance (Method m) {
234 418 : assert (m.coroutine);
235 418 : return get_ccode_attribute (m).finish_instance;
236 : }
237 :
238 24938 : public static string get_ccode_type_id (CodeNode node) {
239 24938 : return get_ccode_attribute(node).type_id;
240 : }
241 :
242 3396 : public static string get_ccode_type_function (TypeSymbol sym) {
243 3396 : assert (!((sym is Class && ((Class) sym).is_compact) || sym is ErrorCode || sym is Delegate));
244 3396 : return "%s_get_type".printf (get_ccode_lower_case_name (sym));
245 : }
246 :
247 1248 : public static string get_ccode_marshaller_type_name (CodeNode node) {
248 1248 : return get_ccode_attribute(node).marshaller_type_name;
249 : }
250 :
251 1217 : public static string get_ccode_get_value_function (CodeNode sym) {
252 1217 : return get_ccode_attribute(sym).get_value_function;
253 : }
254 :
255 1290 : public static string get_ccode_set_value_function (CodeNode sym) {
256 1290 : return get_ccode_attribute(sym).set_value_function;
257 : }
258 :
259 848 : public static string get_ccode_take_value_function (CodeNode sym) {
260 848 : return get_ccode_attribute(sym).take_value_function;
261 : }
262 :
263 1012 : public static string get_ccode_param_spec_function (CodeNode sym) {
264 1012 : return get_ccode_attribute(sym).param_spec_function;
265 : }
266 :
267 4490 : public static string get_ccode_type_check_function (TypeSymbol sym) {
268 4490 : unowned Class? cl = sym as Class;
269 4490 : var a = sym.get_attribute_string ("CCode", "type_check_function");
270 4490 : if (cl != null && a != null) {
271 4490 : return a;
272 4490 : } else if ((cl != null && cl.is_compact) || sym is Struct || sym is Enum || sym is Delegate) {
273 0 : return "";
274 : } else {
275 4490 : return get_ccode_upper_case_name (sym, "IS_");
276 : }
277 : }
278 :
279 1523 : public static string get_ccode_class_type_check_function (Class cl) {
280 1523 : assert (!cl.is_compact);
281 1523 : return "%s_CLASS".printf (get_ccode_type_check_function (cl));
282 : }
283 :
284 11125 : public static string get_ccode_default_value (TypeSymbol sym) {
285 11125 : return get_ccode_attribute(sym).default_value;
286 : }
287 :
288 474 : public static string get_ccode_default_value_on_error (TypeSymbol sym) {
289 474 : return get_ccode_attribute (sym).default_value_on_error;
290 : }
291 :
292 44 : public static bool get_ccode_has_copy_function (Struct st) {
293 44 : return st.get_attribute_bool ("CCode", "has_copy_function", true);
294 : }
295 :
296 287 : public static bool get_ccode_has_destroy_function (Struct st) {
297 287 : return st.get_attribute_bool ("CCode", "has_destroy_function", true);
298 : }
299 :
300 21445 : public static double get_ccode_instance_pos (CodeNode node) {
301 21445 : if (node is Delegate) {
302 895 : return node.get_attribute_double ("CCode", "instance_pos", -2);
303 : } else {
304 20550 : return node.get_attribute_double ("CCode", "instance_pos", 0);
305 : }
306 : }
307 :
308 2491 : public static double get_ccode_error_pos (Callable c) {
309 2491 : return c.get_attribute_double ("CCode", "error_pos", -1);
310 : }
311 :
312 49880 : public static bool get_ccode_array_length (CodeNode node) {
313 49880 : return get_ccode_attribute(node).array_length;
314 : }
315 :
316 6609 : public static string get_ccode_array_length_type (CodeNode node) {
317 6609 : if (node is ArrayType) {
318 4453 : return get_ccode_name (((ArrayType) node).length_type);
319 2156 : } else if (node is DataType) {
320 0 : Report.error (node.source_reference, "`CCode.array_length_type' not supported");
321 0 : return "";
322 : } else {
323 2156 : assert (node is Method || node is Parameter || node is Delegate || node is Property || node is Field);
324 4312 : return get_ccode_attribute(node).array_length_type;
325 : }
326 : }
327 :
328 33227 : public static bool get_ccode_array_null_terminated (CodeNode node) {
329 33227 : return get_ccode_attribute(node).array_null_terminated;
330 : }
331 :
332 2058 : public static string? get_ccode_array_length_name (CodeNode node) {
333 2058 : return get_ccode_attribute(node).array_length_name;
334 : }
335 :
336 31311 : public static string? get_ccode_array_length_expr (CodeNode node) {
337 31311 : return get_ccode_attribute(node).array_length_expr;
338 : }
339 :
340 2570 : public static double get_ccode_array_length_pos (CodeNode node) {
341 21897 : var a = node.get_attribute ("CCode");
342 131 : if (a != null && a.has_argument ("array_length_pos")) {
343 16 : return a.get_double ("array_length_pos");
344 : }
345 2554 : if (node is Parameter) {
346 1949 : unowned Parameter param = (Parameter) node;
347 1949 : return get_ccode_pos (param) + 0.1;
348 : } else {
349 605 : return -3;
350 : }
351 : }
352 :
353 1595 : public static double get_ccode_delegate_target_pos (CodeNode node) {
354 1595 : var a = node.get_attribute ("CCode");
355 180 : if (a != null && a.has_argument ("delegate_target_pos")) {
356 180 : return a.get_double ("delegate_target_pos");
357 : }
358 1415 : if (node is Parameter) {
359 1283 : unowned Parameter param = (Parameter) node;
360 1283 : return get_ccode_pos (param) + 0.1;
361 : } else {
362 132 : return -3;
363 : }
364 : }
365 :
366 310 : public static double get_ccode_destroy_notify_pos (CodeNode node) {
367 310 : var a = node.get_attribute ("CCode");
368 20 : if (a != null && a.has_argument ("destroy_notify_pos")) {
369 0 : return a.get_double ("destroy_notify_pos");
370 : }
371 310 : return get_ccode_delegate_target_pos (node) + 0.01;
372 : }
373 :
374 65759 : public static bool get_ccode_delegate_target (CodeNode node) {
375 65759 : return get_ccode_attribute(node).delegate_target;
376 : }
377 :
378 539 : public static string get_ccode_delegate_target_name (Variable variable) {
379 539 : return get_ccode_attribute(variable).delegate_target_name;
380 : }
381 :
382 371 : public static string get_ccode_delegate_target_destroy_notify_name (Variable variable) {
383 371 : return get_ccode_attribute(variable).delegate_target_destroy_notify_name;
384 : }
385 :
386 39724 : public static double get_ccode_pos (Parameter param) {
387 39724 : return get_ccode_attribute(param).pos;
388 : }
389 :
390 98690 : public static string? get_ccode_type (CodeNode node) {
391 98690 : return get_ccode_attribute(node).ctype;
392 : }
393 :
394 35907 : public static bool get_ccode_simple_generics (Method m) {
395 35907 : return m.get_attribute_bool ("CCode", "simple_generics");
396 : }
397 :
398 11236 : public static string get_ccode_real_name (Symbol sym) {
399 11236 : return get_ccode_attribute(sym).real_name;
400 : }
401 :
402 77 : public static string get_ccode_constructv_name (CreationMethod m) {
403 77 : const string infix = "constructv";
404 :
405 77 : unowned Class parent = (Class) m.parent_symbol;
406 :
407 77 : if (m.name == ".new") {
408 28 : return "%s%s".printf (get_ccode_lower_case_prefix (parent), infix);
409 : } else {
410 49 : return "%s%s_%s".printf (get_ccode_lower_case_prefix (parent), infix, m.name);
411 : }
412 : }
413 :
414 2860 : public static string get_ccode_vfunc_name (Method m) {
415 2860 : return get_ccode_attribute(m).vfunc_name;
416 : }
417 :
418 1126 : public static double get_ccode_async_result_pos (Method m) {
419 1126 : assert (m.coroutine);
420 1126 : return m.get_attribute_double ("CCode", "async_result_pos", 0.1);
421 : }
422 :
423 499 : public static string get_ccode_finish_name (Method m) {
424 499 : assert (m.coroutine);
425 499 : return get_ccode_attribute(m).finish_name;
426 : }
427 :
428 185 : public static string get_ccode_finish_vfunc_name (Method m) {
429 185 : assert (m.coroutine);
430 185 : return get_ccode_attribute(m).finish_vfunc_name;
431 : }
432 :
433 190 : public static string get_ccode_finish_real_name (Method m) {
434 190 : assert (m.coroutine);
435 190 : return get_ccode_attribute(m).finish_real_name;
436 : }
437 :
438 7561 : public static bool get_ccode_no_accessor_method (Property p) {
439 7561 : return p.has_attribute ("NoAccessorMethod");
440 : }
441 :
442 703 : public static bool get_ccode_concrete_accessor (Property p) {
443 703 : return p.has_attribute ("ConcreteAccessor");
444 : }
445 :
446 58 : public static bool get_ccode_has_emitter (Signal sig) {
447 58 : return sig.has_attribute ("HasEmitter");
448 : }
449 :
450 2307 : public static bool get_ccode_has_type_id (TypeSymbol sym) {
451 2307 : if (sym is ErrorDomain && sym.external_package) {
452 0 : return sym.get_attribute_bool ("CCode", "has_type_id", false);
453 : } else {
454 2307 : return sym.get_attribute_bool ("CCode", "has_type_id", true);
455 : }
456 : }
457 :
458 1610 : public static bool get_ccode_has_new_function (Method m) {
459 1610 : return m.get_attribute_bool ("CCode", "has_new_function", true);
460 : }
461 :
462 17422 : public static bool get_ccode_has_generic_type_parameter (Method m) {
463 17422 : var a = m.get_attribute ("CCode");
464 2094 : return a != null && a.has_argument ("generic_type_pos");
465 : }
466 :
467 50 : public static double get_ccode_generic_type_pos (Method m) {
468 50 : return m.get_attribute_double ("CCode", "generic_type_pos");
469 : }
470 :
471 5821 : public static bool get_ccode_no_wrapper (Method m) {
472 5821 : return m.has_attribute ("NoWrapper");
473 : }
474 :
475 1116 : public static string get_ccode_sentinel (Method m) {
476 1116 : return get_ccode_attribute(m).sentinel;
477 : }
478 : }
|