blob: 6b69864b7adddc71f64300d99eaacc233af7f354 [file] [log] [blame]
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001#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* CHAR_SEQUENCE_TYPE;
15Type* TEXT_UTILS_TYPE;
16Type* REMOTE_EXCEPTION_TYPE;
17Type* RUNTIME_EXCEPTION_TYPE;
18Type* IBINDER_TYPE;
19Type* IINTERFACE_TYPE;
20Type* BINDER_NATIVE_TYPE;
21Type* BINDER_PROXY_TYPE;
22Type* PARCEL_TYPE;
23Type* PARCELABLE_INTERFACE_TYPE;
24Type* MAP_TYPE;
25Type* LIST_TYPE;
26Type* CLASSLOADER_TYPE;
27
28Expression* NULL_VALUE;
29Expression* THIS_VALUE;
30Expression* SUPER_VALUE;
31Expression* TRUE_VALUE;
32Expression* FALSE_VALUE;
33
34void
35register_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
119static Type*
120make_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
132Type::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
144Type::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
162Type::~Type()
163{
164}
165
166bool
167Type::CanBeArray() const
168{
169 return false;
170}
171
172string
173Type::ImportType() const
174{
175 return m_qualifiedName;
176}
177
178string
179Type::CreatorName() const
180{
181 return "";
182}
183
184string
185Type::InstantiableName() const
186{
187 return QualifiedName();
188}
189
190
191void
192Type::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
200void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700201Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700202{
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
209void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700210Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700211{
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
218void
219Type::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
227void
228Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700229 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700230{
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
237void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700238Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700239{
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
246void
247Type::SetQualifiedName(const string& qualified)
248{
249 m_qualifiedName = qualified;
250}
251
252Expression*
253Type::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
267BasicType::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
280void
281BasicType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
282{
283 addTo->Add(new MethodCall(parcel, m_marshallMethod, 1, v));
284}
285
286void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700287BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700288{
289 addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallMethod)));
290}
291
292bool
293BasicType::CanBeArray() const
294{
295 return true;
296}
297
298void
299BasicType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
300{
301 addTo->Add(new MethodCall(parcel, m_writeArrayMethod, 1, v));
302}
303
304void
305BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700306 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700307{
308 addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayMethod)));
309}
310
311void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700312BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700313{
314 addTo->Add(new MethodCall(parcel, m_readArrayMethod, 1, v));
315}
316
317
318// ================================================================
319
320BooleanType::BooleanType()
321 :Type("boolean", BUILT_IN, true, false)
322{
323}
324
325void
326BooleanType::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
333void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700334BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700335{
336 addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"),
337 "!=", new MethodCall(parcel, "readInt"))));
338}
339
340bool
341BooleanType::CanBeArray() const
342{
343 return true;
344}
345
346void
347BooleanType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
348{
349 addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
350}
351
352void
353BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700354 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700355{
356 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
357}
358
359void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700360BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700361{
362 addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
363}
364
365
366// ================================================================
367
368CharType::CharType()
369 :Type("char", BUILT_IN, true, false)
370{
371}
372
373void
374CharType::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
380void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700381CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700382{
383 addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
384}
385
386bool
387CharType::CanBeArray() const
388{
389 return true;
390}
391
392void
393CharType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
394{
395 addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
396}
397
398void
399CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700400 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700401{
402 addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
403}
404
405void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700406CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700407{
408 addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
409}
410
411// ================================================================
412
413StringType::StringType()
414 :Type("java.lang", "String", BUILT_IN, true, false)
415{
416}
417
418string
419StringType::CreatorName() const
420{
421 return "android.os.Parcel.STRING_CREATOR";
422}
423
424void
425StringType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
426{
427 addTo->Add(new MethodCall(parcel, "writeString", 1, v));
428}
429
430void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700431StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700432{
433 addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
434}
435
436bool
437StringType::CanBeArray() const
438{
439 return true;
440}
441
442void
443StringType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
444{
445 addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
446}
447
448void
449StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700450 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700451{
452 addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
453}
454
455void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700456StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700457{
458 addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
459}
460
461// ================================================================
462
463CharSequenceType::CharSequenceType()
464 :Type("java.lang", "CharSequence", BUILT_IN, true, false)
465{
466}
467
468string
469CharSequenceType::CreatorName() const
470{
471 return "android.os.Parcel.STRING_CREATOR";
472}
473
474void
475CharSequenceType::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
497void
498CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700499 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700500{
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
523RemoteExceptionType::RemoteExceptionType()
524 :Type("android.os", "RemoteException", BUILT_IN, false, false)
525{
526}
527
528void
529RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
530{
531 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
532}
533
534void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700535RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700536{
537 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
538}
539
540// ================================================================
541
542RuntimeExceptionType::RuntimeExceptionType()
543 :Type("java.lang", "RuntimeException", BUILT_IN, false, false)
544{
545}
546
547void
548RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
549{
550 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
551}
552
553void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700554RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700555{
556 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
557}
558
559
560// ================================================================
561
562IBinderType::IBinderType()
563 :Type("android.os", "IBinder", BUILT_IN, true, false)
564{
565}
566
567void
568IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
569{
570 addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
571}
572
573void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700574IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700575{
576 addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
577}
578
579void
580IBinderType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
581{
582 addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
583}
584
585void
586IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700587 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700588{
589 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
590}
591
592void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700593IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700594{
595 addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
596}
597
598
599// ================================================================
600
601IInterfaceType::IInterfaceType()
602 :Type("android.os", "IInterface", BUILT_IN, false, false)
603{
604}
605
606void
607IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
608{
609 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
610}
611
612void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700613IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700614{
615 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
616}
617
618
619// ================================================================
620
621BinderType::BinderType()
622 :Type("android.os", "Binder", BUILT_IN, false, false)
623{
624}
625
626void
627BinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
628{
629 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
630}
631
632void
633BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700634 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700635{
636 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
637}
638
639
640// ================================================================
641
642BinderProxyType::BinderProxyType()
643 :Type("android.os", "BinderProxy", BUILT_IN, false, false)
644{
645}
646
647void
648BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
649{
650 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
651}
652
653void
654BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700655 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700656{
657 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
658}
659
660
661// ================================================================
662
663ParcelType::ParcelType()
664 :Type("android.os", "Parcel", BUILT_IN, false, false)
665{
666}
667
668void
669ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
670{
671 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
672}
673
674void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700675ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700676{
677 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
678}
679
680// ================================================================
681
682ParcelableInterfaceType::ParcelableInterfaceType()
683 :Type("android.os", "Parcelable", BUILT_IN, false, false)
684{
685}
686
687void
688ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
689{
690 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
691}
692
693void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700694ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700695{
696 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
697}
698
699// ================================================================
700
701MapType::MapType()
702 :Type("java.util", "Map", BUILT_IN, true, true)
703{
704}
705
706void
707MapType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
708{
709 addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
710}
711
Elliott Hughes15f8da22011-07-13 12:10:30 -0700712static void EnsureClassLoader(StatementBlock* addTo, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700713{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700714 // 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
724void
725MapType::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)));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700729}
730
731void
732MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700733 Variable* parcel, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700734{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700735 EnsureClassLoader(addTo, cl);
736 addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700737}
738
739
740// ================================================================
741
742ListType::ListType()
743 :Type("java.util", "List", BUILT_IN, true, true)
744{
745}
746
747string
748ListType::InstantiableName() const
749{
750 return "java.util.ArrayList";
751}
752
753void
754ListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
755{
756 addTo->Add(new MethodCall(parcel, "writeList", 1, v));
757}
758
759void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700760ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700761{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700762 EnsureClassLoader(addTo, cl);
763 addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700764}
765
766void
767ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700768 Variable* parcel, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700769{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700770 EnsureClassLoader(addTo, cl);
771 addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700772}
773
774
775// ================================================================
776
777ParcelableType::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
784string
785ParcelableType::CreatorName() const
786{
787 return QualifiedName() + ".CREATOR";
788}
789
790void
791ParcelableType::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
813void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700814ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700815{
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
834void
835ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700836 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700837{
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
850bool
851ParcelableType::CanBeArray() const
852{
853 return true;
854}
855
856void
857ParcelableType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
858{
859 addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
860 BuildWriteToParcelFlags(flags)));
861}
862
863void
864ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700865 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700866{
867 string creator = v->type->QualifiedName() + ".CREATOR";
868 addTo->Add(new Assignment(v, new MethodCall(parcel,
869 "createTypedArray", 1, new LiteralExpression(creator))));
870}
871
872void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700873ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700874{
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
883InterfaceType::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
892bool
893InterfaceType::OneWay() const
894{
895 return m_oneway;
896}
897
898void
899InterfaceType::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
909void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700910InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700911{
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
923GenericType::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
945string
946GenericType::GenericArguments() const
947{
948 return m_genericArguments;
949}
950
951string
952GenericType::ImportType() const
953{
954 return m_importName;
955}
956
957void
958GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
959{
960 fprintf(stderr, "implement GenericType::WriteToParcel\n");
961}
962
963void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700964GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700965{
966 fprintf(stderr, "implement GenericType::CreateFromParcel\n");
967}
968
969void
970GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700971 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700972{
973 fprintf(stderr, "implement GenericType::ReadFromParcel\n");
974}
975
976
977// ================================================================
978
979GenericListType::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
986string
987GenericListType::CreatorName() const
988{
989 return "android.os.Parcel.arrayListCreator";
990}
991
992string
993GenericListType::InstantiableName() const
994{
995 return "java.util.ArrayList" + GenericArguments();
996}
997
998void
999GenericListType::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
1011void
Elliott Hughes15f8da22011-07-13 12:10:30 -07001012GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001013{
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
1028void
1029GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -07001030 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001031{
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
1046ClassLoaderType::ClassLoaderType()
1047 :Type("java.lang", "ClassLoader", BUILT_IN, false, false)
1048{
1049}
1050
1051
1052// ================================================================
1053
1054Namespace::Namespace()
1055{
1056}
1057
1058Namespace::~Namespace()
1059{
1060 int N = m_types.size();
1061 for (int i=0; i<N; i++) {
1062 delete m_types[i];
1063 }
1064}
1065
1066void
1067Namespace::Add(Type* type)
1068{
1069 Type* t = Find(type->QualifiedName());
1070 if (t == NULL) {
1071 m_types.push_back(type);
1072 }
1073}
1074
1075void
1076Namespace::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
1086Type*
1087Namespace::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
1098Type*
1099Namespace::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
1110static string
1111normalize_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
1124Type*
1125Namespace::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
1194const Namespace::Generic*
1195Namespace::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
1218void
1219Namespace::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}