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