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