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