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