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