Line data Source code
1 : /* valaccodeattribute.vala
2 : *
3 : * Copyright (C) 2011 Luca Bruno
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 : * Luca Bruno <lucabru@src.gnome.org>
21 : */
22 :
23 :
24 : /**
25 : * Cache for the CCode attribute
26 : */
27 885 : public class Vala.CCodeAttribute : AttributeCache {
28 : private static int next_lambda_id = 0;
29 :
30 : private weak CodeNode node;
31 : private weak Symbol? sym;
32 155404 : private Attribute ccode;
33 :
34 : public string name {
35 590141 : get {
36 590141 : if (_name == null) {
37 144061 : if (ccode != null) {
38 8804 : _name = ccode.get_string ("cname");
39 : }
40 144061 : if (_name == null) {
41 141377 : _name = get_default_name ();
42 : }
43 : }
44 590141 : return _name;
45 : }
46 : }
47 :
48 : public string const_name {
49 50513 : get {
50 50513 : if (_const_name == null) {
51 2098 : if (ccode != null) {
52 1054 : _const_name = ccode.get_string ("const_cname");
53 : }
54 2098 : if (_const_name == null) {
55 1844 : _const_name = get_default_const_name ();
56 : }
57 : }
58 50513 : return _const_name;
59 : }
60 : }
61 :
62 : public string type_name {
63 17579 : get {
64 17579 : if (_type_name == null) {
65 1122 : if (ccode != null) {
66 231 : _type_name = ccode.get_string ("type_cname");
67 : }
68 1122 : if (_type_name == null) {
69 1122 : if (sym is Class) {
70 1004 : _type_name = "%sClass".printf (get_ccode_name (sym));
71 118 : } else if (sym is Interface) {
72 118 : _type_name = "%sIface".printf (get_ccode_name (sym));
73 : } else {
74 0 : Report.error (sym.source_reference, "`CCode.type_cname' not supported");
75 0 : _type_name = "";
76 : }
77 : }
78 : }
79 17579 : return _type_name;
80 : }
81 : }
82 :
83 : public string feature_test_macros {
84 16838 : get {
85 16838 : if (_feature_test_macros == null) {
86 8256 : if (ccode != null) {
87 4401 : _feature_test_macros = ccode.get_string ("feature_test_macro");
88 : }
89 8256 : if (_feature_test_macros == null) {
90 8255 : _feature_test_macros = "";
91 : }
92 : }
93 16838 : return _feature_test_macros;
94 : }
95 : }
96 :
97 : public string header_filenames {
98 22971 : get {
99 22971 : if (_header_filenames == null) {
100 9860 : if (ccode != null) {
101 5197 : _header_filenames = ccode.get_string ("cheader_filename");
102 : }
103 9860 : if (_header_filenames == null) {
104 6058 : _header_filenames = get_default_header_filenames ();
105 : }
106 : }
107 22971 : return _header_filenames;
108 : }
109 : }
110 :
111 : public string prefix {
112 8341 : get {
113 8341 : if (_prefix == null) {
114 1564 : if (ccode != null) {
115 693 : _prefix = ccode.get_string ("cprefix");
116 : }
117 1564 : if (_prefix == null) {
118 931 : _prefix = get_default_prefix ();
119 : }
120 : }
121 8341 : return _prefix;
122 : }
123 : }
124 :
125 : public string lower_case_prefix {
126 67590 : get {
127 67590 : if (_lower_case_prefix == null) {
128 3802 : if (ccode != null) {
129 1739 : _lower_case_prefix = ccode.get_string ("lower_case_cprefix");
130 1739 : if (_lower_case_prefix == null && (sym is ObjectTypeSymbol || sym is Struct)) {
131 971 : _lower_case_prefix = ccode.get_string ("cprefix");
132 : }
133 : }
134 3802 : if (_lower_case_prefix == null) {
135 3023 : _lower_case_prefix = get_default_lower_case_prefix ();
136 : }
137 : }
138 67590 : return _lower_case_prefix;
139 : }
140 : }
141 :
142 : public string lower_case_suffix {
143 50840 : get {
144 50840 : if (_lower_case_suffix == null) {
145 2293 : if (ccode != null) {
146 1128 : _lower_case_suffix = ccode.get_string ("lower_case_csuffix");
147 : }
148 2293 : if (_lower_case_suffix == null) {
149 2289 : _lower_case_suffix = get_default_lower_case_suffix ();
150 : }
151 : }
152 50840 : return _lower_case_suffix;
153 : }
154 : }
155 :
156 : public string ref_function {
157 36861 : get {
158 36861 : if (!ref_function_set) {
159 1858 : if (ccode != null) {
160 1129 : _ref_function = ccode.get_string ("ref_function");
161 : }
162 1858 : if (_ref_function == null) {
163 1456 : _ref_function = get_default_ref_function ();
164 : }
165 1858 : ref_function_set = true;
166 : }
167 36861 : return _ref_function;
168 : }
169 : }
170 :
171 : public bool ref_function_void {
172 3850 : get {
173 3850 : if (_ref_function_void == null) {
174 1301 : if (ccode != null && ccode.has_argument ("ref_function_void")) {
175 75880 : _ref_function_void = ccode.get_bool ("ref_function_void");
176 : } else {
177 266669 : var cl = (Class) sym;
178 650 : if (cl.base_class != null) {
179 244 : _ref_function_void = get_ccode_ref_function_void (cl.base_class);
180 : } else {
181 406 : _ref_function_void = false;
182 : }
183 : }
184 : }
185 3850 : return _ref_function_void;
186 : }
187 : }
188 :
189 : public string unref_function {
190 16088 : get {
191 16088 : if (!unref_function_set) {
192 1503 : if (ccode != null) {
193 769 : _unref_function = ccode.get_string ("unref_function");
194 : }
195 1503 : if (_unref_function == null) {
196 1104 : _unref_function = get_default_unref_function ();
197 : }
198 1503 : unref_function_set = true;
199 : }
200 16088 : return _unref_function;
201 : }
202 : }
203 :
204 : public string ref_sink_function {
205 44 : get {
206 44 : if (_ref_sink_function == null) {
207 29 : if (ccode != null) {
208 29 : _ref_sink_function = ccode.get_string ("ref_sink_function");
209 : }
210 29 : if (_ref_sink_function == null) {
211 0 : _ref_sink_function = get_default_ref_sink_function ();
212 : }
213 : }
214 44 : return _ref_sink_function;
215 : }
216 : }
217 :
218 : public string copy_function {
219 2875 : get {
220 2875 : if (!copy_function_set) {
221 443 : if (ccode != null) {
222 264 : _copy_function = ccode.get_string ("copy_function");
223 : }
224 443 : if (_copy_function == null && sym is Struct) {
225 49 : _copy_function = "%scopy".printf (lower_case_prefix);
226 : }
227 443 : if (_copy_function == null && sym is TypeParameter) {
228 124 : _copy_function = "%s_dup_func".printf (sym.name.ascii_down ());
229 : }
230 443 : copy_function_set = true;
231 : }
232 2875 : return _copy_function;
233 : }
234 : }
235 :
236 : public string destroy_function {
237 1527 : get {
238 1527 : if (!destroy_function_set) {
239 213 : if (ccode != null) {
240 45 : _destroy_function = ccode.get_string ("destroy_function");
241 : }
242 213 : if (_destroy_function == null && sym is Struct) {
243 49 : _destroy_function = "%sdestroy".printf (lower_case_prefix);
244 : }
245 213 : if (_destroy_function == null && sym is TypeParameter) {
246 123 : _destroy_function = "%s_destroy_func".printf (sym.name.ascii_down ());
247 : }
248 213 : destroy_function_set = true;
249 : }
250 1527 : return _destroy_function;
251 : }
252 : }
253 :
254 : public string dup_function {
255 1145 : get {
256 1145 : if (!dup_function_set) {
257 199 : if (ccode != null) {
258 55 : _dup_function = ccode.get_string ("dup_function");
259 : }
260 199 : if (_dup_function == null && !sym.external_package
261 158 : && sym is Struct && !((Struct) sym).is_simple_type ()) {
262 157 : _dup_function = "%sdup".printf (lower_case_prefix);
263 : }
264 199 : dup_function_set = true;
265 : }
266 1145 : return _dup_function;
267 : }
268 : }
269 :
270 : public string free_function {
271 12903 : get {
272 12903 : if (!free_function_set) {
273 659 : if (ccode != null) {
274 429 : _free_function = ccode.get_string ("free_function");
275 : }
276 659 : if (_free_function == null) {
277 306 : _free_function = get_default_free_function ();
278 : }
279 659 : free_function_set = true;
280 : }
281 12903 : return _free_function;
282 : }
283 : }
284 :
285 : public bool free_function_address_of {
286 5088 : get {
287 5088 : if (_free_function_address_of == null) {
288 360 : if (ccode != null && ccode.has_argument ("free_function_address_of")) {
289 0 : _free_function_address_of = ccode.get_bool ("free_function_address_of");
290 : } else {
291 360 : unowned Class cl = (Class) sym;
292 360 : if (cl.base_class != null) {
293 11 : _free_function_address_of = get_ccode_free_function_address_of (cl.base_class);
294 : } else {
295 349 : _free_function_address_of = false;
296 : }
297 : }
298 : }
299 5088 : return _free_function_address_of;
300 : }
301 : }
302 :
303 : public string ctype {
304 98690 : get {
305 98690 : if (!ctype_set) {
306 20194 : if (ccode != null) {
307 1194 : _ctype = ccode.get_string ("type");
308 1194 : if (_ctype == null) {
309 1157 : _ctype = ccode.get_string ("ctype");
310 1157 : if (_ctype != null) {
311 0 : Report.deprecated (node.source_reference, "[CCode (ctype = \"...\")] is deprecated, use [CCode (type = \"...\")] instead.");
312 : }
313 : }
314 : }
315 20194 : ctype_set = true;
316 : }
317 98690 : return _ctype;
318 : }
319 : }
320 :
321 : public string type_id {
322 24944 : get {
323 24944 : if (_type_id == null) {
324 6717 : if (ccode != null) {
325 4310 : _type_id = ccode.get_string ("type_id");
326 : }
327 6717 : if (_type_id == null && sym is TypeParameter) {
328 123 : _type_id = "%s_type".printf (sym.name.ascii_down ());
329 : }
330 6717 : if (_type_id == null) {
331 2719 : _type_id = get_default_type_id ();
332 : }
333 : }
334 24944 : return _type_id;
335 : }
336 : }
337 :
338 : public string marshaller_type_name {
339 1248 : get {
340 1248 : if (_marshaller_type_name == null) {
341 285 : if (ccode != null) {
342 35 : _marshaller_type_name = ccode.get_string ("marshaller_type_name");
343 : }
344 285 : if (_marshaller_type_name == null) {
345 251 : _marshaller_type_name = get_default_marshaller_type_name ();
346 : }
347 : }
348 1248 : return _marshaller_type_name;
349 : }
350 : }
351 :
352 : public string get_value_function {
353 1217 : get {
354 1217 : if (_get_value_function == null) {
355 446 : if (ccode != null) {
356 126 : _get_value_function = ccode.get_string ("get_value_function");
357 : }
358 446 : if (_get_value_function == null) {
359 332 : _get_value_function = get_default_get_value_function ();
360 : }
361 : }
362 1217 : return _get_value_function;
363 : }
364 : }
365 :
366 : public string set_value_function {
367 1290 : get {
368 1290 : if (_set_value_function == null) {
369 454 : if (ccode != null) {
370 136 : _set_value_function = ccode.get_string ("set_value_function");
371 : }
372 454 : if (_set_value_function == null) {
373 346 : _set_value_function = get_default_set_value_function ();
374 : }
375 : }
376 1290 : return _set_value_function;
377 : }
378 : }
379 :
380 : public string take_value_function {
381 848 : get {
382 848 : if (_take_value_function == null) {
383 279 : if (ccode != null) {
384 17 : _take_value_function = ccode.get_string ("take_value_function");
385 : }
386 279 : if (_take_value_function == null) {
387 263 : _take_value_function = get_default_take_value_function ();
388 : }
389 : }
390 848 : return _take_value_function;
391 : }
392 : }
393 :
394 : public string param_spec_function {
395 1012 : get {
396 1012 : if (_param_spec_function == null) {
397 341 : if (ccode != null) {
398 61 : _param_spec_function = ccode.get_string ("param_spec_function");
399 : }
400 341 : if (_param_spec_function == null) {
401 303 : _param_spec_function = get_default_param_spec_function ();
402 : }
403 : }
404 1012 : return _param_spec_function;
405 : }
406 : }
407 :
408 : public string default_value {
409 11191 : get {
410 11191 : if (_default_value == null) {
411 1717 : if (ccode != null) {
412 1051 : _default_value = ccode.get_string ("default_value");
413 : }
414 1717 : if (_default_value == null) {
415 1209 : _default_value = get_default_default_value ();
416 : }
417 : }
418 11191 : return _default_value;
419 : }
420 : }
421 :
422 : public string default_value_on_error {
423 474 : get {
424 474 : if (_default_value_on_error == null) {
425 104 : if (ccode != null) {
426 82 : _default_value_on_error = ccode.get_string ("default_value_on_error");
427 : }
428 104 : if (_default_value_on_error == null) {
429 132 : _default_value_on_error = default_value;
430 : }
431 : }
432 474 : return _default_value_on_error;
433 : }
434 : }
435 :
436 : public double pos {
437 39724 : get {
438 39724 : if (_pos == null) {
439 7131 : if (ccode != null && ccode.has_argument ("pos")) {
440 14262 : _pos = ccode.get_double ("pos");
441 : } else {
442 7021 : unowned Parameter param = (Parameter) node;
443 7021 : unowned Callable? callable = param.parent_symbol as Callable;
444 7021 : unowned Method? method = param.parent_symbol as Method;
445 7021 : if (method != null && method.coroutine) {
446 77 : int index = method.get_async_begin_parameters ().index_of (param);
447 77 : if (index < 0) {
448 15 : index = method.get_async_end_parameters ().index_of (param);
449 : }
450 15 : if (index < 0) {
451 0 : Report.error (param.source_reference, "internal: Parameter `%s' not found in `%s'", param.name, method.get_full_name ());
452 : }
453 77 : _pos = index + 1.0;
454 6944 : } else if (callable != null) {
455 6864 : _pos = callable.get_parameters ().index_of (param) + 1.0;
456 : } else {
457 80 : _pos = 0.0;
458 : }
459 : }
460 : }
461 39724 : return _pos;
462 : }
463 : }
464 :
465 : public string real_name {
466 11260 : get {
467 11260 : if (_real_name == null) {
468 6094 : if (ccode != null && sym is CreationMethod) {
469 222 : _real_name = ccode.get_string ("construct_function");
470 : }
471 6094 : if (_real_name == null) {
472 5877 : _real_name = get_default_real_name ();
473 : }
474 : }
475 11260 : return _real_name;
476 : }
477 : }
478 :
479 : public string vfunc_name {
480 2900 : get {
481 2900 : if (_vfunc_name == null) {
482 638 : if (ccode != null) {
483 24 : _vfunc_name = ccode.get_string ("vfunc_name");
484 : }
485 638 : if (_vfunc_name == null) {
486 636 : unowned Method? m = node as Method;
487 636 : if (m != null && m.signal_reference != null) {
488 10 : _vfunc_name = get_ccode_lower_case_name (m.signal_reference);
489 : } else {
490 1252 : _vfunc_name = sym.name;
491 : }
492 : }
493 : }
494 2900 : return _vfunc_name;
495 : }
496 : }
497 :
498 : public string finish_name {
499 602 : get {
500 602 : if (_finish_name == null) {
501 156 : if (ccode != null) {
502 13 : _finish_name = ccode.get_string ("finish_name");
503 13 : if (_finish_name == null) {
504 8 : _finish_name = ccode.get_string ("finish_function");
505 8 : if (_finish_name != null) {
506 0 : Report.deprecated (node.source_reference, "[CCode (finish_function = \"...\")] is deprecated, use [CCode (finish_name = \"...\")] instead.");
507 : }
508 : }
509 : }
510 156 : if (_finish_name == null) {
511 151 : _finish_name = get_finish_name_for_basename (name);
512 : }
513 : }
514 602 : return _finish_name;
515 : }
516 : }
517 :
518 : public string finish_vfunc_name {
519 185 : get {
520 185 : if (_finish_vfunc_name == null) {
521 41 : if (ccode != null) {
522 2 : _finish_vfunc_name = ccode.get_string ("finish_vfunc_name");
523 : }
524 41 : if (_finish_vfunc_name == null) {
525 40 : _finish_vfunc_name = get_finish_name_for_basename (vfunc_name);
526 : }
527 : }
528 185 : return _finish_vfunc_name;
529 : }
530 : }
531 :
532 : public string finish_real_name {
533 190 : get {
534 190 : if (_finish_real_name == null) {
535 127 : unowned Method? m = node as Method;
536 127 : if (m != null && !(m is CreationMethod) && !(m.is_abstract || m.is_virtual)) {
537 206 : _finish_real_name = finish_name;
538 : } else {
539 24 : _finish_real_name = get_finish_name_for_basename (real_name);
540 : }
541 : }
542 190 : return _finish_real_name;
543 : }
544 : }
545 :
546 : public bool finish_instance {
547 418 : get {
548 418 : if (_finish_instance == null) {
549 94 : unowned Method? m = node as Method;
550 94 : bool is_creation_method = m is CreationMethod;
551 94 : if (ccode == null || m == null || m.is_abstract || m.is_virtual) {
552 88 : _finish_instance = !is_creation_method;
553 : } else {
554 6 : _finish_instance = ccode.get_bool ("finish_instance", !is_creation_method);
555 : }
556 : }
557 418 : return _finish_instance;
558 : }
559 : }
560 :
561 : public bool delegate_target {
562 65759 : get {
563 65759 : if (_delegate_target == null) {
564 15141 : if (ccode != null) {
565 523 : _delegate_target = ccode.get_bool ("delegate_target", get_default_delegate_target ());
566 : } else {
567 14618 : _delegate_target = get_default_delegate_target ();
568 : }
569 : }
570 65759 : return _delegate_target;
571 : }
572 : }
573 :
574 : public string delegate_target_name {
575 645 : get {
576 645 : if (_delegate_target_name == null) {
577 120 : if (ccode != null) {
578 8 : _delegate_target_name = ccode.get_string ("delegate_target_cname");
579 : }
580 120 : if (_delegate_target_name == null) {
581 112 : _delegate_target_name = "%s_target".printf (name);
582 : }
583 : }
584 645 : return _delegate_target_name;
585 : }
586 : }
587 :
588 : public string delegate_target_destroy_notify_name {
589 371 : get {
590 371 : if (_delegate_target_destroy_notify_name == null) {
591 106 : if (ccode != null) {
592 8 : _delegate_target_destroy_notify_name = ccode.get_string ("destroy_notify_cname");
593 : }
594 106 : if (_delegate_target_destroy_notify_name == null) {
595 106 : _delegate_target_destroy_notify_name = "%s_destroy_notify".printf (delegate_target_name);
596 : }
597 : }
598 371 : return _delegate_target_destroy_notify_name;
599 : }
600 : }
601 :
602 : public bool array_length {
603 49880 : get {
604 49880 : if (_array_length == null) {
605 12776 : if (node.has_attribute ("NoArrayLength")) {
606 0 : Report.deprecated (node.source_reference, "[NoArrayLength] is deprecated, use [CCode (array_length = false)] instead.");
607 0 : _array_length = false;
608 12776 : } else if (ccode != null && ccode.has_argument ("array_length")) {
609 172 : _array_length = ccode.get_bool ("array_length");
610 : } else {
611 12604 : _array_length = get_default_array_length ();
612 : }
613 : }
614 49880 : return _array_length;
615 : }
616 : }
617 :
618 : public bool array_null_terminated {
619 33227 : get {
620 33227 : if (_array_null_terminated == null) {
621 : // If arrays claim to have an array-length and also are null-terminated then rely on the given length
622 8918 : if (ccode != null && ccode.has_argument ("array_length") && ccode.get_bool ("array_length")) {
623 1 : _array_null_terminated = false;
624 8917 : } else if (ccode != null && ccode.has_argument ("array_null_terminated")) {
625 81 : _array_null_terminated = ccode.get_bool ("array_null_terminated");
626 : } else {
627 8836 : _array_null_terminated = get_default_array_null_terminated ();
628 : }
629 : }
630 33227 : return _array_null_terminated;
631 : }
632 : }
633 :
634 : public string array_length_type {
635 2156 : get {
636 2156 : if (_array_length_type == null) {
637 442 : if (ccode != null && ccode.has_argument ("array_length_type")) {
638 34 : _array_length_type = ccode.get_string ("array_length_type");
639 : } else {
640 408 : _array_length_type = get_default_array_length_type ();
641 : }
642 : }
643 2156 : return _array_length_type;
644 : }
645 : }
646 :
647 : public string sentinel {
648 1116 : get {
649 1116 : if (_sentinel == null) {
650 325 : if (ccode != null) {
651 243 : _sentinel = ccode.get_string ("sentinel", "NULL");
652 : } else {
653 82 : _sentinel = "NULL";
654 : }
655 : }
656 1116 : return _sentinel;
657 : }
658 : }
659 :
660 177454 : public string? array_length_name { get; private set; }
661 206707 : public string? array_length_expr { get; private set; }
662 :
663 155404 : private string _name;
664 155404 : private string _const_name;
665 155404 : private string _type_name;
666 155404 : private string _feature_test_macros;
667 155404 : private string _header_filenames;
668 155404 : private string _prefix;
669 155404 : private string _lower_case_prefix;
670 155404 : private string _lower_case_suffix;
671 155404 : private string? _ref_function;
672 : private bool ref_function_set;
673 155404 : private bool? _ref_function_void;
674 155404 : private string? _unref_function;
675 : private bool unref_function_set;
676 155404 : private string _ref_sink_function;
677 155404 : private string? _copy_function;
678 : private bool copy_function_set;
679 155404 : private string? _destroy_function;
680 : private bool destroy_function_set;
681 155404 : private string? _dup_function;
682 : private bool dup_function_set;
683 155404 : private string? _free_function;
684 : private bool free_function_set;
685 155404 : private bool? _free_function_address_of;
686 155404 : private string _type_id;
687 155404 : private string _marshaller_type_name;
688 155404 : private string _get_value_function;
689 155404 : private string _set_value_function;
690 155404 : private string _take_value_function;
691 155404 : private string _param_spec_function;
692 155404 : private string _default_value;
693 155404 : private string _default_value_on_error;
694 155404 : private double? _pos;
695 155404 : private string _vfunc_name;
696 155404 : private string _finish_name;
697 155404 : private string _finish_vfunc_name;
698 155404 : private string _finish_real_name;
699 155404 : private bool? _finish_instance;
700 155404 : private string _real_name;
701 155404 : private bool? _delegate_target;
702 155404 : private string _delegate_target_name;
703 155404 : private string _delegate_target_destroy_notify_name;
704 155404 : private string _ctype;
705 155404 : private bool ctype_set = false;
706 155404 : private bool? _array_length;
707 155404 : private string _array_length_type;
708 155404 : private bool? _array_null_terminated;
709 155404 : private string _sentinel;
710 :
711 : private static int dynamic_method_id;
712 :
713 310808 : public CCodeAttribute (CodeNode node) {
714 155404 : this.node = node;
715 155404 : this.sym = node as Symbol;
716 :
717 165400 : ccode = node.get_attribute ("CCode");
718 155404 : if (ccode != null) {
719 9996 : array_length_name = ccode.get_string ("array_length_cname");
720 9996 : array_length_expr = ccode.get_string ("array_length_cexpr");
721 : }
722 : }
723 :
724 141377 : private string get_default_name () {
725 141377 : if (sym != null) {
726 22839 : if (sym is Constant && !(sym is EnumValue)) {
727 264 : if (sym.parent_symbol is Block) {
728 : // local constant
729 32 : return sym.name;
730 : }
731 248 : return "%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol).ascii_up (), sym.name);
732 22575 : } else if (sym is Field) {
733 1828 : var cname = sym.name;
734 1828 : if (((Field) sym).binding == MemberBinding.STATIC) {
735 356 : cname = "%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), sym.name);
736 : }
737 1828 : if (cname[0].isdigit ()) {
738 1 : Report.error (node.source_reference, "Field name starts with a digit. Use the `cname' attribute to provide a valid C name if intended");
739 1827 : } else if (CCodeBaseModule.reserved_identifiers.contains (cname)) {
740 1 : Report.error (node.source_reference, "Field name `%s' collides with reserved identifier. Use the `cname' attribute to provide a valid C name if intended", cname);
741 : }
742 1828 : return cname;
743 20747 : } else if (sym is CreationMethod) {
744 1370 : unowned CreationMethod m = (CreationMethod) sym;
745 : string infix;
746 1370 : if (m.parent_symbol is Struct) {
747 45 : infix = "init";
748 : } else {
749 1325 : infix = "new";
750 : }
751 1370 : if (m.name == ".new") {
752 1318 : return "%s%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), infix);
753 : } else {
754 52 : return "%s%s_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), infix, m.name);
755 : }
756 19377 : } else if (sym is DynamicMethod) {
757 1 : return "_dynamic_%s%d".printf (sym.name, dynamic_method_id++);
758 19376 : } else if (sym is Method) {
759 5653 : unowned Method m = (Method) sym;
760 5653 : if (m.parent_node is LambdaExpression) {
761 353 : return "_vala_lambda%d_".printf (next_lambda_id++);
762 : }
763 5300 : if (m.is_async_callback) {
764 19 : return "%s_co".printf (get_ccode_real_name ((Method) m.parent_symbol));
765 : }
766 5281 : if (m.signal_reference != null) {
767 6 : return "%s%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), get_ccode_lower_case_name (m.signal_reference));
768 : }
769 : string cname;
770 5275 : if (sym.name == "main" && sym.parent_symbol.name == null) {
771 : // avoid conflict with generated main function
772 858 : if (m.coroutine) {
773 5 : return "_vala_main_async";
774 : } else {
775 853 : return "_vala_main";
776 : }
777 4417 : } else if (sym.name.has_prefix ("_")) {
778 7 : cname = "_%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), sym.name.substring (1));
779 : } else {
780 4410 : cname = "%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), sym.name);
781 : }
782 4417 : if (CCodeBaseModule.reserved_identifiers.contains (cname)) {
783 1 : Report.error (node.source_reference, "Method name `%s' collides with reserved identifier. Use the `cname' attribute to provide a valid C name if intended", cname);
784 : }
785 4417 : return cname;
786 13723 : } else if (sym is Property) {
787 394 : return sym.name.replace ("_", "-");
788 13329 : } else if (sym is PropertyAccessor) {
789 1313 : unowned PropertyAccessor acc = (PropertyAccessor) sym;
790 1313 : var t = (TypeSymbol) acc.prop.parent_symbol;
791 :
792 1313 : if (acc.readable) {
793 810 : return "%sget_%s".printf (get_ccode_lower_case_prefix (t), acc.prop.name);
794 : } else {
795 503 : return "%sset_%s".printf (get_ccode_lower_case_prefix (t), acc.prop.name);
796 : }
797 12016 : } else if (sym is Signal) {
798 99 : return Symbol.camel_case_to_lower_case (sym.name).replace ("_", "-");;
799 11917 : } else if (sym is LocalVariable) {
800 22 : unowned string name = sym.name;
801 22 : if (CCodeBaseModule.reserved_identifiers.contains (name) || CCodeBaseModule.reserved_vala_identifiers.contains (name)) {
802 0 : return "_%s_".printf (name);
803 : } else {
804 44 : return name;
805 : }
806 11895 : } else if (sym is Parameter) {
807 4400 : unowned Parameter param = (Parameter) sym;
808 4400 : if (param.ellipsis) {
809 2 : return "...";
810 : }
811 4398 : unowned string name = sym.name;
812 4398 : if (CCodeBaseModule.reserved_identifiers.contains (name) || CCodeBaseModule.reserved_vala_identifiers.contains (name)) {
813 13 : return "_%s_".printf (name);
814 : } else {
815 8770 : return name;
816 : }
817 7495 : } else if (sym is TypeParameter) {
818 0 : assert (node is GenericType);
819 0 : var type = (GenericType) node;
820 0 : if (type.value_owned) {
821 0 : if (CodeContext.get ().profile == Profile.GOBJECT) {
822 0 : return "gpointer";
823 : } else {
824 0 : return "void *";
825 : }
826 : } else {
827 0 : if (CodeContext.get ().profile == Profile.GOBJECT) {
828 0 : return "gconstpointer";
829 : } else {
830 0 : return "const void *";
831 : }
832 : }
833 : } else {
834 7495 : return "%s%s".printf (get_ccode_prefix (sym.parent_symbol), sym.name);
835 : }
836 118538 : } else if (node is ObjectType) {
837 73682 : var type = (ObjectType) node;
838 :
839 : string cname;
840 73682 : if (!type.value_owned) {
841 50306 : cname = get_ccode_const_name (type.type_symbol);
842 : } else {
843 23376 : cname = get_ccode_name (type.type_symbol);
844 : }
845 73682 : return "%s*".printf (cname);
846 44856 : } else if (node is ArrayType) {
847 4642 : var type = (ArrayType) node;
848 4642 : var cname = get_ccode_name (type.element_type);
849 4642 : if (type.inline_allocated) {
850 102 : return cname;
851 : } else {
852 4540 : return "%s*".printf (cname);
853 : }
854 40214 : } else if (node is DelegateType) {
855 1252 : var type = (DelegateType) node;
856 1252 : return get_ccode_name (type.delegate_symbol);
857 38962 : } else if (node is ErrorType) {
858 428 : return "GError*";
859 38534 : } else if (node is GenericType) {
860 935 : var type = (GenericType) node;
861 935 : if (type.value_owned) {
862 727 : if (CodeContext.get ().profile == Profile.GOBJECT) {
863 727 : return "gpointer";
864 : } else {
865 0 : return "void *";
866 : }
867 : } else {
868 208 : if (CodeContext.get ().profile == Profile.GOBJECT) {
869 208 : return "gconstpointer";
870 : } else {
871 0 : return "const void *";
872 : }
873 : }
874 37599 : } else if (node is MethodType) {
875 12 : if (CodeContext.get ().profile == Profile.GOBJECT) {
876 12 : return "gpointer";
877 : } else {
878 0 : return "void *";
879 : }
880 37587 : } else if (node is NullType) {
881 1 : if (CodeContext.get ().profile == Profile.GOBJECT) {
882 1 : return "gpointer";
883 : } else {
884 0 : return "void *";
885 : }
886 37586 : } else if (node is PointerType) {
887 804 : var type = (PointerType) node;
888 804 : if (type.base_type.type_symbol != null && type.base_type.type_symbol.is_reference_type ()) {
889 67 : return get_ccode_name (type.base_type);
890 : } else {
891 737 : return "%s*".printf (get_ccode_name (type.base_type));
892 : }
893 36782 : } else if (node is VoidType) {
894 9831 : return "void";
895 26951 : } else if (node is ClassType) {
896 7 : var type = (ClassType) node;
897 7 : return "%s*".printf (get_ccode_type_name (type.class_symbol));
898 26944 : } else if (node is InterfaceType) {
899 0 : var type = (InterfaceType) node;
900 0 : return "%s*".printf (get_ccode_type_name (type.interface_symbol));
901 26944 : } else if (node is ValueType) {
902 26782 : var type = (ValueType) node;
903 26782 : var cname = get_ccode_name (type.type_symbol);
904 26782 : if (type.nullable) {
905 1046 : return "%s*".printf (cname);
906 : } else {
907 25736 : return cname;
908 : }
909 162 : } else if (node is CType) {
910 322 : return ((CType) node).ctype_name;
911 : } else {
912 1 : Report.error (node.source_reference, "Unresolved type reference");
913 1 : return "";
914 : }
915 : }
916 :
917 6058 : private string get_default_header_filenames () {
918 6058 : if (sym is DynamicProperty || sym is DynamicMethod) {
919 0 : return "";
920 : }
921 6073 : if (sym.parent_symbol != null && !sym.is_extern) {
922 6043 : var parent_headers = get_ccode_header_filenames (sym.parent_symbol);
923 6043 : if (parent_headers.length > 0) {
924 6058 : return parent_headers;
925 : }
926 : }
927 30 : if (sym.source_reference != null && !sym.external_package && !sym.is_extern) {
928 : // don't add default include directives for VAPI files
929 6 : return sym.source_reference.file.get_cinclude_filename ();
930 : }
931 24 : return "";
932 : }
933 :
934 931 : private string get_default_prefix () {
935 931 : if (sym is ObjectTypeSymbol) {
936 66 : return name;
937 898 : } else if (sym is Enum || sym is ErrorDomain) {
938 169 : return "%s_".printf (get_ccode_upper_case_name (sym));
939 729 : } else if (sym is Namespace) {
940 689 : if (sym.name != null) {
941 75 : var parent_prefix = "";
942 75 : if (sym.parent_symbol != null) {
943 75 : parent_prefix = get_ccode_prefix (sym.parent_symbol);
944 : }
945 75 : return "%s%s".printf (parent_prefix, sym.name);
946 : } else {
947 614 : return "";
948 : }
949 40 : } else if (sym.name != null) {
950 80 : return sym.name;
951 : }
952 0 : return "";
953 : }
954 :
955 3023 : private string get_default_lower_case_prefix () {
956 3023 : if (sym is Namespace) {
957 904 : if (sym.name == null) {
958 723 : return "";
959 : } else {
960 181 : return "%s%s_".printf (get_ccode_lower_case_prefix (sym.parent_symbol), Symbol.camel_case_to_lower_case (sym.name));
961 : }
962 2119 : } else if (sym is Method) {
963 : // for lambda expressions
964 0 : return "";
965 : } else {
966 2119 : return "%s_".printf (get_ccode_lower_case_name (sym));
967 : }
968 : }
969 :
970 2289 : private string get_default_lower_case_suffix () {
971 2289 : if (sym is ObjectTypeSymbol) {
972 1807 : var csuffix = Symbol.camel_case_to_lower_case (sym.name);
973 :
974 : // FIXME Code duplication with GirParser.Node.get_default_lower_case_suffix()
975 : // remove underscores in some cases to avoid conflicts of type macros
976 1807 : if (csuffix.has_prefix ("type_")) {
977 17 : csuffix = "type" + csuffix.substring ("type_".length);
978 1790 : } else if (csuffix.has_prefix ("is_")) {
979 0 : csuffix = "is" + csuffix.substring ("is_".length);
980 : }
981 1807 : if (csuffix.has_suffix ("_class")) {
982 21 : csuffix = csuffix.substring (0, csuffix.length - "_class".length) + "class";
983 : }
984 1807 : return csuffix;
985 482 : } else if (sym is Signal) {
986 0 : return get_ccode_attribute (sym).name.replace ("-", "_");
987 482 : } else if (sym.name != null) {
988 482 : return Symbol.camel_case_to_lower_case (sym.name);
989 : }
990 0 : return "";
991 : }
992 :
993 1456 : private string? get_default_ref_function () {
994 1456 : if (sym is Class) {
995 1410 : unowned Class cl = (Class) sym;
996 1410 : if (cl.is_fundamental ()) {
997 317 : return "%sref".printf (lower_case_prefix);
998 1093 : } else if (cl.base_class != null) {
999 704 : return get_ccode_ref_function (cl.base_class);
1000 : }
1001 46 : } else if (sym is Interface) {
1002 46 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1003 44 : string ref_func = get_ccode_ref_function ((ObjectTypeSymbol) prereq.type_symbol);
1004 44 : if (ref_func != null) {
1005 44 : return ref_func;
1006 : }
1007 : }
1008 : }
1009 1456 : return null;
1010 : }
1011 :
1012 1104 : private string? get_default_unref_function () {
1013 1104 : if (sym is Class) {
1014 1046 : unowned Class cl = (Class) sym;
1015 1046 : if (cl.is_fundamental ()) {
1016 314 : return "%sunref".printf (lower_case_prefix);
1017 732 : } else if (cl.base_class != null) {
1018 700 : return get_ccode_unref_function (cl.base_class);
1019 : }
1020 58 : } else if (sym is Interface) {
1021 58 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1022 56 : string unref_func = get_ccode_unref_function ((ObjectTypeSymbol) prereq.type_symbol);
1023 56 : if (unref_func != null) {
1024 56 : return unref_func;
1025 : }
1026 : }
1027 : }
1028 1104 : return null;
1029 : }
1030 :
1031 0 : private string get_default_ref_sink_function () {
1032 0 : if (sym is Class) {
1033 0 : unowned Class? base_class = ((Class) sym).base_class;
1034 0 : if (base_class != null) {
1035 0 : return get_ccode_ref_sink_function (base_class);
1036 : }
1037 0 : } else if (sym is Interface) {
1038 0 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1039 0 : string ref_sink_func = get_ccode_ref_sink_function ((ObjectTypeSymbol) prereq.type_symbol);
1040 0 : if (ref_sink_func != "") {
1041 0 : return ref_sink_func;
1042 : }
1043 : }
1044 : }
1045 0 : return "";
1046 : }
1047 :
1048 306 : private string? get_default_free_function () {
1049 306 : if (sym is Class) {
1050 41 : unowned Class cl = (Class) sym;
1051 41 : if (cl.base_class != null) {
1052 9 : return get_ccode_free_function (cl.base_class);
1053 : }
1054 32 : return "%sfree".printf (lower_case_prefix);
1055 265 : } else if (sym is Struct) {
1056 203 : if (!sym.external_package && !((Struct) sym).is_simple_type ()) {
1057 157 : return "%sfree".printf (lower_case_prefix);
1058 : }
1059 : }
1060 306 : return null;
1061 : }
1062 :
1063 2719 : private string get_default_type_id () {
1064 2719 : if (sym != null) {
1065 1556 : if (sym is Class && !((Class) sym).is_compact || sym is Interface) {
1066 1281 : return get_ccode_upper_case_name (sym, "TYPE_");
1067 275 : } else if (sym is Struct) {
1068 156 : unowned Struct st = (Struct) sym;
1069 156 : unowned Struct? base_struct = st.base_struct;
1070 156 : if (!get_ccode_has_type_id (st) || (base_struct != null && base_struct.is_simple_type ())) {
1071 16 : if (base_struct != null) {
1072 13 : return get_ccode_type_id (base_struct);
1073 : }
1074 3 : if (!st.is_simple_type ()) {
1075 2 : return "G_TYPE_POINTER";
1076 : }
1077 : } else {
1078 140 : return get_ccode_upper_case_name (st, "TYPE_");
1079 : }
1080 119 : } else if (sym is Enum) {
1081 75 : unowned Enum en = (Enum) sym;
1082 75 : if (get_ccode_has_type_id (en)) {
1083 71 : return get_ccode_upper_case_name (en, "TYPE_");
1084 : } else {
1085 8 : return en.is_flags ? "G_TYPE_UINT" : "G_TYPE_INT";
1086 : }
1087 44 : } else if (sym is ErrorDomain) {
1088 40 : unowned ErrorDomain edomain = (ErrorDomain) sym;
1089 40 : if (get_ccode_has_type_id (edomain)) {
1090 40 : return get_ccode_upper_case_name (edomain, "TYPE_");
1091 : } else {
1092 0 : return "G_TYPE_ERROR";
1093 : }
1094 : } else {
1095 4 : return "G_TYPE_POINTER";
1096 : }
1097 1163 : } else if (node is ArrayType && ((ArrayType) node).element_type.type_symbol == CodeContext.get ().analyzer.string_type.type_symbol) {
1098 6 : return "G_TYPE_STRV";
1099 1157 : } else if (node is PointerType || node is DelegateType) {
1100 5 : return "G_TYPE_POINTER";
1101 1152 : } else if (node is ErrorType) {
1102 3 : return "G_TYPE_ERROR";
1103 1154 : } else if (node is VoidType) {
1104 1 : return "G_TYPE_NONE";
1105 : } else {
1106 1148 : var type = (DataType) node;
1107 1148 : if (type.type_symbol != null) {
1108 1143 : return get_ccode_type_id (type.type_symbol);
1109 : }
1110 : }
1111 6 : return "";
1112 : }
1113 :
1114 251 : private string get_default_marshaller_type_name () {
1115 251 : if (sym != null) {
1116 89 : if (sym is Class) {
1117 5 : unowned Class cl = (Class) sym;
1118 5 : if (cl.base_class != null) {
1119 1 : return get_ccode_marshaller_type_name (cl.base_class);
1120 4 : } else if (!cl.is_compact) {
1121 4 : return get_ccode_upper_case_name (cl);
1122 0 : } else if (type_id == "G_TYPE_POINTER") {
1123 0 : return "POINTER";
1124 : } else {
1125 0 : return "BOXED";
1126 : }
1127 84 : } else if (sym is Enum) {
1128 3 : unowned Enum en = (Enum) sym;
1129 3 : if (get_ccode_has_type_id (en)) {
1130 3 : if (en.is_flags) {
1131 1 : return "FLAGS";
1132 : } else {
1133 2 : return "ENUM";
1134 : }
1135 : } else {
1136 0 : if (en.is_flags) {
1137 0 : return "UINT";
1138 : } else {
1139 0 : return "INT";
1140 : }
1141 : }
1142 81 : } else if (sym is Interface) {
1143 2 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1144 2 : var type_name = get_ccode_marshaller_type_name (prereq.type_symbol);
1145 2 : if (type_name != "") {
1146 2 : return type_name;
1147 : }
1148 : }
1149 0 : return "POINTER";
1150 79 : } else if (sym is Struct) {
1151 5 : unowned Struct st = (Struct) sym;
1152 5 : unowned Struct? base_st = st.base_struct;
1153 5 : while (base_st != null) {
1154 1 : if (get_ccode_has_type_id (base_st)) {
1155 1 : return get_ccode_marshaller_type_name (base_st);
1156 : } else {
1157 0 : base_st = base_st.base_struct;
1158 : }
1159 : }
1160 4 : if (st.is_simple_type ()) {
1161 0 : Report.error (st.source_reference, "The type `%s' doesn't declare a marshaller type name", st.get_full_name ());
1162 4 : } else if (get_ccode_has_type_id (st)) {
1163 3 : return "BOXED";
1164 : } else {
1165 1 : return "POINTER";
1166 : }
1167 74 : } else if (sym is Parameter) {
1168 74 : unowned Parameter param = (Parameter) sym;
1169 74 : if (param.direction != ParameterDirection.IN) {
1170 1 : return "POINTER";
1171 : } else {
1172 73 : return get_ccode_marshaller_type_name (param.variable_type);
1173 : }
1174 : } else {
1175 0 : return "POINTER";
1176 : }
1177 162 : } else if (node is ValueType && ((ValueType) node).nullable) {
1178 14 : return "POINTER";
1179 148 : } else if (node is PointerType || node is GenericType) {
1180 6 : return "POINTER";
1181 142 : } else if (node is ErrorType) {
1182 2 : return "BOXED";
1183 140 : } else if (node is ArrayType) {
1184 3 : unowned ArrayType array_type = (ArrayType) node;
1185 3 : if (array_type.element_type.type_symbol == CodeContext.get ().analyzer.string_type.type_symbol) {
1186 2 : return "BOXED,%s".printf (get_ccode_marshaller_type_name (array_type.length_type.type_symbol));
1187 : } else {
1188 1 : var ret = "POINTER";
1189 1 : var length_marshaller_type_name = get_ccode_marshaller_type_name (array_type.length_type.type_symbol);
1190 4 : for (var i = 0; i < array_type.rank; i++) {
1191 3 : ret = "%s,%s".printf (ret, length_marshaller_type_name);
1192 : }
1193 1 : return ret;
1194 : }
1195 137 : } else if (node is DelegateType) {
1196 3 : unowned DelegateType delegate_type = (DelegateType) node;
1197 3 : var ret = "POINTER";
1198 3 : if (delegate_type.delegate_symbol.has_target) {
1199 2 : ret = "%s,POINTER".printf (ret);
1200 2 : if (delegate_type.is_disposable ()) {
1201 1 : ret = "%s,POINTER".printf (ret);
1202 : }
1203 : }
1204 3 : return ret;
1205 134 : } else if (node is VoidType) {
1206 65 : return "VOID";
1207 : } else {
1208 69 : return get_ccode_marshaller_type_name (((DataType) node).type_symbol);
1209 : }
1210 0 : return "";
1211 : }
1212 :
1213 332 : private string get_default_get_value_function () {
1214 332 : if (sym is Class) {
1215 286 : unowned Class cl = (Class) sym;
1216 286 : if (cl.is_fundamental ()) {
1217 259 : return get_ccode_lower_case_name (cl, "value_get_");
1218 27 : } else if (cl.base_class != null) {
1219 25 : return get_ccode_get_value_function (cl.base_class);
1220 2 : } else if (type_id == "G_TYPE_POINTER") {
1221 1 : return "g_value_get_pointer";
1222 : } else {
1223 1 : return "g_value_get_boxed";
1224 : }
1225 46 : } else if (sym is Enum) {
1226 15 : unowned Enum en = (Enum) sym;
1227 15 : if (get_ccode_has_type_id (en)) {
1228 13 : if (en.is_flags) {
1229 3 : return "g_value_get_flags";
1230 : } else {
1231 10 : return "g_value_get_enum";
1232 : }
1233 : } else {
1234 2 : if (en.is_flags) {
1235 1 : return "g_value_get_uint";
1236 : } else {
1237 1 : return "g_value_get_int";
1238 : }
1239 : }
1240 31 : } else if (sym is ErrorDomain) {
1241 1 : return "g_value_get_boxed";
1242 30 : } else if (sym is Interface) {
1243 1 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1244 1 : var type_name = get_ccode_get_value_function (prereq.type_symbol);
1245 1 : if (type_name != "") {
1246 1 : return type_name;
1247 : }
1248 : }
1249 0 : return "g_value_get_pointer";
1250 29 : } else if (sym is Struct) {
1251 25 : unowned Struct st = (Struct) sym;
1252 25 : unowned Struct? base_st = st.base_struct;
1253 25 : while (base_st != null) {
1254 13 : if (get_ccode_has_type_id (base_st)) {
1255 13 : return get_ccode_get_value_function (base_st);
1256 : } else {
1257 0 : base_st = base_st.base_struct;
1258 : }
1259 : }
1260 12 : if (st.is_simple_type ()) {
1261 0 : Report.error (st.source_reference, "The type `%s' doesn't declare a GValue get function", st.get_full_name ());
1262 12 : } else if (get_ccode_has_type_id (st)) {
1263 12 : return "g_value_get_boxed";
1264 : } else {
1265 0 : return "g_value_get_pointer";
1266 : }
1267 : } else {
1268 4 : return "g_value_get_pointer";
1269 : }
1270 0 : return "";
1271 : }
1272 :
1273 346 : private string get_default_set_value_function () {
1274 346 : if (sym is Class) {
1275 301 : unowned Class cl = (Class) sym;
1276 301 : if (cl.is_fundamental ()) {
1277 259 : return get_ccode_lower_case_name (cl, "value_set_");
1278 42 : } else if (cl.base_class != null) {
1279 40 : return get_ccode_set_value_function (cl.base_class);
1280 2 : } else if (type_id == "G_TYPE_POINTER") {
1281 1 : return "g_value_set_pointer";
1282 : } else {
1283 1 : return "g_value_set_boxed";
1284 : }
1285 45 : } else if (sym is Enum) {
1286 13 : unowned Enum en = (Enum) sym;
1287 13 : if (get_ccode_has_type_id (en)) {
1288 11 : if (en.is_flags) {
1289 2 : return "g_value_set_flags";
1290 : } else {
1291 9 : return "g_value_set_enum";
1292 : }
1293 : } else {
1294 2 : if (en.is_flags) {
1295 1 : return "g_value_set_uint";
1296 : } else {
1297 1 : return "g_value_set_int";
1298 : }
1299 : }
1300 32 : } else if (sym is ErrorDomain) {
1301 1 : return "g_value_set_boxed";
1302 31 : } else if (sym is Interface) {
1303 2 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1304 2 : var type_name = get_ccode_set_value_function (prereq.type_symbol);
1305 2 : if (type_name != "") {
1306 2 : return type_name;
1307 : }
1308 : }
1309 0 : return "g_value_set_pointer";
1310 29 : } else if (sym is Struct) {
1311 26 : unowned Struct st = (Struct) sym;
1312 26 : unowned Struct? base_st = st.base_struct;
1313 26 : while (base_st != null) {
1314 13 : if (get_ccode_has_type_id (base_st)) {
1315 13 : return get_ccode_set_value_function (base_st);
1316 : } else {
1317 0 : base_st = base_st.base_struct;
1318 : }
1319 : }
1320 13 : if (st.is_simple_type ()) {
1321 0 : Report.error (st.source_reference, "The type `%s' doesn't declare a GValue set function", st.get_full_name ());
1322 13 : } else if (get_ccode_has_type_id (st)) {
1323 13 : return "g_value_set_boxed";
1324 : } else {
1325 0 : return "g_value_set_pointer";
1326 : }
1327 : } else {
1328 3 : return "g_value_set_pointer";
1329 : }
1330 0 : return "";
1331 : }
1332 :
1333 263 : private string get_default_take_value_function () {
1334 263 : if (sym is Class) {
1335 260 : unowned Class cl = (Class) sym;
1336 260 : if (cl.is_fundamental ()) {
1337 256 : return get_ccode_lower_case_name (cl, "value_take_");
1338 4 : } else if (cl.base_class != null) {
1339 4 : return get_ccode_take_value_function (cl.base_class);
1340 0 : } else if (type_id == "G_TYPE_POINTER") {
1341 0 : return "g_value_set_pointer";
1342 : } else {
1343 0 : return "g_value_take_boxed";
1344 : }
1345 3 : } else if (sym is ErrorDomain) {
1346 1 : return "g_value_take_boxed";
1347 2 : } else if (sym is Interface) {
1348 1 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1349 1 : var func = get_ccode_take_value_function (prereq.type_symbol);
1350 1 : if (func != "") {
1351 1 : return func;
1352 : }
1353 : }
1354 0 : return "g_value_set_pointer";
1355 1 : } else if (sym is Struct) {
1356 0 : unowned Struct st = (Struct) sym;
1357 0 : unowned Struct? base_st = st.base_struct;
1358 0 : while (base_st != null) {
1359 0 : if (get_ccode_has_type_id (base_st)) {
1360 0 : return get_ccode_take_value_function (base_st);
1361 : } else {
1362 0 : base_st = base_st.base_struct;
1363 : }
1364 : }
1365 0 : if (st.is_simple_type ()) {
1366 0 : Report.error (st.source_reference, "The type `%s' doesn't declare a GValue take function", st.get_full_name ());
1367 0 : } else if (get_ccode_has_type_id (st)) {
1368 0 : return "g_value_take_boxed";
1369 : } else {
1370 0 : return "g_value_set_pointer";
1371 : }
1372 : } else {
1373 1 : return "g_value_set_pointer";
1374 : }
1375 0 : return "";
1376 : }
1377 :
1378 303 : private string get_default_param_spec_function () {
1379 303 : if (node is Symbol) {
1380 303 : if (sym is Class) {
1381 302 : unowned Class cl = (Class) sym;
1382 302 : if (cl.is_fundamental ()) {
1383 259 : return get_ccode_lower_case_name (cl, "param_spec_");
1384 43 : } else if (cl.base_class != null) {
1385 41 : return get_ccode_param_spec_function (cl.base_class);
1386 2 : } else if (type_id == "G_TYPE_POINTER") {
1387 1 : return "g_param_spec_pointer";
1388 : } else {
1389 1 : return "g_param_spec_boxed";
1390 : }
1391 1 : } else if (sym is Interface) {
1392 1 : foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1393 1 : var func = get_ccode_param_spec_function (prereq.type_symbol);
1394 1 : if (func != "") {
1395 1 : return func;
1396 : }
1397 : }
1398 0 : return "g_param_spec_pointer";
1399 0 : } else if (sym is Enum) {
1400 0 : unowned Enum e = (Enum) sym;
1401 0 : if (get_ccode_has_type_id (e)) {
1402 0 : if (e.is_flags) {
1403 0 : return "g_param_spec_flags";
1404 : } else {
1405 0 : return "g_param_spec_enum";
1406 : }
1407 : } else {
1408 0 : if (e.is_flags) {
1409 0 : return "g_param_spec_uint";
1410 : } else {
1411 0 : return "g_param_spec_int";
1412 : }
1413 : }
1414 0 : } else if (sym is ErrorDomain) {
1415 0 : return "g_param_spec_boxed";
1416 0 : } else if (sym is Struct) {
1417 0 : var type_id = get_ccode_type_id (sym);
1418 0 : if (type_id == "G_TYPE_INT") {
1419 0 : return "g_param_spec_int";
1420 0 : } else if (type_id == "G_TYPE_UINT") {
1421 0 : return "g_param_spec_uint";
1422 0 : } else if (type_id == "G_TYPE_INT64") {
1423 0 : return "g_param_spec_int64";
1424 0 : } else if (type_id == "G_TYPE_UINT64") {
1425 0 : return "g_param_spec_uint64";
1426 0 : } else if (type_id == "G_TYPE_LONG") {
1427 0 : return "g_param_spec_long";
1428 0 : } else if (type_id == "G_TYPE_ULONG") {
1429 0 : return "g_param_spec_ulong";
1430 0 : } else if (type_id == "G_TYPE_BOOLEAN") {
1431 0 : return "g_param_spec_boolean";
1432 0 : } else if (type_id == "G_TYPE_CHAR") {
1433 0 : return "g_param_spec_char";
1434 0 : } else if (type_id == "G_TYPE_UCHAR") {
1435 0 : return "g_param_spec_uchar";
1436 0 : }else if (type_id == "G_TYPE_FLOAT") {
1437 0 : return "g_param_spec_float";
1438 0 : } else if (type_id == "G_TYPE_DOUBLE") {
1439 0 : return "g_param_spec_double";
1440 0 : } else if (type_id == "G_TYPE_GTYPE") {
1441 0 : return "g_param_spec_gtype";
1442 : } else {
1443 0 : return "g_param_spec_boxed";
1444 : }
1445 : }
1446 0 : } else if (node is ArrayType && ((ArrayType) node).element_type.type_symbol == CodeContext.get ().analyzer.string_type.type_symbol) {
1447 0 : return "g_param_spec_boxed";
1448 0 : } else if (node is DataType && ((DataType) node).type_symbol != null) {
1449 0 : return get_ccode_param_spec_function (((DataType) node).type_symbol);
1450 : }
1451 :
1452 0 : return "g_param_spec_pointer";
1453 : }
1454 :
1455 1209 : private string get_default_default_value () {
1456 1209 : if (sym is Enum) {
1457 45 : unowned Enum en = (Enum) sym;
1458 45 : if (en.is_flags) {
1459 6 : return "0U";
1460 : } else {
1461 39 : return "0";
1462 : }
1463 1164 : } else if (sym is Struct) {
1464 205 : unowned Struct st = (Struct) sym;
1465 205 : unowned Struct? base_st = st.base_struct;
1466 205 : if (base_st != null) {
1467 39 : return get_ccode_default_value (base_st);
1468 : }
1469 : }
1470 1125 : return "";
1471 : }
1472 :
1473 215 : private string get_finish_name_for_basename (string basename) {
1474 215 : string result = basename;
1475 215 : if (result.has_suffix ("_async")) {
1476 48 : result = result.substring (0, result.length - "_async".length);
1477 : }
1478 215 : return "%s_finish".printf (result);
1479 : }
1480 :
1481 5877 : private string get_default_real_name () {
1482 5877 : if (sym is CreationMethod) {
1483 861 : unowned CreationMethod m = (CreationMethod) sym;
1484 861 : unowned Class? parent = m.parent_symbol as Class;
1485 :
1486 861 : if (parent == null || parent.is_compact) {
1487 164 : return name;
1488 : }
1489 :
1490 779 : string infix = "construct";
1491 :
1492 779 : if (m.name == ".new") {
1493 746 : return "%s%s".printf (get_ccode_lower_case_prefix (parent), infix);
1494 : } else {
1495 33 : return "%s%s_%s".printf (get_ccode_lower_case_prefix (parent), infix, m.name);
1496 : }
1497 5016 : } else if (sym is Method) {
1498 4168 : unowned Method m = (Method) sym;
1499 4168 : if (m.base_method != null || m.base_interface_method != null || m.signal_reference != null) {
1500 : string m_name;
1501 983 : if (m.signal_reference != null) {
1502 11 : m_name = get_ccode_lower_case_name (m.signal_reference);
1503 : } else {
1504 1944 : m_name = m.name;
1505 : }
1506 983 : if (m.base_interface_type != null) {
1507 8 : return "%sreal_%s%s".printf (get_ccode_lower_case_prefix (m.parent_symbol),
1508 : get_ccode_lower_case_prefix (m.base_interface_type.type_symbol),
1509 : m_name);
1510 : } else {
1511 975 : return "%sreal_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m_name);
1512 : }
1513 : } else {
1514 6370 : return name;
1515 : }
1516 848 : } else if (sym is PropertyAccessor) {
1517 848 : unowned PropertyAccessor acc = (PropertyAccessor) sym;
1518 848 : unowned Property prop = (Property) acc.prop;
1519 848 : if (prop.base_property != null || prop.base_interface_property != null) {
1520 144 : if (acc.readable) {
1521 86 : return "%sreal_get_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), prop.name);
1522 : } else {
1523 58 : return "%sreal_set_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), prop.name);
1524 : }
1525 : } else {
1526 1408 : return name;
1527 : }
1528 : }
1529 0 : assert_not_reached ();
1530 : }
1531 :
1532 1844 : private string get_default_const_name () {
1533 1844 : if (node is DataType) {
1534 50 : unowned DataType type = (DataType) node;
1535 : string ptr;
1536 : TypeSymbol t;
1537 : // FIXME: workaround to make constant arrays possible
1538 50 : if (type is ArrayType) {
1539 32 : t = ((ArrayType) type).element_type.type_symbol;
1540 : } else {
1541 18 : t = type.type_symbol;
1542 : }
1543 50 : if (!t.is_reference_type ()) {
1544 39 : ptr = "";
1545 : } else {
1546 11 : ptr = "*";
1547 : }
1548 :
1549 50 : return "const %s%s".printf (get_ccode_name (t), ptr);
1550 : } else {
1551 1794 : if (node is Class && ((Class) node).is_immutable) {
1552 3 : return "const %s".printf (name);
1553 : } else {
1554 3582 : return name;
1555 : }
1556 : }
1557 : }
1558 :
1559 15141 : private bool get_default_delegate_target () {
1560 15141 : if (node is Field || node is Parameter || node is LocalVariable) {
1561 8763 : if (node is Parameter) {
1562 6877 : unowned Parameter param = (Parameter) node;
1563 6877 : if (param.base_parameter != null) {
1564 851 : return get_ccode_delegate_target (param.base_parameter);
1565 : }
1566 : }
1567 7912 : unowned DelegateType? delegate_type = ((Variable) node).variable_type as DelegateType;
1568 7912 : return delegate_type != null && delegate_type.delegate_symbol.has_target;
1569 6378 : } else if (node is Callable) {
1570 5434 : if (node is Method) {
1571 5309 : unowned Method method = (Method) node;
1572 5309 : if (method.base_method != null && method.base_method != method) {
1573 623 : return get_ccode_delegate_target (method.base_method);
1574 4686 : } else if (method.base_interface_method != null && method.base_interface_method != method) {
1575 96 : return get_ccode_delegate_target (method.base_interface_method);
1576 : }
1577 : }
1578 4715 : unowned DelegateType? delegate_type = ((Callable) node).return_type as DelegateType;
1579 4715 : return delegate_type != null && delegate_type.delegate_symbol.has_target;
1580 944 : } else if (node is Property) {
1581 471 : unowned Property prop = (Property) node;
1582 471 : if (prop.base_property != null && prop.base_property != prop) {
1583 34 : return get_ccode_delegate_target (prop.base_property);
1584 437 : } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1585 34 : return get_ccode_delegate_target (prop.base_interface_property);
1586 : }
1587 403 : unowned DelegateType? delegate_type = prop.property_type as DelegateType;
1588 403 : return delegate_type != null && delegate_type.delegate_symbol.has_target;
1589 473 : } else if (node is PropertyAccessor) {
1590 441 : return get_ccode_delegate_target (((PropertyAccessor) node).prop);
1591 32 : } else if (node is Expression) {
1592 32 : unowned Symbol? symbol = ((Expression) node).symbol_reference;
1593 32 : if (symbol != null) {
1594 29 : return get_ccode_delegate_target (symbol);
1595 : }
1596 : }
1597 15141 : return false;
1598 : }
1599 :
1600 12604 : private bool get_default_array_length () {
1601 12604 : if (node is Parameter) {
1602 5441 : unowned Parameter param = (Parameter) node;
1603 5441 : if (param.base_parameter != null) {
1604 187 : return get_ccode_array_length (param.base_parameter);
1605 : }
1606 7163 : } else if (node is Method) {
1607 5395 : unowned Method method = (Method) node;
1608 5395 : if (method.base_method != null && method.base_method != method) {
1609 624 : return get_ccode_array_length (method.base_method);
1610 4771 : } else if (method.base_interface_method != null && method.base_interface_method != method) {
1611 97 : return get_ccode_array_length (method.base_interface_method);
1612 : }
1613 1768 : } else if (node is Property) {
1614 495 : unowned Property prop = (Property) node;
1615 495 : if (prop.base_property != null && prop.base_property != prop) {
1616 35 : return get_ccode_array_length (prop.base_property);
1617 460 : } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1618 35 : return get_ccode_array_length (prop.base_interface_property);
1619 : }
1620 1273 : } else if (node is PropertyAccessor) {
1621 458 : return get_ccode_array_length (((PropertyAccessor) node).prop);
1622 : }
1623 12604 : return true;
1624 : }
1625 :
1626 8836 : private bool get_default_array_null_terminated () {
1627 8836 : if (node is Parameter) {
1628 6577 : unowned Parameter param = (Parameter) node;
1629 6577 : if (param.base_parameter != null) {
1630 790 : return get_ccode_array_null_terminated (param.base_parameter);
1631 : }
1632 2259 : } else if (node is Method) {
1633 62 : unowned Method method = (Method) node;
1634 62 : if (method.base_method != null && method.base_method != method) {
1635 1 : return get_ccode_array_null_terminated (method.base_method);
1636 61 : } else if (method.base_interface_method != null && method.base_interface_method != method) {
1637 0 : return get_ccode_array_null_terminated (method.base_interface_method);
1638 : }
1639 2197 : } else if (node is Property) {
1640 33 : unowned Property prop = (Property) node;
1641 33 : if (prop.base_property != null && prop.base_property != prop) {
1642 0 : return get_ccode_array_null_terminated (prop.base_property);
1643 33 : } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1644 0 : return get_ccode_array_null_terminated (prop.base_interface_property);
1645 : }
1646 2164 : } else if (node is PropertyAccessor) {
1647 0 : return get_ccode_array_null_terminated (((PropertyAccessor) node).prop);
1648 : }
1649 8836 : return false;
1650 : }
1651 :
1652 408 : private string get_default_array_length_type () {
1653 408 : if (node is Field || node is Parameter) {
1654 315 : if (node is Parameter) {
1655 234 : unowned Parameter param = (Parameter) node;
1656 234 : if (param.base_parameter != null) {
1657 5 : return get_ccode_array_length_type (param.base_parameter);
1658 : }
1659 : }
1660 310 : return get_ccode_array_length_type (((Variable) node).variable_type);
1661 93 : } else if (node is Method || node is Delegate) {
1662 76 : if (node is Method) {
1663 73 : unowned Method method = (Method) node;
1664 73 : if (method.base_method != null && method.base_method != method) {
1665 1 : return get_ccode_array_length_type (method.base_method);
1666 72 : } else if (method.base_interface_method != null && method.base_interface_method != method) {
1667 1 : return get_ccode_array_length_type (method.base_interface_method);
1668 : }
1669 : }
1670 74 : return get_ccode_array_length_type (((Callable) node).return_type);
1671 17 : } else if (node is Property) {
1672 17 : unowned Property prop = (Property) node;
1673 17 : if (prop.base_property != null && prop.base_property != prop) {
1674 1 : return get_ccode_array_length_type (prop.base_property);
1675 16 : } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1676 1 : return get_ccode_array_length_type (prop.base_interface_property);
1677 : } else {
1678 15 : return get_ccode_array_length_type (prop.property_type);
1679 : }
1680 0 : } else if (node is PropertyAccessor) {
1681 0 : return get_ccode_array_length_type (((PropertyAccessor) node).prop);
1682 : } else {
1683 0 : Report.error (node.source_reference, "`CCode.array_length_type' not supported");
1684 0 : return "";
1685 : }
1686 : }
1687 : }
|