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