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