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