Type.cpp revision e24dbeafe64278408b3342fcb77756bc7d091791
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 ParcelableType("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 899ParcelableType::ParcelableType(const string& package, const string& name, 900 bool builtIn, const string& declFile, int declLine) 901 :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, false, true, 902 declFile, declLine) 903{ 904} 905 906string 907ParcelableType::CreatorName() const 908{ 909 return QualifiedName() + ".CREATOR"; 910} 911 912void 913ParcelableType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 914{ 915 // if (v != null) { 916 // parcel.writeInt(1); 917 // v.writeToParcel(parcel); 918 // } else { 919 // parcel.writeInt(0); 920 // } 921 IfStatement* elsepart = new IfStatement(); 922 elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1, 923 new LiteralExpression("0"))); 924 IfStatement* ifpart = new IfStatement; 925 ifpart->expression = new Comparison(v, "!=", NULL_VALUE); 926 ifpart->elseif = elsepart; 927 ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1, 928 new LiteralExpression("1"))); 929 ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2, 930 parcel, BuildWriteToParcelFlags(flags))); 931 932 addTo->Add(ifpart); 933} 934 935void 936ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 937{ 938 // if (0 != parcel.readInt()) { 939 // v = CLASS.CREATOR.createFromParcel(parcel) 940 // } else { 941 // v = null; 942 // } 943 IfStatement* elsepart = new IfStatement(); 944 elsepart->statements->Add(new Assignment(v, NULL_VALUE)); 945 946 IfStatement* ifpart = new IfStatement(); 947 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", 948 new MethodCall(parcel, "readInt")); 949 ifpart->elseif = elsepart; 950 ifpart->statements->Add(new Assignment(v, 951 new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel))); 952 953 addTo->Add(ifpart); 954} 955 956void 957ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v, 958 Variable* parcel, Variable**) 959{ 960 // TODO: really, we don't need to have this extra check, but we 961 // don't have two separate marshalling code paths 962 // if (0 != parcel.readInt()) { 963 // v.readFromParcel(parcel) 964 // } 965 IfStatement* ifpart = new IfStatement(); 966 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", 967 new MethodCall(parcel, "readInt")); 968 ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel)); 969 addTo->Add(ifpart); 970} 971 972bool 973ParcelableType::CanBeArray() const 974{ 975 return true; 976} 977 978void 979ParcelableType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 980{ 981 addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v, 982 BuildWriteToParcelFlags(flags))); 983} 984 985void 986ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, 987 Variable* parcel, Variable**) 988{ 989 string creator = v->type->QualifiedName() + ".CREATOR"; 990 addTo->Add(new Assignment(v, new MethodCall(parcel, 991 "createTypedArray", 1, new LiteralExpression(creator)))); 992} 993 994void 995ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 996{ 997 string creator = v->type->QualifiedName() + ".CREATOR"; 998 addTo->Add(new MethodCall(parcel, "readTypedArray", 2, 999 v, new LiteralExpression(creator))); 1000} 1001 1002// ================================================================ 1003 1004FlattenableType::FlattenableType(const string& package, const string& name, 1005 bool builtIn, const string& declFile, int declLine) 1006 :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, false, true, true, 1007 declFile, declLine) 1008{ 1009} 1010 1011string 1012FlattenableType::CreatorName() const 1013{ 1014 return QualifiedName() + ".CREATOR"; 1015} 1016 1017void 1018FlattenableType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v, 1019 Variable* data, int flags) 1020{ 1021 // if (v != null) { 1022 // RpcData _obj = new RpcData(); 1023 // v.writeToRpcData(_obj); 1024 // data.putRpcData(k, obj); 1025 // } 1026 IfStatement* ifpart = new IfStatement; 1027 ifpart->expression = new Comparison(v, "!=", NULL_VALUE); 1028 Variable* _obj = new Variable(RPC_DATA_TYPE, "_obj"); 1029 ifpart->statements->Add(new VariableDeclaration(_obj, new NewExpression(RPC_DATA_TYPE))); 1030 ifpart->statements->Add(new MethodCall(v, "writeToRpcData", 1, _obj)); 1031 ifpart->statements->Add(new MethodCall(data, "putRpcData", 2, k, _obj)); 1032 1033 addTo->Add(ifpart); 1034} 1035 1036void 1037FlattenableType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, 1038 Variable* data, Variable** cl) 1039{ 1040 // RpcData _obj_XX = data.getRpcData(k); 1041 // if (_data_XX != null) 1042 // v = CLASS.RPC_CREATOR.createFromParcel(parcel) 1043 // } else { 1044 // v = null; 1045 // } 1046 1047 StatementBlock* block = new StatementBlock; 1048 addTo->Add(block); 1049 1050 Variable* _obj = new Variable(RPC_DATA_TYPE, "_obj"); 1051 block->Add(new VariableDeclaration(_obj, new MethodCall(data, "getRpcData", 1, k))); 1052 1053 IfStatement* ifpart = new IfStatement(); 1054 ifpart->expression = new Comparison(_obj, "!=", NULL_VALUE); 1055 ifpart->statements->Add(new Assignment(v, 1056 new MethodCall(v->type, "RPC_CREATOR.createFromRpcData", 1, data))); 1057 1058 IfStatement* elsepart = new IfStatement(); 1059 ifpart->elseif = elsepart; 1060 elsepart->statements->Add(new Assignment(v, NULL_VALUE)); 1061 1062 block->Add(ifpart); 1063} 1064 1065bool 1066FlattenableType::CanBeArray() const 1067{ 1068 return true; 1069} 1070 1071// ================================================================ 1072 1073InterfaceType::InterfaceType(const string& package, const string& name, 1074 bool builtIn, bool oneway, 1075 const string& declFile, int declLine) 1076 :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, false, 1077 declFile, declLine) 1078 ,m_oneway(oneway) 1079{ 1080} 1081 1082bool 1083InterfaceType::OneWay() const 1084{ 1085 return m_oneway; 1086} 1087 1088void 1089InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 1090{ 1091 // parcel.writeStrongBinder(v != null ? v.asBinder() : null); 1092 addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, 1093 new Ternary( 1094 new Comparison(v, "!=", NULL_VALUE), 1095 new MethodCall(v, "asBinder"), 1096 NULL_VALUE))); 1097} 1098 1099void 1100InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 1101{ 1102 // v = Interface.asInterface(parcel.readStrongBinder()); 1103 string type = v->type->QualifiedName(); 1104 type += ".Stub"; 1105 addTo->Add(new Assignment(v, 1106 new MethodCall( NAMES.Find(type), "asInterface", 1, 1107 new MethodCall(parcel, "readStrongBinder")))); 1108} 1109 1110 1111// ================================================================ 1112 1113GenericType::GenericType(const string& package, const string& name, 1114 const vector<Type*>& args) 1115 :Type(package, name, BUILT_IN, true, true, true) 1116{ 1117 m_args = args; 1118 1119 m_importName = package + '.' + name; 1120 1121 string gen = "<"; 1122 int N = args.size(); 1123 for (int i=0; i<N; i++) { 1124 Type* t = args[i]; 1125 gen += t->QualifiedName(); 1126 if (i != N-1) { 1127 gen += ','; 1128 } 1129 } 1130 gen += '>'; 1131 m_genericArguments = gen; 1132 SetQualifiedName(m_importName + gen); 1133} 1134 1135const vector<Type*>& 1136GenericType::GenericArgumentTypes() const 1137{ 1138 return m_args; 1139} 1140 1141string 1142GenericType::GenericArguments() const 1143{ 1144 return m_genericArguments; 1145} 1146 1147string 1148GenericType::ImportType() const 1149{ 1150 return m_importName; 1151} 1152 1153void 1154GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 1155{ 1156 fprintf(stderr, "implement GenericType::WriteToParcel\n"); 1157} 1158 1159void 1160GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 1161{ 1162 fprintf(stderr, "implement GenericType::CreateFromParcel\n"); 1163} 1164 1165void 1166GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v, 1167 Variable* parcel, Variable**) 1168{ 1169 fprintf(stderr, "implement GenericType::ReadFromParcel\n"); 1170} 1171 1172 1173// ================================================================ 1174 1175GenericListType::GenericListType(const string& package, const string& name, 1176 const vector<Type*>& args) 1177 :GenericType(package, name, args), 1178 m_creator(args[0]->CreatorName()) 1179{ 1180} 1181 1182string 1183GenericListType::CreatorName() const 1184{ 1185 return "android.os.Parcel.arrayListCreator"; 1186} 1187 1188string 1189GenericListType::InstantiableName() const 1190{ 1191 return "java.util.ArrayList" + GenericArguments(); 1192} 1193 1194void 1195GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) 1196{ 1197 if (m_creator == STRING_TYPE->CreatorName()) { 1198 addTo->Add(new MethodCall(parcel, "writeStringList", 1, v)); 1199 } else if (m_creator == IBINDER_TYPE->CreatorName()) { 1200 addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v)); 1201 } else { 1202 // parcel.writeTypedListXX(arg); 1203 addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v)); 1204 } 1205} 1206 1207void 1208GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**) 1209{ 1210 if (m_creator == STRING_TYPE->CreatorName()) { 1211 addTo->Add(new Assignment(v, 1212 new MethodCall(parcel, "createStringArrayList", 0))); 1213 } else if (m_creator == IBINDER_TYPE->CreatorName()) { 1214 addTo->Add(new Assignment(v, 1215 new MethodCall(parcel, "createBinderArrayList", 0))); 1216 } else { 1217 // v = _data.readTypedArrayList(XXX.creator); 1218 addTo->Add(new Assignment(v, 1219 new MethodCall(parcel, "createTypedArrayList", 1, 1220 new LiteralExpression(m_creator)))); 1221 } 1222} 1223 1224void 1225GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v, 1226 Variable* parcel, Variable**) 1227{ 1228 if (m_creator == STRING_TYPE->CreatorName()) { 1229 addTo->Add(new MethodCall(parcel, "readStringList", 1, v)); 1230 } else if (m_creator == IBINDER_TYPE->CreatorName()) { 1231 addTo->Add(new MethodCall(parcel, "readBinderList", 1, v)); 1232 } else { 1233 // v = _data.readTypedList(v, XXX.creator); 1234 addTo->Add(new MethodCall(parcel, "readTypedList", 2, 1235 v, 1236 new LiteralExpression(m_creator))); 1237 } 1238} 1239 1240void 1241GenericListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v, 1242 Variable* data, int flags) 1243{ 1244 addTo->Add(new MethodCall(data, "putList", 2, k, v)); 1245} 1246 1247void 1248GenericListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, 1249 Variable* data, Variable** cl) 1250{ 1251 string classArg = GenericArgumentTypes()[0]->QualifiedName(); 1252 classArg += ".class"; 1253 addTo->Add(new Assignment(v, new MethodCall(data, "getList", 2, k, 1254 new LiteralExpression(classArg)))); 1255} 1256 1257 1258// ================================================================ 1259 1260RpcDataType::RpcDataType() 1261 :Type("com.android.athome.rpc", "RpcData", Type::BUILT_IN, false, true, true) 1262{ 1263} 1264 1265void 1266RpcDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v, 1267 Variable* data, int flags) 1268{ 1269 addTo->Add(new MethodCall(data, "putRpcData", 2, k, v)); 1270} 1271 1272void 1273RpcDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data, 1274 Variable** cl) 1275{ 1276 addTo->Add(new Assignment(v, new MethodCall(data, "getRpcData", 1, k))); 1277} 1278 1279 1280// ================================================================ 1281 1282ClassLoaderType::ClassLoaderType() 1283 :Type("java.lang", "ClassLoader", BUILT_IN, false, false, false) 1284{ 1285} 1286 1287 1288// ================================================================ 1289 1290Namespace::Namespace() 1291{ 1292} 1293 1294Namespace::~Namespace() 1295{ 1296 int N = m_types.size(); 1297 for (int i=0; i<N; i++) { 1298 delete m_types[i]; 1299 } 1300} 1301 1302void 1303Namespace::Add(Type* type) 1304{ 1305 Type* t = Find(type->QualifiedName()); 1306 if (t == NULL) { 1307 m_types.push_back(type); 1308 } 1309} 1310 1311void 1312Namespace::AddGenericType(const string& package, const string& name, int args) 1313{ 1314 Generic g; 1315 g.package = package; 1316 g.name = name; 1317 g.qualified = package + '.' + name; 1318 g.args = args; 1319 m_generics.push_back(g); 1320} 1321 1322Type* 1323Namespace::Find(const string& name) const 1324{ 1325 int N = m_types.size(); 1326 for (int i=0; i<N; i++) { 1327 if (m_types[i]->QualifiedName() == name) { 1328 return m_types[i]; 1329 } 1330 } 1331 return NULL; 1332} 1333 1334Type* 1335Namespace::Find(const char* package, const char* name) const 1336{ 1337 string s; 1338 if (package != NULL) { 1339 s += package; 1340 s += '.'; 1341 } 1342 s += name; 1343 return Find(s); 1344} 1345 1346static string 1347normalize_generic(const string& s) 1348{ 1349 string r; 1350 int N = s.size(); 1351 for (int i=0; i<N; i++) { 1352 char c = s[i]; 1353 if (!isspace(c)) { 1354 r += c; 1355 } 1356 } 1357 return r; 1358} 1359 1360Type* 1361Namespace::Search(const string& name) 1362{ 1363 // an exact match wins 1364 Type* result = Find(name); 1365 if (result != NULL) { 1366 return result; 1367 } 1368 1369 // try the class names 1370 // our language doesn't allow you to not specify outer classes 1371 // when referencing an inner class. that could be changed, and this 1372 // would be the place to do it, but I don't think the complexity in 1373 // scoping rules is worth it. 1374 int N = m_types.size(); 1375 for (int i=0; i<N; i++) { 1376 if (m_types[i]->Name() == name) { 1377 return m_types[i]; 1378 } 1379 } 1380 1381 // we got to here and it's not a generic, give up 1382 if (name.find('<') == name.npos) { 1383 return NULL; 1384 } 1385 1386 // remove any whitespace 1387 string normalized = normalize_generic(name); 1388 1389 // find the part before the '<', find a generic for it 1390 ssize_t baseIndex = normalized.find('<'); 1391 string base(normalized.c_str(), baseIndex); 1392 const Generic* g = search_generic(base); 1393 if (g == NULL) { 1394 return NULL; 1395 } 1396 1397 // For each of the args, do a recursive search on it. We don't allow 1398 // generics within generics like Java does, because we're really limiting 1399 // them to just built-in container classes, at least for now. Our syntax 1400 // ensures this right now as well. 1401 vector<Type*> args; 1402 size_t start = baseIndex + 1; 1403 size_t end = start; 1404 while (normalized[start] != '\0') { 1405 end = normalized.find(',', start); 1406 if (end == normalized.npos) { 1407 end = normalized.find('>', start); 1408 } 1409 string s(normalized.c_str()+start, end-start); 1410 Type* t = this->Search(s); 1411 if (t == NULL) { 1412 // maybe we should print a warning here? 1413 return NULL; 1414 } 1415 args.push_back(t); 1416 start = end+1; 1417 } 1418 1419 // construct a GenericType, add it to our name set so they always get 1420 // the same object, and return it. 1421 result = make_generic_type(g->package, g->name, args); 1422 if (result == NULL) { 1423 return NULL; 1424 } 1425 1426 this->Add(result); 1427 return this->Find(result->QualifiedName()); 1428} 1429 1430const Namespace::Generic* 1431Namespace::search_generic(const string& name) const 1432{ 1433 int N = m_generics.size(); 1434 1435 // first exact match 1436 for (int i=0; i<N; i++) { 1437 const Generic& g = m_generics[i]; 1438 if (g.qualified == name) { 1439 return &g; 1440 } 1441 } 1442 1443 // then name match 1444 for (int i=0; i<N; i++) { 1445 const Generic& g = m_generics[i]; 1446 if (g.name == name) { 1447 return &g; 1448 } 1449 } 1450 1451 return NULL; 1452} 1453 1454void 1455Namespace::Dump() const 1456{ 1457 int n = m_types.size(); 1458 for (int i=0; i<n; i++) { 1459 Type* t = m_types[i]; 1460 printf("type: package=%s name=%s qualifiedName=%s\n", 1461 t->Package().c_str(), t->Name().c_str(), 1462 t->QualifiedName().c_str()); 1463 } 1464} 1465