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