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