Home | History | Annotate | Download | only in aidl
      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