blob: 54690e72412ca9e7d231128e9acd278baf8a600d [file] [log] [blame]
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001#include "Type.h"
2
3Namespace NAMES;
4
5Type* VOID_TYPE;
6Type* BOOLEAN_TYPE;
7Type* BYTE_TYPE;
8Type* CHAR_TYPE;
9Type* INT_TYPE;
10Type* LONG_TYPE;
11Type* FLOAT_TYPE;
12Type* DOUBLE_TYPE;
13Type* STRING_TYPE;
Joe Onoratoc596cfe2011-08-30 17:24:17 -070014Type* OBJECT_TYPE;
The Android Open Source Project46c012c2008-10-21 07:00:00 -070015Type* CHAR_SEQUENCE_TYPE;
16Type* TEXT_UTILS_TYPE;
17Type* REMOTE_EXCEPTION_TYPE;
18Type* RUNTIME_EXCEPTION_TYPE;
19Type* IBINDER_TYPE;
20Type* IINTERFACE_TYPE;
21Type* BINDER_NATIVE_TYPE;
22Type* BINDER_PROXY_TYPE;
23Type* PARCEL_TYPE;
24Type* PARCELABLE_INTERFACE_TYPE;
Joe Onoratoc596cfe2011-08-30 17:24:17 -070025Type* CONTEXT_TYPE;
The Android Open Source Project46c012c2008-10-21 07:00:00 -070026Type* MAP_TYPE;
27Type* LIST_TYPE;
28Type* CLASSLOADER_TYPE;
Joe Onoratoc596cfe2011-08-30 17:24:17 -070029Type* RPC_SERVICE_BASE_TYPE;
30Type* RPC_DATA_TYPE;
31Type* RPC_BROKER_TYPE;
32Type* RPC_ENDPOINT_INFO_TYPE;
33Type* RPC_RESULT_HANDLER_TYPE;
34Type* RPC_ERROR_TYPE;
35Type* RPC_ERROR_LISTENER_TYPE;
The Android Open Source Project46c012c2008-10-21 07:00:00 -070036
37Expression* NULL_VALUE;
38Expression* THIS_VALUE;
39Expression* SUPER_VALUE;
40Expression* TRUE_VALUE;
41Expression* FALSE_VALUE;
42
43void
44register_base_types()
45{
46 VOID_TYPE = new BasicType("void", "XXX", "XXX", "XXX", "XXX", "XXX");
47 NAMES.Add(VOID_TYPE);
48
49 BOOLEAN_TYPE = new BooleanType();
50 NAMES.Add(BOOLEAN_TYPE);
51
52 BYTE_TYPE = new BasicType("byte", "writeByte", "readByte",
53 "writeByteArray", "createByteArray", "readByteArray");
54 NAMES.Add(BYTE_TYPE);
55
56 CHAR_TYPE = new CharType();
57 NAMES.Add(CHAR_TYPE);
58
59 INT_TYPE = new BasicType("int", "writeInt", "readInt",
60 "writeIntArray", "createIntArray", "readIntArray");
61 NAMES.Add(INT_TYPE);
62
63 LONG_TYPE = new BasicType("long", "writeLong", "readLong",
64 "writeLongArray", "createLongArray", "readLongArray");
65 NAMES.Add(LONG_TYPE);
66
67 FLOAT_TYPE = new BasicType("float", "writeFloat", "readFloat",
68 "writeFloatArray", "createFloatArray", "readFloatArray");
69 NAMES.Add(FLOAT_TYPE);
70
71 DOUBLE_TYPE = new BasicType("double", "writeDouble", "readDouble",
72 "writeDoubleArray", "createDoubleArray", "readDoubleArray");
73 NAMES.Add(DOUBLE_TYPE);
74
75 STRING_TYPE = new StringType();
76 NAMES.Add(STRING_TYPE);
77
Joe Onoratoc596cfe2011-08-30 17:24:17 -070078 OBJECT_TYPE = new Type("java.lang", "Object",
79 Type::BUILT_IN, false, false);
80 NAMES.Add(OBJECT_TYPE);
81
The Android Open Source Project46c012c2008-10-21 07:00:00 -070082 CHAR_SEQUENCE_TYPE = new CharSequenceType();
83 NAMES.Add(CHAR_SEQUENCE_TYPE);
84
85 MAP_TYPE = new MapType();
86 NAMES.Add(MAP_TYPE);
87
88 LIST_TYPE = new ListType();
89 NAMES.Add(LIST_TYPE);
90
91 TEXT_UTILS_TYPE = new Type("android.text", "TextUtils",
92 Type::BUILT_IN, false, false);
93 NAMES.Add(TEXT_UTILS_TYPE);
94
95 REMOTE_EXCEPTION_TYPE = new RemoteExceptionType();
96 NAMES.Add(REMOTE_EXCEPTION_TYPE);
97
98 RUNTIME_EXCEPTION_TYPE = new RuntimeExceptionType();
99 NAMES.Add(RUNTIME_EXCEPTION_TYPE);
100
101 IBINDER_TYPE = new IBinderType();
102 NAMES.Add(IBINDER_TYPE);
103
104 IINTERFACE_TYPE = new IInterfaceType();
105 NAMES.Add(IINTERFACE_TYPE);
106
107 BINDER_NATIVE_TYPE = new BinderType();
108 NAMES.Add(BINDER_NATIVE_TYPE);
109
110 BINDER_PROXY_TYPE = new BinderProxyType();
111 NAMES.Add(BINDER_PROXY_TYPE);
112
113 PARCEL_TYPE = new ParcelType();
114 NAMES.Add(PARCEL_TYPE);
115
116 PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType();
117 NAMES.Add(PARCELABLE_INTERFACE_TYPE);
118
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700119 CONTEXT_TYPE = new Type("android.content", "Context",
120 Type::BUILT_IN, false, false);
121 NAMES.Add(CONTEXT_TYPE);
122
123 RPC_SERVICE_BASE_TYPE = new Type("com.android.athome.service", "AndroidAtHomeService",
124 Type::BUILT_IN, false, false);
125 NAMES.Add(RPC_SERVICE_BASE_TYPE);
126
127 RPC_DATA_TYPE = new Type("com.android.athome.rpc", "RpcData",
128 Type::BUILT_IN, false, false);
129 NAMES.Add(RPC_DATA_TYPE);
130
131 RPC_BROKER_TYPE = new Type("com.android.athome.utils", "AndroidAtHomeBroker",
132 Type::BUILT_IN, false, false);
133 NAMES.Add(RPC_BROKER_TYPE);
134
135 RPC_ENDPOINT_INFO_TYPE = new ParcelableType("com.android.athome.rpc", "EndpointInfo",
136 true, __FILE__, __LINE__);
137 NAMES.Add(RPC_ENDPOINT_INFO_TYPE);
138
139 RPC_RESULT_HANDLER_TYPE = new ParcelableType("com.android.athome.rpc", "RpcResultHandler",
140 true, __FILE__, __LINE__);
141 NAMES.Add(RPC_RESULT_HANDLER_TYPE);
142
143 RPC_ERROR_TYPE = new ParcelableType("com.android.athome.rpc", "RpcError",
144 true, __FILE__, __LINE__);
145 NAMES.Add(RPC_ERROR_TYPE);
146
147 RPC_ERROR_LISTENER_TYPE = new Type("com.android.athome.rpc", "RpcErrorHandler",
148 Type::BUILT_IN, false, false);
149 NAMES.Add(RPC_ERROR_LISTENER_TYPE);
150
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700151 CLASSLOADER_TYPE = new ClassLoaderType();
152 NAMES.Add(CLASSLOADER_TYPE);
153
154 NULL_VALUE = new LiteralExpression("null");
155 THIS_VALUE = new LiteralExpression("this");
156 SUPER_VALUE = new LiteralExpression("super");
157 TRUE_VALUE = new LiteralExpression("true");
158 FALSE_VALUE = new LiteralExpression("false");
159
160 NAMES.AddGenericType("java.util", "List", 1);
161 NAMES.AddGenericType("java.util", "Map", 2);
162}
163
164static Type*
165make_generic_type(const string& package, const string& name,
166 const vector<Type*>& args)
167{
168 if (package == "java.util" && name == "List") {
169 return new GenericListType("java.util", "List", args);
170 }
171 return NULL;
172 //return new GenericType(package, name, args);
173}
174
175// ================================================================
176
177Type::Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut)
178 :m_package(),
179 m_name(name),
180 m_declFile(""),
181 m_declLine(-1),
182 m_kind(kind),
183 m_canWriteToParcel(canWriteToParcel),
184 m_canBeOut(canBeOut)
185{
186 m_qualifiedName = name;
187}
188
189Type::Type(const string& package, const string& name,
190 int kind, bool canWriteToParcel, bool canBeOut,
191 const string& declFile, int declLine)
192 :m_package(package),
193 m_name(name),
194 m_declFile(declFile),
195 m_declLine(declLine),
196 m_kind(kind),
197 m_canWriteToParcel(canWriteToParcel),
198 m_canBeOut(canBeOut)
199{
200 if (package.length() > 0) {
201 m_qualifiedName = package;
202 m_qualifiedName += '.';
203 }
204 m_qualifiedName += name;
205}
206
207Type::~Type()
208{
209}
210
211bool
212Type::CanBeArray() const
213{
214 return false;
215}
216
217string
218Type::ImportType() const
219{
220 return m_qualifiedName;
221}
222
223string
224Type::CreatorName() const
225{
226 return "";
227}
228
229string
230Type::InstantiableName() const
231{
232 return QualifiedName();
233}
234
235
236void
237Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
238{
239 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn",
240 __FILE__, __LINE__, m_qualifiedName.c_str());
241 addTo->Add(new LiteralExpression("/* WriteToParcel error "
242 + m_qualifiedName + " */"));
243}
244
245void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700246Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700247{
248 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
249 __FILE__, __LINE__, m_qualifiedName.c_str());
250 addTo->Add(new LiteralExpression("/* CreateFromParcel error "
251 + m_qualifiedName + " */"));
252}
253
254void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700255Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700256{
257 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
258 __FILE__, __LINE__, m_qualifiedName.c_str());
259 addTo->Add(new LiteralExpression("/* ReadFromParcel error "
260 + m_qualifiedName + " */"));
261}
262
263void
264Type::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
265{
266 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
267 __FILE__, __LINE__, m_qualifiedName.c_str());
268 addTo->Add(new LiteralExpression("/* WriteArrayToParcel error "
269 + m_qualifiedName + " */"));
270}
271
272void
273Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700274 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700275{
276 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
277 __FILE__, __LINE__, m_qualifiedName.c_str());
278 addTo->Add(new LiteralExpression("/* CreateArrayFromParcel error "
279 + m_qualifiedName + " */"));
280}
281
282void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700283Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700284{
285 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
286 __FILE__, __LINE__, m_qualifiedName.c_str());
287 addTo->Add(new LiteralExpression("/* ReadArrayFromParcel error "
288 + m_qualifiedName + " */"));
289}
290
291void
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700292Type::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
293 Variable* data, int flags)
294{
295 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn",
296 __FILE__, __LINE__, m_qualifiedName.c_str());
297 addTo->Add(new LiteralExpression("/* WriteToRpcData error "
298 + m_qualifiedName + " */"));
299}
300
301void
302Type::ReadFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
303 Variable** cl)
304{
305 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn",
306 __FILE__, __LINE__, m_qualifiedName.c_str());
307 addTo->Add(new LiteralExpression("/* ReadFromRpcData error "
308 + m_qualifiedName + " */"));
309}
310
311void
312Type::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
313 Variable** cl)
314{
315 fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn",
316 __FILE__, __LINE__, m_qualifiedName.c_str());
317 addTo->Add(new LiteralExpression("/* ReadFromRpcData error "
318 + m_qualifiedName + " */"));
319}
320
321void
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700322Type::SetQualifiedName(const string& qualified)
323{
324 m_qualifiedName = qualified;
325}
326
327Expression*
328Type::BuildWriteToParcelFlags(int flags)
329{
330 if (flags == 0) {
331 return new LiteralExpression("0");
332 }
333 if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0) {
334 return new FieldVariable(PARCELABLE_INTERFACE_TYPE,
335 "PARCELABLE_WRITE_RETURN_VALUE");
336 }
337 return new LiteralExpression("0");
338}
339
340// ================================================================
341
342BasicType::BasicType(const string& name, const string& marshallMethod,
343 const string& unmarshallMethod,
344 const string& writeArray, const string& createArray,
345 const string& readArray)
346 :Type(name, BUILT_IN, true, false),
347 m_marshallMethod(marshallMethod),
348 m_unmarshallMethod(unmarshallMethod),
349 m_writeArrayMethod(writeArray),
350 m_createArrayMethod(createArray),
351 m_readArrayMethod(readArray)
352{
353}
354
355void
356BasicType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
357{
358 addTo->Add(new MethodCall(parcel, m_marshallMethod, 1, v));
359}
360
361void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700362BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700363{
364 addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallMethod)));
365}
366
367bool
368BasicType::CanBeArray() const
369{
370 return true;
371}
372
373void
374BasicType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
375{
376 addTo->Add(new MethodCall(parcel, m_writeArrayMethod, 1, v));
377}
378
379void
380BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700381 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700382{
383 addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayMethod)));
384}
385
386void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700387BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700388{
389 addTo->Add(new MethodCall(parcel, m_readArrayMethod, 1, v));
390}
391
392
393// ================================================================
394
395BooleanType::BooleanType()
396 :Type("boolean", BUILT_IN, true, false)
397{
398}
399
400void
401BooleanType::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
408void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700409BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700410{
411 addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"),
412 "!=", new MethodCall(parcel, "readInt"))));
413}
414
415bool
416BooleanType::CanBeArray() const
417{
418 return true;
419}
420
421void
422BooleanType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
423{
424 addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
425}
426
427void
428BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700429 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700430{
431 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
432}
433
434void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700435BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700436{
437 addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
438}
439
440
441// ================================================================
442
443CharType::CharType()
444 :Type("char", BUILT_IN, true, false)
445{
446}
447
448void
449CharType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
450{
451 addTo->Add(new MethodCall(parcel, "writeInt", 1,
452 new Cast(INT_TYPE, v)));
453}
454
455void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700456CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700457{
458 addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
459}
460
461bool
462CharType::CanBeArray() const
463{
464 return true;
465}
466
467void
468CharType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
469{
470 addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
471}
472
473void
474CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700475 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700476{
477 addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
478}
479
480void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700481CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700482{
483 addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
484}
485
486// ================================================================
487
488StringType::StringType()
489 :Type("java.lang", "String", BUILT_IN, true, false)
490{
491}
492
493string
494StringType::CreatorName() const
495{
496 return "android.os.Parcel.STRING_CREATOR";
497}
498
499void
500StringType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
501{
502 addTo->Add(new MethodCall(parcel, "writeString", 1, v));
503}
504
505void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700506StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700507{
508 addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
509}
510
511bool
512StringType::CanBeArray() const
513{
514 return true;
515}
516
517void
518StringType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
519{
520 addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
521}
522
523void
524StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700525 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700526{
527 addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
528}
529
530void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700531StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700532{
533 addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
534}
535
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700536void
537StringType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
538 Variable* data, int flags)
539{
540 addTo->Add(new MethodCall(data, "putString", 2, k, v));
541}
542
543void
544StringType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
545 Variable* data, Variable**)
546{
547 addTo->Add(new Assignment(v, new MethodCall(data, "getString", 1, k)));
548}
549
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700550// ================================================================
551
552CharSequenceType::CharSequenceType()
553 :Type("java.lang", "CharSequence", BUILT_IN, true, false)
554{
555}
556
557string
558CharSequenceType::CreatorName() const
559{
560 return "android.os.Parcel.STRING_CREATOR";
561}
562
563void
564CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
565{
566 // if (v != null) {
567 // parcel.writeInt(1);
568 // v.writeToParcel(parcel);
569 // } else {
570 // parcel.writeInt(0);
571 // }
572 IfStatement* elsepart = new IfStatement();
573 elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1,
574 new LiteralExpression("0")));
575 IfStatement* ifpart = new IfStatement;
576 ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
577 ifpart->elseif = elsepart;
578 ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1,
579 new LiteralExpression("1")));
580 ifpart->statements->Add(new MethodCall(TEXT_UTILS_TYPE, "writeToParcel",
581 3, v, parcel, BuildWriteToParcelFlags(flags)));
582
583 addTo->Add(ifpart);
584}
585
586void
587CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700588 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700589{
590 // if (0 != parcel.readInt()) {
591 // v = TextUtils.createFromParcel(parcel)
592 // } else {
593 // v = null;
594 // }
595 IfStatement* elsepart = new IfStatement();
596 elsepart->statements->Add(new Assignment(v, NULL_VALUE));
597
598 IfStatement* ifpart = new IfStatement();
599 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
600 new MethodCall(parcel, "readInt"));
601 ifpart->elseif = elsepart;
602 ifpart->statements->Add(new Assignment(v,
603 new MethodCall(TEXT_UTILS_TYPE,
604 "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel)));
605
606 addTo->Add(ifpart);
607}
608
609
610// ================================================================
611
612RemoteExceptionType::RemoteExceptionType()
613 :Type("android.os", "RemoteException", BUILT_IN, false, false)
614{
615}
616
617void
618RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
619{
620 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
621}
622
623void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700624RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700625{
626 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
627}
628
629// ================================================================
630
631RuntimeExceptionType::RuntimeExceptionType()
632 :Type("java.lang", "RuntimeException", BUILT_IN, false, false)
633{
634}
635
636void
637RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
638{
639 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
640}
641
642void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700643RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700644{
645 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
646}
647
648
649// ================================================================
650
651IBinderType::IBinderType()
652 :Type("android.os", "IBinder", BUILT_IN, true, false)
653{
654}
655
656void
657IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
658{
659 addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
660}
661
662void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700663IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700664{
665 addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
666}
667
668void
669IBinderType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
670{
671 addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
672}
673
674void
675IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700676 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700677{
678 addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
679}
680
681void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700682IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700683{
684 addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
685}
686
687
688// ================================================================
689
690IInterfaceType::IInterfaceType()
691 :Type("android.os", "IInterface", BUILT_IN, false, false)
692{
693}
694
695void
696IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
697{
698 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
699}
700
701void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700702IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700703{
704 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
705}
706
707
708// ================================================================
709
710BinderType::BinderType()
711 :Type("android.os", "Binder", BUILT_IN, false, false)
712{
713}
714
715void
716BinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
717{
718 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
719}
720
721void
722BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700723 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700724{
725 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
726}
727
728
729// ================================================================
730
731BinderProxyType::BinderProxyType()
732 :Type("android.os", "BinderProxy", BUILT_IN, false, false)
733{
734}
735
736void
737BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
738{
739 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
740}
741
742void
743BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700744 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700745{
746 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
747}
748
749
750// ================================================================
751
752ParcelType::ParcelType()
753 :Type("android.os", "Parcel", BUILT_IN, false, false)
754{
755}
756
757void
758ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
759{
760 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
761}
762
763void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700764ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700765{
766 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
767}
768
769// ================================================================
770
771ParcelableInterfaceType::ParcelableInterfaceType()
772 :Type("android.os", "Parcelable", BUILT_IN, false, false)
773{
774}
775
776void
777ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
778{
779 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
780}
781
782void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700783ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700784{
785 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
786}
787
788// ================================================================
789
790MapType::MapType()
791 :Type("java.util", "Map", BUILT_IN, true, true)
792{
793}
794
795void
796MapType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
797{
798 addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
799}
800
Elliott Hughes15f8da22011-07-13 12:10:30 -0700801static void EnsureClassLoader(StatementBlock* addTo, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700802{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700803 // We don't want to look up the class loader once for every
804 // collection argument, so ensure we do it at most once per method.
805 if (*cl == NULL) {
806 *cl = new Variable(CLASSLOADER_TYPE, "cl");
807 addTo->Add(new VariableDeclaration(*cl,
808 new LiteralExpression("this.getClass().getClassLoader()"),
809 CLASSLOADER_TYPE));
810 }
811}
812
813void
814MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
815{
816 EnsureClassLoader(addTo, cl);
817 addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700818}
819
820void
821MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700822 Variable* parcel, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700823{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700824 EnsureClassLoader(addTo, cl);
825 addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700826}
827
828
829// ================================================================
830
831ListType::ListType()
832 :Type("java.util", "List", BUILT_IN, true, true)
833{
834}
835
836string
837ListType::InstantiableName() const
838{
839 return "java.util.ArrayList";
840}
841
842void
843ListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
844{
845 addTo->Add(new MethodCall(parcel, "writeList", 1, v));
846}
847
848void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700849ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700850{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700851 EnsureClassLoader(addTo, cl);
852 addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700853}
854
855void
856ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700857 Variable* parcel, Variable** cl)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700858{
Elliott Hughes15f8da22011-07-13 12:10:30 -0700859 EnsureClassLoader(addTo, cl);
860 addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700861}
862
863
864// ================================================================
865
866ParcelableType::ParcelableType(const string& package, const string& name,
867 bool builtIn, const string& declFile, int declLine)
868 :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, true,
869 declFile, declLine)
870{
871}
872
873string
874ParcelableType::CreatorName() const
875{
876 return QualifiedName() + ".CREATOR";
877}
878
879void
880ParcelableType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
881{
882 // if (v != null) {
883 // parcel.writeInt(1);
884 // v.writeToParcel(parcel);
885 // } else {
886 // parcel.writeInt(0);
887 // }
888 IfStatement* elsepart = new IfStatement();
889 elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1,
890 new LiteralExpression("0")));
891 IfStatement* ifpart = new IfStatement;
892 ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
893 ifpart->elseif = elsepart;
894 ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1,
895 new LiteralExpression("1")));
896 ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2,
897 parcel, BuildWriteToParcelFlags(flags)));
898
899 addTo->Add(ifpart);
900}
901
902void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700903ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700904{
905 // if (0 != parcel.readInt()) {
906 // v = CLASS.CREATOR.createFromParcel(parcel)
907 // } else {
908 // v = null;
909 // }
910 IfStatement* elsepart = new IfStatement();
911 elsepart->statements->Add(new Assignment(v, NULL_VALUE));
912
913 IfStatement* ifpart = new IfStatement();
914 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
915 new MethodCall(parcel, "readInt"));
916 ifpart->elseif = elsepart;
917 ifpart->statements->Add(new Assignment(v,
918 new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel)));
919
920 addTo->Add(ifpart);
921}
922
923void
924ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700925 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700926{
927 // TODO: really, we don't need to have this extra check, but we
928 // don't have two separate marshalling code paths
929 // if (0 != parcel.readInt()) {
930 // v.readFromParcel(parcel)
931 // }
932 IfStatement* ifpart = new IfStatement();
933 ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
934 new MethodCall(parcel, "readInt"));
935 ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel));
936 addTo->Add(ifpart);
937}
938
939bool
940ParcelableType::CanBeArray() const
941{
942 return true;
943}
944
945void
946ParcelableType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
947{
948 addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
949 BuildWriteToParcelFlags(flags)));
950}
951
952void
953ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -0700954 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700955{
956 string creator = v->type->QualifiedName() + ".CREATOR";
957 addTo->Add(new Assignment(v, new MethodCall(parcel,
958 "createTypedArray", 1, new LiteralExpression(creator))));
959}
960
961void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700962ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -0700963{
964 string creator = v->type->QualifiedName() + ".CREATOR";
965 addTo->Add(new MethodCall(parcel, "readTypedArray", 2,
966 v, new LiteralExpression(creator)));
967}
968
969
970// ================================================================
971
972InterfaceType::InterfaceType(const string& package, const string& name,
973 bool builtIn, bool oneway,
974 const string& declFile, int declLine)
975 :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false,
976 declFile, declLine)
977 ,m_oneway(oneway)
978{
979}
980
981bool
982InterfaceType::OneWay() const
983{
984 return m_oneway;
985}
986
987void
988InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
989{
990 // parcel.writeStrongBinder(v != null ? v.asBinder() : null);
991 addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1,
992 new Ternary(
993 new Comparison(v, "!=", NULL_VALUE),
994 new MethodCall(v, "asBinder"),
995 NULL_VALUE)));
996}
997
998void
Elliott Hughes15f8da22011-07-13 12:10:30 -0700999InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001000{
1001 // v = Interface.asInterface(parcel.readStrongBinder());
1002 string type = v->type->QualifiedName();
1003 type += ".Stub";
1004 addTo->Add(new Assignment(v,
1005 new MethodCall( NAMES.Find(type), "asInterface", 1,
1006 new MethodCall(parcel, "readStrongBinder"))));
1007}
1008
1009
1010// ================================================================
1011
1012GenericType::GenericType(const string& package, const string& name,
1013 const vector<Type*>& args)
1014 :Type(package, name, BUILT_IN, true, true)
1015{
1016 m_args = args;
1017
1018 m_importName = package + '.' + name;
1019
1020 string gen = "<";
1021 int N = args.size();
1022 for (int i=0; i<N; i++) {
1023 Type* t = args[i];
1024 gen += t->QualifiedName();
1025 if (i != N-1) {
1026 gen += ',';
1027 }
1028 }
1029 gen += '>';
1030 m_genericArguments = gen;
1031 SetQualifiedName(m_importName + gen);
1032}
1033
1034string
1035GenericType::GenericArguments() const
1036{
1037 return m_genericArguments;
1038}
1039
1040string
1041GenericType::ImportType() const
1042{
1043 return m_importName;
1044}
1045
1046void
1047GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
1048{
1049 fprintf(stderr, "implement GenericType::WriteToParcel\n");
1050}
1051
1052void
Elliott Hughes15f8da22011-07-13 12:10:30 -07001053GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001054{
1055 fprintf(stderr, "implement GenericType::CreateFromParcel\n");
1056}
1057
1058void
1059GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -07001060 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001061{
1062 fprintf(stderr, "implement GenericType::ReadFromParcel\n");
1063}
1064
1065
1066// ================================================================
1067
1068GenericListType::GenericListType(const string& package, const string& name,
1069 const vector<Type*>& args)
1070 :GenericType(package, name, args),
1071 m_creator(args[0]->CreatorName())
1072{
1073}
1074
1075string
1076GenericListType::CreatorName() const
1077{
1078 return "android.os.Parcel.arrayListCreator";
1079}
1080
1081string
1082GenericListType::InstantiableName() const
1083{
1084 return "java.util.ArrayList" + GenericArguments();
1085}
1086
1087void
1088GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
1089{
1090 if (m_creator == STRING_TYPE->CreatorName()) {
1091 addTo->Add(new MethodCall(parcel, "writeStringList", 1, v));
1092 } else if (m_creator == IBINDER_TYPE->CreatorName()) {
1093 addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v));
1094 } else {
1095 // parcel.writeTypedListXX(arg);
1096 addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v));
1097 }
1098}
1099
1100void
Elliott Hughes15f8da22011-07-13 12:10:30 -07001101GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001102{
1103 if (m_creator == STRING_TYPE->CreatorName()) {
1104 addTo->Add(new Assignment(v,
1105 new MethodCall(parcel, "createStringArrayList", 0)));
1106 } else if (m_creator == IBINDER_TYPE->CreatorName()) {
1107 addTo->Add(new Assignment(v,
1108 new MethodCall(parcel, "createBinderArrayList", 0)));
1109 } else {
1110 // v = _data.readTypedArrayList(XXX.creator);
1111 addTo->Add(new Assignment(v,
1112 new MethodCall(parcel, "createTypedArrayList", 1,
1113 new LiteralExpression(m_creator))));
1114 }
1115}
1116
1117void
1118GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Elliott Hughes15f8da22011-07-13 12:10:30 -07001119 Variable* parcel, Variable**)
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001120{
1121 if (m_creator == STRING_TYPE->CreatorName()) {
1122 addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
1123 } else if (m_creator == IBINDER_TYPE->CreatorName()) {
1124 addTo->Add(new MethodCall(parcel, "readBinderList", 1, v));
1125 } else {
1126 // v = _data.readTypedList(v, XXX.creator);
1127 addTo->Add(new MethodCall(parcel, "readTypedList", 2,
1128 v,
1129 new LiteralExpression(m_creator)));
1130 }
1131}
1132
1133// ================================================================
1134
1135ClassLoaderType::ClassLoaderType()
1136 :Type("java.lang", "ClassLoader", BUILT_IN, false, false)
1137{
1138}
1139
1140
1141// ================================================================
1142
1143Namespace::Namespace()
1144{
1145}
1146
1147Namespace::~Namespace()
1148{
1149 int N = m_types.size();
1150 for (int i=0; i<N; i++) {
1151 delete m_types[i];
1152 }
1153}
1154
1155void
1156Namespace::Add(Type* type)
1157{
1158 Type* t = Find(type->QualifiedName());
1159 if (t == NULL) {
1160 m_types.push_back(type);
1161 }
1162}
1163
1164void
1165Namespace::AddGenericType(const string& package, const string& name, int args)
1166{
1167 Generic g;
1168 g.package = package;
1169 g.name = name;
1170 g.qualified = package + '.' + name;
1171 g.args = args;
1172 m_generics.push_back(g);
1173}
1174
1175Type*
1176Namespace::Find(const string& name) const
1177{
1178 int N = m_types.size();
1179 for (int i=0; i<N; i++) {
1180 if (m_types[i]->QualifiedName() == name) {
1181 return m_types[i];
1182 }
1183 }
1184 return NULL;
1185}
1186
1187Type*
1188Namespace::Find(const char* package, const char* name) const
1189{
1190 string s;
1191 if (package != NULL) {
1192 s += package;
1193 s += '.';
1194 }
1195 s += name;
1196 return Find(s);
1197}
1198
1199static string
1200normalize_generic(const string& s)
1201{
1202 string r;
1203 int N = s.size();
1204 for (int i=0; i<N; i++) {
1205 char c = s[i];
1206 if (!isspace(c)) {
1207 r += c;
1208 }
1209 }
1210 return r;
1211}
1212
1213Type*
1214Namespace::Search(const string& name)
1215{
1216 // an exact match wins
1217 Type* result = Find(name);
1218 if (result != NULL) {
1219 return result;
1220 }
1221
1222 // try the class names
1223 // our language doesn't allow you to not specify outer classes
1224 // when referencing an inner class. that could be changed, and this
1225 // would be the place to do it, but I don't think the complexity in
1226 // scoping rules is worth it.
1227 int N = m_types.size();
1228 for (int i=0; i<N; i++) {
1229 if (m_types[i]->Name() == name) {
1230 return m_types[i];
1231 }
1232 }
1233
1234 // we got to here and it's not a generic, give up
1235 if (name.find('<') == name.npos) {
1236 return NULL;
1237 }
1238
1239 // remove any whitespace
1240 string normalized = normalize_generic(name);
1241
1242 // find the part before the '<', find a generic for it
1243 ssize_t baseIndex = normalized.find('<');
1244 string base(normalized.c_str(), baseIndex);
1245 const Generic* g = search_generic(base);
1246 if (g == NULL) {
1247 return NULL;
1248 }
1249
1250 // For each of the args, do a recursive search on it. We don't allow
1251 // generics within generics like Java does, because we're really limiting
1252 // them to just built-in container classes, at least for now. Our syntax
1253 // ensures this right now as well.
1254 vector<Type*> args;
1255 size_t start = baseIndex + 1;
1256 size_t end = start;
1257 while (normalized[start] != '\0') {
1258 end = normalized.find(',', start);
1259 if (end == normalized.npos) {
1260 end = normalized.find('>', start);
1261 }
1262 string s(normalized.c_str()+start, end-start);
1263 Type* t = this->Search(s);
1264 if (t == NULL) {
1265 // maybe we should print a warning here?
1266 return NULL;
1267 }
1268 args.push_back(t);
1269 start = end+1;
1270 }
1271
1272 // construct a GenericType, add it to our name set so they always get
1273 // the same object, and return it.
1274 result = make_generic_type(g->package, g->name, args);
1275 if (result == NULL) {
1276 return NULL;
1277 }
1278
1279 this->Add(result);
1280 return this->Find(result->QualifiedName());
1281}
1282
1283const Namespace::Generic*
1284Namespace::search_generic(const string& name) const
1285{
1286 int N = m_generics.size();
1287
1288 // first exact match
1289 for (int i=0; i<N; i++) {
1290 const Generic& g = m_generics[i];
1291 if (g.qualified == name) {
1292 return &g;
1293 }
1294 }
1295
1296 // then name match
1297 for (int i=0; i<N; i++) {
1298 const Generic& g = m_generics[i];
1299 if (g.name == name) {
1300 return &g;
1301 }
1302 }
1303
1304 return NULL;
1305}
1306
1307void
1308Namespace::Dump() const
1309{
1310 int n = m_types.size();
1311 for (int i=0; i<n; i++) {
1312 Type* t = m_types[i];
1313 printf("type: package=%s name=%s qualifiedName=%s\n",
1314 t->Package().c_str(), t->Name().c_str(),
1315 t->QualifiedName().c_str());
1316 }
1317}