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