1 #include "Type.h" 2 3 Namespace NAMES; 4 5 Type* VOID_TYPE; 6 Type* BOOLEAN_TYPE; 7 Type* BYTE_TYPE; 8 Type* CHAR_TYPE; 9 Type* INT_TYPE; 10 Type* LONG_TYPE; 11 Type* FLOAT_TYPE; 12 Type* DOUBLE_TYPE; 13 Type* STRING_TYPE; 14 Type* CHAR_SEQUENCE_TYPE; 15 Type* TEXT_UTILS_TYPE; 16 Type* REMOTE_EXCEPTION_TYPE; 17 Type* RUNTIME_EXCEPTION_TYPE; 18 Type* IBINDER_TYPE; 19 Type* IINTERFACE_TYPE; 20 Type* BINDER_NATIVE_TYPE; 21 Type* BINDER_PROXY_TYPE; 22 Type* PARCEL_TYPE; 23 Type* PARCELABLE_INTERFACE_TYPE; 24 Type* MAP_TYPE; 25 Type* LIST_TYPE; 26 Type* CLASSLOADER_TYPE; 27 28 Expression* NULL_VALUE; 29 Expression* THIS_VALUE; 30 Expression* SUPER_VALUE; 31 Expression* TRUE_VALUE; 32 Expression* FALSE_VALUE; 33 34 void 35 register_base_types() 36 { 37 VOID_TYPE = new BasicType("void", "XXX", "XXX", "XXX", "XXX", "XXX"); 38 NAMES.Add(VOID_TYPE); 39 40 BOOLEAN_TYPE = new BooleanType(); 41 NAMES.Add(BOOLEAN_TYPE); 42 43 BYTE_TYPE = new BasicType("byte", "writeByte", "readByte", 44 "writeByteArray", "createByteArray", "readByteArray"); 45 NAMES.Add(BYTE_TYPE); 46 47 CHAR_TYPE = new CharType(); 48 NAMES.Add(CHAR_TYPE); 49 50 INT_TYPE = new BasicType("int", "writeInt", "readInt", 51 "writeIntArray", "createIntArray", "readIntArray"); 52 NAMES.Add(INT_TYPE); 53 54 LONG_TYPE = new BasicType("long", "writeLong", "readLong", 55 "writeLongArray", "createLongArray", "readLongArray"); 56 NAMES.Add(LONG_TYPE); 57 58 FLOAT_TYPE = new BasicType("float", "writeFloat", "readFloat", 59 "writeFloatArray", "createFloatArray", "readFloatArray"); 60 NAMES.Add(FLOAT_TYPE); 61 62 DOUBLE_TYPE = new BasicType("double", "writeDouble", "readDouble", 63 "writeDoubleArray", "createDoubleArray", "readDoubleArray"); 64 NAMES.Add(DOUBLE_TYPE); 65 66 STRING_TYPE = new StringType(); 67 NAMES.Add(STRING_TYPE); 68 69 CHAR_SEQUENCE_TYPE = new CharSequenceType(); 70 NAMES.Add(CHAR_SEQUENCE_TYPE); 71 72 MAP_TYPE = new MapType(); 73 NAMES.Add(MAP_TYPE); 74 75 LIST_TYPE = new ListType(); 76 NAMES.Add(LIST_TYPE); 77 78 TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", 79 Type::BUILT_IN, false, false); 80 NAMES.Add(TEXT_UTILS_TYPE); 81 82 REMOTE_EXCEPTION_TYPE = new RemoteExceptionType(); 83 NAMES.Add(REMOTE_EXCEPTION_TYPE); 84 85 RUNTIME_EXCEPTION_TYPE = new RuntimeExceptionType(); 86 NAMES.Add(RUNTIME_EXCEPTION_TYPE); 87 88 IBINDER_TYPE = new IBinderType(); 89 NAMES.Add(IBINDER_TYPE); 90 91 IINTERFACE_TYPE = new IInterfaceType(); 92 NAMES.Add(IINTERFACE_TYPE); 93 94 BINDER_NATIVE_TYPE = new BinderType(); 95 NAMES.Add(BINDER_NATIVE_TYPE); 96 97 BINDER_PROXY_TYPE = new BinderProxyType(); 98 NAMES.Add(BINDER_PROXY_TYPE); 99 100 PARCEL_TYPE = new ParcelType(); 101 NAMES.Add(PARCEL_TYPE); 102 103 PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType(); 104 NAMES.Add(PARCELABLE_INTERFACE_TYPE); 105 106 CLASSLOADER_TYPE = new ClassLoaderType(); 107 NAMES.Add(CLASSLOADER_TYPE); 108 109 NULL_VALUE = new LiteralExpression("null"); 110 THIS_VALUE = new LiteralExpression("this"); 111 SUPER_VALUE = new LiteralExpression("super"); 112 TRUE_VALUE = new LiteralExpression("true"); 113 FALSE_VALUE = new LiteralExpression("false"); 114 115 NAMES.AddGenericType("java.util", "List", 1); 116 NAMES.AddGenericType("java.util", "Map", 2); 117 } 118 119 static Type* 120 make_generic_type(const string& package, const string& name, 121 const vector<Type*>& args) 122 { 123 if (package == "java.util" && name == "List") { 124 return new GenericListType("java.util", "List", args); 125 } 126 return NULL; 127 //return new GenericType(package, name, args); 128 } 129 130 // ================================================================ 131 132 Type::Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut) 133 :m_package(), 134 m_name(name), 135 m_declFile(""), 136 m_declLine(-1), 137 m_kind(kind), 138 m_canWriteToParcel(canWriteToParcel), 139 m_canBeOut(canBeOut) 140 { 141 m_qualifiedName = name; 142 } 143 144 Type::Type(const string& package, const string& name, 145 int kind, bool canWriteToParcel, bool canBeOut, 146 const string& declFile, int declLine) 147 :m_package(package), 148 m_name(name), 149 m_declFile(declFile), 150 m_declLine(declLine), 151 m_kind(kind), 152 m_canWriteToParcel(canWriteToParcel), 153 m_canBeOut(canBeOut) 154 { 155 if (package.length() > 0) { 156 m_qualifiedName = package; 157 m_qualifiedName += '.'; 158 } 159 m_qualifiedName += name; 160 } 161 162 Type::~Type() 163 { 164 } 165 166 bool 167 Type::CanBeArray() const 168 { 169 return false; 170 } 171 172 string 173 Type::ImportType() const 174 { 175 return m_qualifiedName; 176 } 177 178 string 179 Type::CreatorName() const 180 { 181 return ""; 182 } 183 184 string 185 Type::InstantiableName() const 186 { 187 return QualifiedName(); 188 } 189 190 191 void 192 Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 193 { 194 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn", 195 __FILE__, __LINE__, m_qualifiedName.c_str()); 196 addTo->Add(new LiteralExpression("/* WriteToParcel error " 197 + m_qualifiedName + " */")); 198 } 199 200 void 201 Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 202 { 203 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", 204 __FILE__, __LINE__, m_qualifiedName.c_str()); 205 addTo->Add(new LiteralExpression("/* CreateFromParcel error " 206 + m_qualifiedName + " */")); 207 } 208 209 void 210 Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 211 { 212 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", 213 __FILE__, __LINE__, m_qualifiedName.c_str()); 214 addTo->Add(new LiteralExpression("/* ReadFromParcel error " 215 + m_qualifiedName + " */")); 216 } 217 218 void 219 Type::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 220 { 221 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", 222 __FILE__, __LINE__, m_qualifiedName.c_str()); 223 addTo->Add(new LiteralExpression("/* WriteArrayToParcel error " 224 + m_qualifiedName + " */")); 225 } 226 227 void 228 Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 229 Variable* parcel, Variable**) 230 { 231 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", 232 __FILE__, __LINE__, m_qualifiedName.c_str()); 233 addTo->Add(new LiteralExpression("/* CreateArrayFromParcel error " 234 + m_qualifiedName + " */")); 235 } 236 237 void 238 Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 239 { 240 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", 241 __FILE__, __LINE__, m_qualifiedName.c_str()); 242 addTo->Add(new LiteralExpression("/* ReadArrayFromParcel error " 243 + m_qualifiedName + " */")); 244 } 245 246 void 247 Type::SetQualifiedName(const string& qualified) 248 { 249 m_qualifiedName = qualified; 250 } 251 252 Expression* 253 Type::BuildWriteToParcelFlags(int flags) 254 { 255 if (flags == 0) { 256 return new LiteralExpression("0"); 257 } 258 if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0) { 259 return new FieldVariable(PARCELABLE_INTERFACE_TYPE, 260 "PARCELABLE_WRITE_RETURN_VALUE"); 261 } 262 return new LiteralExpression("0"); 263 } 264 265 // ================================================================ 266 267 BasicType::BasicType(const string& name, const string& marshallMethod, 268 const string& unmarshallMethod, 269 const string& writeArray, const string& createArray, 270 const string& readArray) 271 :Type(name, BUILT_IN, true, false), 272 m_marshallMethod(marshallMethod), 273 m_unmarshallMethod(unmarshallMethod), 274 m_writeArrayMethod(writeArray), 275 m_createArrayMethod(createArray), 276 m_readArrayMethod(readArray) 277 { 278 } 279 280 void 281 BasicType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 282 { 283 addTo->Add(new MethodCall(parcel, m_marshallMethod, 1, v)); 284 } 285 286 void 287 BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 288 { 289 addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallMethod))); 290 } 291 292 bool 293 BasicType::CanBeArray() const 294 { 295 return true; 296 } 297 298 void 299 BasicType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 300 { 301 addTo->Add(new MethodCall(parcel, m_writeArrayMethod, 1, v)); 302 } 303 304 void 305 BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 306 Variable* parcel, Variable**) 307 { 308 addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayMethod))); 309 } 310 311 void 312 BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 313 { 314 addTo->Add(new MethodCall(parcel, m_readArrayMethod, 1, v)); 315 } 316 317 318 // ================================================================ 319 320 BooleanType::BooleanType() 321 :Type("boolean", BUILT_IN, true, false) 322 { 323 } 324 325 void 326 BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 327 { 328 addTo->Add(new MethodCall(parcel, "writeInt", 1, 329 new Ternary(v, new LiteralExpression("1"), 330 new LiteralExpression("0")))); 331 } 332 333 void 334 BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 335 { 336 addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"), 337 "!=", new MethodCall(parcel, "readInt")))); 338 } 339 340 bool 341 BooleanType::CanBeArray() const 342 { 343 return true; 344 } 345 346 void 347 BooleanType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 348 { 349 addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v)); 350 } 351 352 void 353 BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 354 Variable* parcel, Variable**) 355 { 356 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray"))); 357 } 358 359 void 360 BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 361 { 362 addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v)); 363 } 364 365 366 // ================================================================ 367 368 CharType::CharType() 369 :Type("char", BUILT_IN, true, false) 370 { 371 } 372 373 void 374 CharType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 375 { 376 addTo->Add(new MethodCall(parcel, "writeInt", 1, 377 new Cast(INT_TYPE, v))); 378 } 379 380 void 381 CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 382 { 383 addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this)); 384 } 385 386 bool 387 CharType::CanBeArray() const 388 { 389 return true; 390 } 391 392 void 393 CharType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 394 { 395 addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v)); 396 } 397 398 void 399 CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 400 Variable* parcel, Variable**) 401 { 402 addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray"))); 403 } 404 405 void 406 CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 407 { 408 addTo->Add(new MethodCall(parcel, "readCharArray", 1, v)); 409 } 410 411 // ================================================================ 412 413 StringType::StringType() 414 :Type("java.lang", "String", BUILT_IN, true, false) 415 { 416 } 417 418 string 419 StringType::CreatorName() const 420 { 421 return "android.os.Parcel.STRING_CREATOR"; 422 } 423 424 void 425 StringType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 426 { 427 addTo->Add(new MethodCall(parcel, "writeString", 1, v)); 428 } 429 430 void 431 StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 432 { 433 addTo->Add(new Assignment(v, new MethodCall(parcel, "readString"))); 434 } 435 436 bool 437 StringType::CanBeArray() const 438 { 439 return true; 440 } 441 442 void 443 StringType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 444 { 445 addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v)); 446 } 447 448 void 449 StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 450 Variable* parcel, Variable**) 451 { 452 addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray"))); 453 } 454 455 void 456 StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 457 { 458 addTo->Add(new MethodCall(parcel, "readStringArray", 1, v)); 459 } 460 461 // ================================================================ 462 463 CharSequenceType::CharSequenceType() 464 :Type("java.lang", "CharSequence", BUILT_IN, true, false) 465 { 466 } 467 468 string 469 CharSequenceType::CreatorName() const 470 { 471 return "android.os.Parcel.STRING_CREATOR"; 472 } 473 474 void 475 CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 476 { 477 // if (v != null) { 478 // parcel.writeInt(1); 479 // v.writeToParcel(parcel); 480 // } else { 481 // parcel.writeInt(0); 482 // } 483 IfStatement* elsepart = new IfStatement(); 484 elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1, 485 new LiteralExpression("0"))); 486 IfStatement* ifpart = new IfStatement; 487 ifpart->expression = new Comparison(v, "!=", NULL_VALUE); 488 ifpart->elseif = elsepart; 489 ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1, 490 new LiteralExpression("1"))); 491 ifpart->statements->Add(new MethodCall(TEXT_UTILS_TYPE, "writeToParcel", 492 3, v, parcel, BuildWriteToParcelFlags(flags))); 493 494 addTo->Add(ifpart); 495 } 496 497 void 498 CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v, 499 Variable* parcel, Variable**) 500 { 501 // if (0 != parcel.readInt()) { 502 // v = TextUtils.createFromParcel(parcel) 503 // } else { 504 // v = null; 505 // } 506 IfStatement* elsepart = new IfStatement(); 507 elsepart->statements->Add(new Assignment(v, NULL_VALUE)); 508 509 IfStatement* ifpart = new IfStatement(); 510 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", 511 new MethodCall(parcel, "readInt")); 512 ifpart->elseif = elsepart; 513 ifpart->statements->Add(new Assignment(v, 514 new MethodCall(TEXT_UTILS_TYPE, 515 "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel))); 516 517 addTo->Add(ifpart); 518 } 519 520 521 // ================================================================ 522 523 RemoteExceptionType::RemoteExceptionType() 524 :Type("android.os", "RemoteException", BUILT_IN, false, false) 525 { 526 } 527 528 void 529 RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 530 { 531 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 532 } 533 534 void 535 RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 536 { 537 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 538 } 539 540 // ================================================================ 541 542 RuntimeExceptionType::RuntimeExceptionType() 543 :Type("java.lang", "RuntimeException", BUILT_IN, false, false) 544 { 545 } 546 547 void 548 RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 549 { 550 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 551 } 552 553 void 554 RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 555 { 556 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 557 } 558 559 560 // ================================================================ 561 562 IBinderType::IBinderType() 563 :Type("android.os", "IBinder", BUILT_IN, true, false) 564 { 565 } 566 567 void 568 IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 569 { 570 addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v)); 571 } 572 573 void 574 IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 575 { 576 addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder"))); 577 } 578 579 void 580 IBinderType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 581 { 582 addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v)); 583 } 584 585 void 586 IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 587 Variable* parcel, Variable**) 588 { 589 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray"))); 590 } 591 592 void 593 IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 594 { 595 addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v)); 596 } 597 598 599 // ================================================================ 600 601 IInterfaceType::IInterfaceType() 602 :Type("android.os", "IInterface", BUILT_IN, false, false) 603 { 604 } 605 606 void 607 IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 608 { 609 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 610 } 611 612 void 613 IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 614 { 615 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 616 } 617 618 619 // ================================================================ 620 621 BinderType::BinderType() 622 :Type("android.os", "Binder", BUILT_IN, false, false) 623 { 624 } 625 626 void 627 BinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 628 { 629 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 630 } 631 632 void 633 BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, 634 Variable* parcel, Variable**) 635 { 636 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 637 } 638 639 640 // ================================================================ 641 642 BinderProxyType::BinderProxyType() 643 :Type("android.os", "BinderProxy", BUILT_IN, false, false) 644 { 645 } 646 647 void 648 BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 649 { 650 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 651 } 652 653 void 654 BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v, 655 Variable* parcel, Variable**) 656 { 657 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 658 } 659 660 661 // ================================================================ 662 663 ParcelType::ParcelType() 664 :Type("android.os", "Parcel", BUILT_IN, false, false) 665 { 666 } 667 668 void 669 ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 670 { 671 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 672 } 673 674 void 675 ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 676 { 677 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 678 } 679 680 // ================================================================ 681 682 ParcelableInterfaceType::ParcelableInterfaceType() 683 :Type("android.os", "Parcelable", BUILT_IN, false, false) 684 { 685 } 686 687 void 688 ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 689 { 690 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 691 } 692 693 void 694 ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 695 { 696 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 697 } 698 699 // ================================================================ 700 701 MapType::MapType() 702 :Type("java.util", "Map", BUILT_IN, true, true) 703 { 704 } 705 706 void 707 MapType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 708 { 709 addTo->Add(new MethodCall(parcel, "writeMap", 1, v)); 710 } 711 712 static void EnsureClassLoader(StatementBlock* addTo, Variable** cl) 713 { 714 // We don't want to look up the class loader once for every 715 // collection argument, so ensure we do it at most once per method. 716 if (*cl == NULL) { 717 *cl = new Variable(CLASSLOADER_TYPE, "cl"); 718 addTo->Add(new VariableDeclaration(*cl, 719 new LiteralExpression("this.getClass().getClassLoader()"), 720 CLASSLOADER_TYPE)); 721 } 722 } 723 724 void 725 MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl) 726 { 727 EnsureClassLoader(addTo, cl); 728 addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl))); 729 } 730 731 void 732 MapType::ReadFromParcel(StatementBlock* addTo, Variable* v, 733 Variable* parcel, Variable** cl) 734 { 735 EnsureClassLoader(addTo, cl); 736 addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl)); 737 } 738 739 740 // ================================================================ 741 742 ListType::ListType() 743 :Type("java.util", "List", BUILT_IN, true, true) 744 { 745 } 746 747 string 748 ListType::InstantiableName() const 749 { 750 return "java.util.ArrayList"; 751 } 752 753 void 754 ListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 755 { 756 addTo->Add(new MethodCall(parcel, "writeList", 1, v)); 757 } 758 759 void 760 ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl) 761 { 762 EnsureClassLoader(addTo, cl); 763 addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl))); 764 } 765 766 void 767 ListType::ReadFromParcel(StatementBlock* addTo, Variable* v, 768 Variable* parcel, Variable** cl) 769 { 770 EnsureClassLoader(addTo, cl); 771 addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl)); 772 } 773 774 775 // ================================================================ 776 777 ParcelableType::ParcelableType(const string& package, const string& name, 778 bool builtIn, const string& declFile, int declLine) 779 :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, true, 780 declFile, declLine) 781 { 782 } 783 784 string 785 ParcelableType::CreatorName() const 786 { 787 return QualifiedName() + ".CREATOR"; 788 } 789 790 void 791 ParcelableType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 792 { 793 // if (v != null) { 794 // parcel.writeInt(1); 795 // v.writeToParcel(parcel); 796 // } else { 797 // parcel.writeInt(0); 798 // } 799 IfStatement* elsepart = new IfStatement(); 800 elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1, 801 new LiteralExpression("0"))); 802 IfStatement* ifpart = new IfStatement; 803 ifpart->expression = new Comparison(v, "!=", NULL_VALUE); 804 ifpart->elseif = elsepart; 805 ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1, 806 new LiteralExpression("1"))); 807 ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2, 808 parcel, BuildWriteToParcelFlags(flags))); 809 810 addTo->Add(ifpart); 811 } 812 813 void 814 ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 815 { 816 // if (0 != parcel.readInt()) { 817 // v = CLASS.CREATOR.createFromParcel(parcel) 818 // } else { 819 // v = null; 820 // } 821 IfStatement* elsepart = new IfStatement(); 822 elsepart->statements->Add(new Assignment(v, NULL_VALUE)); 823 824 IfStatement* ifpart = new IfStatement(); 825 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", 826 new MethodCall(parcel, "readInt")); 827 ifpart->elseif = elsepart; 828 ifpart->statements->Add(new Assignment(v, 829 new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel))); 830 831 addTo->Add(ifpart); 832 } 833 834 void 835 ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v, 836 Variable* parcel, Variable**) 837 { 838 // TODO: really, we don't need to have this extra check, but we 839 // don't have two separate marshalling code paths 840 // if (0 != parcel.readInt()) { 841 // v.readFromParcel(parcel) 842 // } 843 IfStatement* ifpart = new IfStatement(); 844 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", 845 new MethodCall(parcel, "readInt")); 846 ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel)); 847 addTo->Add(ifpart); 848 } 849 850 bool 851 ParcelableType::CanBeArray() const 852 { 853 return true; 854 } 855 856 void 857 ParcelableType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 858 { 859 addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v, 860 BuildWriteToParcelFlags(flags))); 861 } 862 863 void 864 ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 865 Variable* parcel, Variable**) 866 { 867 string creator = v->type->QualifiedName() + ".CREATOR"; 868 addTo->Add(new Assignment(v, new MethodCall(parcel, 869 "createTypedArray", 1, new LiteralExpression(creator)))); 870 } 871 872 void 873 ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 874 { 875 string creator = v->type->QualifiedName() + ".CREATOR"; 876 addTo->Add(new MethodCall(parcel, "readTypedArray", 2, 877 v, new LiteralExpression(creator))); 878 } 879 880 881 // ================================================================ 882 883 InterfaceType::InterfaceType(const string& package, const string& name, 884 bool builtIn, bool oneway, 885 const string& declFile, int declLine) 886 :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, 887 declFile, declLine) 888 ,m_oneway(oneway) 889 { 890 } 891 892 bool 893 InterfaceType::OneWay() const 894 { 895 return m_oneway; 896 } 897 898 void 899 InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 900 { 901 // parcel.writeStrongBinder(v != null ? v.asBinder() : null); 902 addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, 903 new Ternary( 904 new Comparison(v, "!=", NULL_VALUE), 905 new MethodCall(v, "asBinder"), 906 NULL_VALUE))); 907 } 908 909 void 910 InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 911 { 912 // v = Interface.asInterface(parcel.readStrongBinder()); 913 string type = v->type->QualifiedName(); 914 type += ".Stub"; 915 addTo->Add(new Assignment(v, 916 new MethodCall( NAMES.Find(type), "asInterface", 1, 917 new MethodCall(parcel, "readStrongBinder")))); 918 } 919 920 921 // ================================================================ 922 923 GenericType::GenericType(const string& package, const string& name, 924 const vector<Type*>& args) 925 :Type(package, name, BUILT_IN, true, true) 926 { 927 m_args = args; 928 929 m_importName = package + '.' + name; 930 931 string gen = "<"; 932 int N = args.size(); 933 for (int i=0; i<N; i++) { 934 Type* t = args[i]; 935 gen += t->QualifiedName(); 936 if (i != N-1) { 937 gen += ','; 938 } 939 } 940 gen += '>'; 941 m_genericArguments = gen; 942 SetQualifiedName(m_importName + gen); 943 } 944 945 string 946 GenericType::GenericArguments() const 947 { 948 return m_genericArguments; 949 } 950 951 string 952 GenericType::ImportType() const 953 { 954 return m_importName; 955 } 956 957 void 958 GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 959 { 960 fprintf(stderr, "implement GenericType::WriteToParcel\n"); 961 } 962 963 void 964 GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 965 { 966 fprintf(stderr, "implement GenericType::CreateFromParcel\n"); 967 } 968 969 void 970 GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v, 971 Variable* parcel, Variable**) 972 { 973 fprintf(stderr, "implement GenericType::ReadFromParcel\n"); 974 } 975 976 977 // ================================================================ 978 979 GenericListType::GenericListType(const string& package, const string& name, 980 const vector<Type*>& args) 981 :GenericType(package, name, args), 982 m_creator(args[0]->CreatorName()) 983 { 984 } 985 986 string 987 GenericListType::CreatorName() const 988 { 989 return "android.os.Parcel.arrayListCreator"; 990 } 991 992 string 993 GenericListType::InstantiableName() const 994 { 995 return "java.util.ArrayList" + GenericArguments(); 996 } 997 998 void 999 GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 1000 { 1001 if (m_creator == STRING_TYPE->CreatorName()) { 1002 addTo->Add(new MethodCall(parcel, "writeStringList", 1, v)); 1003 } else if (m_creator == IBINDER_TYPE->CreatorName()) { 1004 addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v)); 1005 } else { 1006 // parcel.writeTypedListXX(arg); 1007 addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v)); 1008 } 1009 } 1010 1011 void 1012 GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 1013 { 1014 if (m_creator == STRING_TYPE->CreatorName()) { 1015 addTo->Add(new Assignment(v, 1016 new MethodCall(parcel, "createStringArrayList", 0))); 1017 } else if (m_creator == IBINDER_TYPE->CreatorName()) { 1018 addTo->Add(new Assignment(v, 1019 new MethodCall(parcel, "createBinderArrayList", 0))); 1020 } else { 1021 // v = _data.readTypedArrayList(XXX.creator); 1022 addTo->Add(new Assignment(v, 1023 new MethodCall(parcel, "createTypedArrayList", 1, 1024 new LiteralExpression(m_creator)))); 1025 } 1026 } 1027 1028 void 1029 GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v, 1030 Variable* parcel, Variable**) 1031 { 1032 if (m_creator == STRING_TYPE->CreatorName()) { 1033 addTo->Add(new MethodCall(parcel, "readStringList", 1, v)); 1034 } else if (m_creator == IBINDER_TYPE->CreatorName()) { 1035 addTo->Add(new MethodCall(parcel, "readBinderList", 1, v)); 1036 } else { 1037 // v = _data.readTypedList(v, XXX.creator); 1038 addTo->Add(new MethodCall(parcel, "readTypedList", 2, 1039 v, 1040 new LiteralExpression(m_creator))); 1041 } 1042 } 1043 1044 // ================================================================ 1045 1046 ClassLoaderType::ClassLoaderType() 1047 :Type("java.lang", "ClassLoader", BUILT_IN, false, false) 1048 { 1049 } 1050 1051 1052 // ================================================================ 1053 1054 Namespace::Namespace() 1055 { 1056 } 1057 1058 Namespace::~Namespace() 1059 { 1060 int N = m_types.size(); 1061 for (int i=0; i<N; i++) { 1062 delete m_types[i]; 1063 } 1064 } 1065 1066 void 1067 Namespace::Add(Type* type) 1068 { 1069 Type* t = Find(type->QualifiedName()); 1070 if (t == NULL) { 1071 m_types.push_back(type); 1072 } 1073 } 1074 1075 void 1076 Namespace::AddGenericType(const string& package, const string& name, int args) 1077 { 1078 Generic g; 1079 g.package = package; 1080 g.name = name; 1081 g.qualified = package + '.' + name; 1082 g.args = args; 1083 m_generics.push_back(g); 1084 } 1085 1086 Type* 1087 Namespace::Find(const string& name) const 1088 { 1089 int N = m_types.size(); 1090 for (int i=0; i<N; i++) { 1091 if (m_types[i]->QualifiedName() == name) { 1092 return m_types[i]; 1093 } 1094 } 1095 return NULL; 1096 } 1097 1098 Type* 1099 Namespace::Find(const char* package, const char* name) const 1100 { 1101 string s; 1102 if (package != NULL) { 1103 s += package; 1104 s += '.'; 1105 } 1106 s += name; 1107 return Find(s); 1108 } 1109 1110 static string 1111 normalize_generic(const string& s) 1112 { 1113 string r; 1114 int N = s.size(); 1115 for (int i=0; i<N; i++) { 1116 char c = s[i]; 1117 if (!isspace(c)) { 1118 r += c; 1119 } 1120 } 1121 return r; 1122 } 1123 1124 Type* 1125 Namespace::Search(const string& name) 1126 { 1127 // an exact match wins 1128 Type* result = Find(name); 1129 if (result != NULL) { 1130 return result; 1131 } 1132 1133 // try the class names 1134 // our language doesn't allow you to not specify outer classes 1135 // when referencing an inner class. that could be changed, and this 1136 // would be the place to do it, but I don't think the complexity in 1137 // scoping rules is worth it. 1138 int N = m_types.size(); 1139 for (int i=0; i<N; i++) { 1140 if (m_types[i]->Name() == name) { 1141 return m_types[i]; 1142 } 1143 } 1144 1145 // we got to here and it's not a generic, give up 1146 if (name.find('<') == name.npos) { 1147 return NULL; 1148 } 1149 1150 // remove any whitespace 1151 string normalized = normalize_generic(name); 1152 1153 // find the part before the '<', find a generic for it 1154 ssize_t baseIndex = normalized.find('<'); 1155 string base(normalized.c_str(), baseIndex); 1156 const Generic* g = search_generic(base); 1157 if (g == NULL) { 1158 return NULL; 1159 } 1160 1161 // For each of the args, do a recursive search on it. We don't allow 1162 // generics within generics like Java does, because we're really limiting 1163 // them to just built-in container classes, at least for now. Our syntax 1164 // ensures this right now as well. 1165 vector<Type*> args; 1166 size_t start = baseIndex + 1; 1167 size_t end = start; 1168 while (normalized[start] != '\0') { 1169 end = normalized.find(',', start); 1170 if (end == normalized.npos) { 1171 end = normalized.find('>', start); 1172 } 1173 string s(normalized.c_str()+start, end-start); 1174 Type* t = this->Search(s); 1175 if (t == NULL) { 1176 // maybe we should print a warning here? 1177 return NULL; 1178 } 1179 args.push_back(t); 1180 start = end+1; 1181 } 1182 1183 // construct a GenericType, add it to our name set so they always get 1184 // the same object, and return it. 1185 result = make_generic_type(g->package, g->name, args); 1186 if (result == NULL) { 1187 return NULL; 1188 } 1189 1190 this->Add(result); 1191 return this->Find(result->QualifiedName()); 1192 } 1193 1194 const Namespace::Generic* 1195 Namespace::search_generic(const string& name) const 1196 { 1197 int N = m_generics.size(); 1198 1199 // first exact match 1200 for (int i=0; i<N; i++) { 1201 const Generic& g = m_generics[i]; 1202 if (g.qualified == name) { 1203 return &g; 1204 } 1205 } 1206 1207 // then name match 1208 for (int i=0; i<N; i++) { 1209 const Generic& g = m_generics[i]; 1210 if (g.name == name) { 1211 return &g; 1212 } 1213 } 1214 1215 return NULL; 1216 } 1217 1218 void 1219 Namespace::Dump() const 1220 { 1221 int n = m_types.size(); 1222 for (int i=0; i<n; i++) { 1223 Type* t = m_types[i]; 1224 printf("type: package=%s name=%s qualifiedName=%s\n", 1225 t->Package().c_str(), t->Name().c_str(), 1226 t->QualifiedName().c_str()); 1227 } 1228 } 1229