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