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