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