1#include "Type.h" 2 3Namespace NAMES; 4 5Type* VOID_TYPE; 6Type* BOOLEAN_TYPE; 7Type* BYTE_TYPE; 8Type* CHAR_TYPE; 9Type* INT_TYPE; 10Type* LONG_TYPE; 11Type* FLOAT_TYPE; 12Type* DOUBLE_TYPE; 13Type* STRING_TYPE; 14Type* CHAR_SEQUENCE_TYPE; 15Type* TEXT_UTILS_TYPE; 16Type* REMOTE_EXCEPTION_TYPE; 17Type* RUNTIME_EXCEPTION_TYPE; 18Type* IBINDER_TYPE; 19Type* IINTERFACE_TYPE; 20Type* BINDER_NATIVE_TYPE; 21Type* BINDER_PROXY_TYPE; 22Type* PARCEL_TYPE; 23Type* PARCELABLE_INTERFACE_TYPE; 24Type* MAP_TYPE; 25Type* LIST_TYPE; 26Type* CLASSLOADER_TYPE; 27 28Expression* NULL_VALUE; 29Expression* THIS_VALUE; 30Expression* SUPER_VALUE; 31Expression* TRUE_VALUE; 32Expression* FALSE_VALUE; 33 34void 35register_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 119static Type* 120make_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 132Type::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 144Type::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 162Type::~Type() 163{ 164} 165 166bool 167Type::CanBeArray() const 168{ 169 return false; 170} 171 172string 173Type::ImportType() const 174{ 175 return m_qualifiedName; 176} 177 178string 179Type::CreatorName() const 180{ 181 return ""; 182} 183 184string 185Type::InstantiableName() const 186{ 187 return QualifiedName(); 188} 189 190 191void 192Type::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 200void 201Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 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 209void 210Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 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 218void 219Type::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 227void 228Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 229 Variable* parcel) 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 237void 238Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 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 246void 247Type::SetQualifiedName(const string& qualified) 248{ 249 m_qualifiedName = qualified; 250} 251 252Expression* 253Type::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 267BasicType::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 280void 281BasicType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 282{ 283 addTo->Add(new MethodCall(parcel, m_marshallMethod, 1, v)); 284} 285 286void 287BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 288{ 289 addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallMethod))); 290} 291 292bool 293BasicType::CanBeArray() const 294{ 295 return true; 296} 297 298void 299BasicType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 300{ 301 addTo->Add(new MethodCall(parcel, m_writeArrayMethod, 1, v)); 302} 303 304void 305BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 306 Variable* parcel) 307{ 308 addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayMethod))); 309} 310 311void 312BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 313{ 314 addTo->Add(new MethodCall(parcel, m_readArrayMethod, 1, v)); 315} 316 317 318// ================================================================ 319 320BooleanType::BooleanType() 321 :Type("boolean", BUILT_IN, true, false) 322{ 323} 324 325void 326BooleanType::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 333void 334BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 335{ 336 addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"), 337 "!=", new MethodCall(parcel, "readInt")))); 338} 339 340bool 341BooleanType::CanBeArray() const 342{ 343 return true; 344} 345 346void 347BooleanType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 348{ 349 addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v)); 350} 351 352void 353BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 354 Variable* parcel) 355{ 356 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray"))); 357} 358 359void 360BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 361{ 362 addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v)); 363} 364 365 366// ================================================================ 367 368CharType::CharType() 369 :Type("char", BUILT_IN, true, false) 370{ 371} 372 373void 374CharType::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 380void 381CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 382{ 383 addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this)); 384} 385 386bool 387CharType::CanBeArray() const 388{ 389 return true; 390} 391 392void 393CharType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 394{ 395 addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v)); 396} 397 398void 399CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 400 Variable* parcel) 401{ 402 addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray"))); 403} 404 405void 406CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 407{ 408 addTo->Add(new MethodCall(parcel, "readCharArray", 1, v)); 409} 410 411// ================================================================ 412 413StringType::StringType() 414 :Type("java.lang", "String", BUILT_IN, true, false) 415{ 416} 417 418string 419StringType::CreatorName() const 420{ 421 return "android.os.Parcel.STRING_CREATOR"; 422} 423 424void 425StringType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 426{ 427 addTo->Add(new MethodCall(parcel, "writeString", 1, v)); 428} 429 430void 431StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 432{ 433 addTo->Add(new Assignment(v, new MethodCall(parcel, "readString"))); 434} 435 436bool 437StringType::CanBeArray() const 438{ 439 return true; 440} 441 442void 443StringType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 444{ 445 addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v)); 446} 447 448void 449StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 450 Variable* parcel) 451{ 452 addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray"))); 453} 454 455void 456StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 457{ 458 addTo->Add(new MethodCall(parcel, "readStringArray", 1, v)); 459} 460 461// ================================================================ 462 463CharSequenceType::CharSequenceType() 464 :Type("java.lang", "CharSequence", BUILT_IN, true, false) 465{ 466} 467 468string 469CharSequenceType::CreatorName() const 470{ 471 return "android.os.Parcel.STRING_CREATOR"; 472} 473 474void 475CharSequenceType::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 497void 498CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v, 499 Variable* parcel) 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 523RemoteExceptionType::RemoteExceptionType() 524 :Type("android.os", "RemoteException", BUILT_IN, false, false) 525{ 526} 527 528void 529RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 530{ 531 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 532} 533 534void 535RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 536{ 537 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 538} 539 540// ================================================================ 541 542RuntimeExceptionType::RuntimeExceptionType() 543 :Type("java.lang", "RuntimeException", BUILT_IN, false, false) 544{ 545} 546 547void 548RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 549{ 550 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 551} 552 553void 554RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 555{ 556 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 557} 558 559 560// ================================================================ 561 562IBinderType::IBinderType() 563 :Type("android.os", "IBinder", BUILT_IN, true, false) 564{ 565} 566 567void 568IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 569{ 570 addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v)); 571} 572 573void 574IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 575{ 576 addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder"))); 577} 578 579void 580IBinderType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 581{ 582 addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v)); 583} 584 585void 586IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 587 Variable* parcel) 588{ 589 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray"))); 590} 591 592void 593IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 594{ 595 addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v)); 596} 597 598 599// ================================================================ 600 601IInterfaceType::IInterfaceType() 602 :Type("android.os", "IInterface", BUILT_IN, false, false) 603{ 604} 605 606void 607IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 608{ 609 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 610} 611 612void 613IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 614{ 615 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 616} 617 618 619// ================================================================ 620 621BinderType::BinderType() 622 :Type("android.os", "Binder", BUILT_IN, false, false) 623{ 624} 625 626void 627BinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 628{ 629 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 630} 631 632void 633BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, 634 Variable* parcel) 635{ 636 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 637} 638 639 640// ================================================================ 641 642BinderProxyType::BinderProxyType() 643 :Type("android.os", "BinderProxy", BUILT_IN, false, false) 644{ 645} 646 647void 648BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 649{ 650 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 651} 652 653void 654BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v, 655 Variable* parcel) 656{ 657 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 658} 659 660 661// ================================================================ 662 663ParcelType::ParcelType() 664 :Type("android.os", "Parcel", BUILT_IN, false, false) 665{ 666} 667 668void 669ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 670{ 671 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 672} 673 674void 675ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 676{ 677 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 678} 679 680// ================================================================ 681 682ParcelableInterfaceType::ParcelableInterfaceType() 683 :Type("android.os", "Parcelable", BUILT_IN, false, false) 684{ 685} 686 687void 688ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 689{ 690 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 691} 692 693void 694ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 695{ 696 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); 697} 698 699// ================================================================ 700 701MapType::MapType() 702 :Type("java.util", "Map", BUILT_IN, true, true) 703{ 704} 705 706void 707MapType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 708{ 709 addTo->Add(new MethodCall(parcel, "writeMap", 1, v)); 710} 711 712void 713MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 714{ 715 Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); 716 addTo->Add(new VariableDeclaration(cl, 717 new LiteralExpression("this.getClass().getClassLoader()"), 718 CLASSLOADER_TYPE)); 719 addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, cl))); 720} 721 722void 723MapType::ReadFromParcel(StatementBlock* addTo, Variable* v, 724 Variable* parcel) 725{ 726 Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); 727 addTo->Add(new VariableDeclaration(cl, 728 new LiteralExpression("this.getClass().getClassLoader()"), 729 CLASSLOADER_TYPE)); 730 addTo->Add(new MethodCall(parcel, "readMap", 2, v, cl)); 731} 732 733 734// ================================================================ 735 736ListType::ListType() 737 :Type("java.util", "List", BUILT_IN, true, true) 738{ 739} 740 741string 742ListType::InstantiableName() const 743{ 744 return "java.util.ArrayList"; 745} 746 747void 748ListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 749{ 750 addTo->Add(new MethodCall(parcel, "writeList", 1, v)); 751} 752 753void 754ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 755{ 756 Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); 757 addTo->Add(new VariableDeclaration(cl, 758 new LiteralExpression("this.getClass().getClassLoader()"), 759 CLASSLOADER_TYPE)); 760 addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, cl))); 761} 762 763void 764ListType::ReadFromParcel(StatementBlock* addTo, Variable* v, 765 Variable* parcel) 766{ 767 Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); 768 addTo->Add(new VariableDeclaration(cl, 769 new LiteralExpression("this.getClass().getClassLoader()"), 770 CLASSLOADER_TYPE)); 771 addTo->Add(new MethodCall(parcel, "readList", 2, v, cl)); 772} 773 774 775// ================================================================ 776 777ParcelableType::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 784string 785ParcelableType::CreatorName() const 786{ 787 return QualifiedName() + ".CREATOR"; 788} 789 790void 791ParcelableType::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 813void 814ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 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 834void 835ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v, 836 Variable* parcel) 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 850bool 851ParcelableType::CanBeArray() const 852{ 853 return true; 854} 855 856void 857ParcelableType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 858{ 859 addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v, 860 BuildWriteToParcelFlags(flags))); 861} 862 863void 864ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 865 Variable* parcel) 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 872void 873ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 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 883InterfaceType::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 892bool 893InterfaceType::OneWay() const 894{ 895 return m_oneway; 896} 897 898void 899InterfaceType::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 909void 910InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 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 923GenericType::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 945string 946GenericType::GenericArguments() const 947{ 948 return m_genericArguments; 949} 950 951string 952GenericType::ImportType() const 953{ 954 return m_importName; 955} 956 957void 958GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 959{ 960 fprintf(stderr, "implement GenericType::WriteToParcel\n"); 961} 962 963void 964GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 965{ 966 fprintf(stderr, "implement GenericType::CreateFromParcel\n"); 967} 968 969void 970GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v, 971 Variable* parcel) 972{ 973 fprintf(stderr, "implement GenericType::ReadFromParcel\n"); 974} 975 976 977// ================================================================ 978 979GenericListType::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 986string 987GenericListType::CreatorName() const 988{ 989 return "android.os.Parcel.arrayListCreator"; 990} 991 992string 993GenericListType::InstantiableName() const 994{ 995 return "java.util.ArrayList" + GenericArguments(); 996} 997 998void 999GenericListType::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 1011void 1012GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) 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 1028void 1029GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v, 1030 Variable* parcel) 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 1046ClassLoaderType::ClassLoaderType() 1047 :Type("java.lang", "ClassLoader", BUILT_IN, false, false) 1048{ 1049} 1050 1051 1052// ================================================================ 1053 1054Namespace::Namespace() 1055{ 1056} 1057 1058Namespace::~Namespace() 1059{ 1060 int N = m_types.size(); 1061 for (int i=0; i<N; i++) { 1062 delete m_types[i]; 1063 } 1064} 1065 1066void 1067Namespace::Add(Type* type) 1068{ 1069 Type* t = Find(type->QualifiedName()); 1070 if (t == NULL) { 1071 m_types.push_back(type); 1072 } 1073} 1074 1075void 1076Namespace::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 1086Type* 1087Namespace::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 1098Type* 1099Namespace::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 1110static string 1111normalize_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 1124Type* 1125Namespace::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 1194const Namespace::Generic* 1195Namespace::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 1218void 1219Namespace::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