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