blob: 91802a92f5796f5fa7cca7363c9b341461555777 [file] [log] [blame]
The Android Open Source Project46c012c2008-10-21 07:00:00 -07001#include "AST.h"
2#include "Type.h"
3
4void
5WriteModifiers(FILE* to, int mod, int mask)
6{
7 int m = mod & mask;
8
9 if ((m & SCOPE_MASK) == PUBLIC) {
10 fprintf(to, "public ");
11 }
12 else if ((m & SCOPE_MASK) == PRIVATE) {
13 fprintf(to, "private ");
14 }
15 else if ((m & SCOPE_MASK) == PROTECTED) {
16 fprintf(to, "protected ");
17 }
18
19 if (m & STATIC) {
20 fprintf(to, "static ");
21 }
22
23 if (m & FINAL) {
24 fprintf(to, "final ");
25 }
26
27 if (m & ABSTRACT) {
28 fprintf(to, "abstract ");
29 }
30}
31
32void
33WriteArgumentList(FILE* to, const vector<Expression*>& arguments)
34{
35 size_t N = arguments.size();
36 for (size_t i=0; i<N; i++) {
37 arguments[i]->Write(to);
38 if (i != N-1) {
39 fprintf(to, ", ");
40 }
41 }
42}
43
44ClassElement::ClassElement()
45{
46}
47
48ClassElement::~ClassElement()
49{
50}
51
52Field::Field()
53 :ClassElement(),
54 modifiers(0),
55 variable(NULL)
56{
57}
58
59Field::Field(int m, Variable* v)
60 :ClassElement(),
61 modifiers(m),
62 variable(v)
63{
64}
65
66Field::~Field()
67{
68}
69
70void
71Field::GatherTypes(set<Type*>* types) const
72{
73 types->insert(this->variable->type);
74}
75
76void
77Field::Write(FILE* to)
78{
79 if (this->comment.length() != 0) {
80 fprintf(to, "%s\n", this->comment.c_str());
81 }
82 WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL);
83 fprintf(to, "%s %s", this->variable->type->QualifiedName().c_str(),
84 this->variable->name.c_str());
85 if (this->value.length() != 0) {
86 fprintf(to, " = %s", this->value.c_str());
87 }
88 fprintf(to, ";\n");
89}
90
91Expression::~Expression()
92{
93}
94
95LiteralExpression::LiteralExpression(const string& v)
96 :value(v)
97{
98}
99
100LiteralExpression::~LiteralExpression()
101{
102}
103
104void
105LiteralExpression::Write(FILE* to)
106{
107 fprintf(to, "%s", this->value.c_str());
108}
109
110Variable::Variable()
111 :type(NULL),
112 name(),
113 dimension(0)
114{
115}
116
117Variable::Variable(Type* t, const string& n)
118 :type(t),
119 name(n),
120 dimension(0)
121{
122}
123
124Variable::Variable(Type* t, const string& n, int d)
125 :type(t),
126 name(n),
127 dimension(d)
128{
129}
130
131Variable::~Variable()
132{
133}
134
135void
136Variable::GatherTypes(set<Type*>* types) const
137{
138 types->insert(this->type);
139}
140
141void
142Variable::WriteDeclaration(FILE* to)
143{
144 string dim;
145 for (int i=0; i<this->dimension; i++) {
146 dim += "[]";
147 }
148 fprintf(to, "%s%s %s", this->type->QualifiedName().c_str(), dim.c_str(),
149 this->name.c_str());
150}
151
152void
153Variable::Write(FILE* to)
154{
155 fprintf(to, "%s", name.c_str());
156}
157
158FieldVariable::FieldVariable(Expression* o, const string& n)
159 :object(o),
160 clazz(NULL),
161 name(n)
162{
163}
164
165FieldVariable::FieldVariable(Type* c, const string& n)
166 :object(NULL),
167 clazz(c),
168 name(n)
169{
170}
171
172FieldVariable::~FieldVariable()
173{
174}
175
176void
177FieldVariable::Write(FILE* to)
178{
179 if (this->object != NULL) {
180 this->object->Write(to);
181 }
182 else if (this->clazz != NULL) {
183 fprintf(to, "%s", this->clazz->QualifiedName().c_str());
184 }
185 fprintf(to, ".%s", name.c_str());
186}
187
188
189Statement::~Statement()
190{
191}
192
193StatementBlock::StatementBlock()
194{
195}
196
197StatementBlock::~StatementBlock()
198{
199}
200
201void
202StatementBlock::Write(FILE* to)
203{
204 fprintf(to, "{\n");
205 int N = this->statements.size();
206 for (int i=0; i<N; i++) {
207 this->statements[i]->Write(to);
208 }
209 fprintf(to, "}\n");
210}
211
212void
213StatementBlock::Add(Statement* statement)
214{
215 this->statements.push_back(statement);
216}
217
218void
219StatementBlock::Add(Expression* expression)
220{
221 this->statements.push_back(new ExpressionStatement(expression));
222}
223
224ExpressionStatement::ExpressionStatement(Expression* e)
225 :expression(e)
226{
227}
228
229ExpressionStatement::~ExpressionStatement()
230{
231}
232
233void
234ExpressionStatement::Write(FILE* to)
235{
236 this->expression->Write(to);
237 fprintf(to, ";\n");
238}
239
240Assignment::Assignment(Variable* l, Expression* r)
241 :lvalue(l),
242 rvalue(r),
243 cast(NULL)
244{
245}
246
247Assignment::Assignment(Variable* l, Expression* r, Type* c)
248 :lvalue(l),
249 rvalue(r),
250 cast(c)
251{
252}
253
254Assignment::~Assignment()
255{
256}
257
258void
259Assignment::Write(FILE* to)
260{
261 this->lvalue->Write(to);
262 fprintf(to, " = ");
263 if (this->cast != NULL) {
264 fprintf(to, "(%s)", this->cast->QualifiedName().c_str());
265 }
266 this->rvalue->Write(to);
267}
268
269MethodCall::MethodCall(const string& n)
270 :obj(NULL),
271 clazz(NULL),
272 name(n)
273{
274}
275
276MethodCall::MethodCall(Expression* o, const string& n)
277 :obj(o),
278 clazz(NULL),
279 name(n)
280{
281}
282
283MethodCall::MethodCall(Type* t, const string& n)
284 :obj(NULL),
285 clazz(t),
286 name(n)
287{
288}
289
290MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...)
291 :obj(o),
292 clazz(NULL),
293 name(n)
294{
295 va_list args;
296 va_start(args, argc);
297 init(argc, args);
298 va_end(args);
299}
300
301MethodCall::MethodCall(Type* t, const string& n, int argc = 0, ...)
302 :obj(NULL),
303 clazz(t),
304 name(n)
305{
306 va_list args;
307 va_start(args, argc);
308 init(argc, args);
309 va_end(args);
310}
311
312MethodCall::~MethodCall()
313{
314}
315
316void
317MethodCall::init(int n, va_list args)
318{
319 for (int i=0; i<n; i++) {
320 Expression* expression = (Expression*)va_arg(args, void*);
321 this->arguments.push_back(expression);
322 }
323}
324
325void
326MethodCall::Write(FILE* to)
327{
328 if (this->obj != NULL) {
329 this->obj->Write(to);
330 fprintf(to, ".");
331 }
332 else if (this->clazz != NULL) {
333 fprintf(to, "%s.", this->clazz->QualifiedName().c_str());
334 }
335 fprintf(to, "%s(", this->name.c_str());
336 WriteArgumentList(to, this->arguments);
337 fprintf(to, ")");
338}
339
340Comparison::Comparison(Expression* l, const string& o, Expression* r)
341 :lvalue(l),
342 op(o),
343 rvalue(r)
344{
345}
346
347Comparison::~Comparison()
348{
349}
350
351void
352Comparison::Write(FILE* to)
353{
354 fprintf(to, "(");
355 this->lvalue->Write(to);
356 fprintf(to, "%s", this->op.c_str());
357 this->rvalue->Write(to);
358 fprintf(to, ")");
359}
360
361NewExpression::NewExpression(Type* t)
362 :type(t)
363{
364}
365
366NewExpression::~NewExpression()
367{
368}
369
370void
371NewExpression::Write(FILE* to)
372{
373 fprintf(to, "new %s(", this->type->InstantiableName().c_str());
374 WriteArgumentList(to, this->arguments);
375 fprintf(to, ")");
376}
377
378NewArrayExpression::NewArrayExpression(Type* t, Expression* s)
379 :type(t),
380 size(s)
381{
382}
383
384NewArrayExpression::~NewArrayExpression()
385{
386}
387
388void
389NewArrayExpression::Write(FILE* to)
390{
391 fprintf(to, "new %s[", this->type->QualifiedName().c_str());
392 size->Write(to);
393 fprintf(to, "]");
394}
395
396Ternary::Ternary()
397 :condition(NULL),
398 ifpart(NULL),
399 elsepart(NULL)
400{
401}
402
403Ternary::Ternary(Expression* a, Expression* b, Expression* c)
404 :condition(a),
405 ifpart(b),
406 elsepart(c)
407{
408}
409
410Ternary::~Ternary()
411{
412}
413
414void
415Ternary::Write(FILE* to)
416{
417 fprintf(to, "((");
418 this->condition->Write(to);
419 fprintf(to, ")?(");
420 this->ifpart->Write(to);
421 fprintf(to, "):(");
422 this->elsepart->Write(to);
423 fprintf(to, "))");
424}
425
426Cast::Cast()
427 :type(NULL),
428 expression(NULL)
429{
430}
431
432Cast::Cast(Type* t, Expression* e)
433 :type(t),
434 expression(e)
435{
436}
437
438Cast::~Cast()
439{
440}
441
442void
443Cast::Write(FILE* to)
444{
445 fprintf(to, "((%s)", this->type->QualifiedName().c_str());
446 expression->Write(to);
447 fprintf(to, ")");
448}
449
450VariableDeclaration::VariableDeclaration(Variable* l, Expression* r, Type* c)
451 :lvalue(l),
452 cast(c),
453 rvalue(r)
454{
455}
456
457VariableDeclaration::VariableDeclaration(Variable* l)
458 :lvalue(l),
459 cast(NULL),
460 rvalue(NULL)
461{
462}
463
464VariableDeclaration::~VariableDeclaration()
465{
466}
467
468void
469VariableDeclaration::Write(FILE* to)
470{
471 this->lvalue->WriteDeclaration(to);
472 if (this->rvalue != NULL) {
473 fprintf(to, " = ");
474 if (this->cast != NULL) {
475 fprintf(to, "(%s)", this->cast->QualifiedName().c_str());
476 }
477 this->rvalue->Write(to);
478 }
479 fprintf(to, ";\n");
480}
481
482IfStatement::IfStatement()
483 :expression(NULL),
484 statements(new StatementBlock),
485 elseif(NULL)
486{
487}
488
489IfStatement::~IfStatement()
490{
491}
492
493void
494IfStatement::Write(FILE* to)
495{
496 if (this->expression != NULL) {
497 fprintf(to, "if (");
498 this->expression->Write(to);
499 fprintf(to, ") ");
500 }
501 this->statements->Write(to);
502 if (this->elseif != NULL) {
503 fprintf(to, "else ");
504 this->elseif->Write(to);
505 }
506}
507
508ReturnStatement::ReturnStatement(Expression* e)
509 :expression(e)
510{
511}
512
513ReturnStatement::~ReturnStatement()
514{
515}
516
517void
518ReturnStatement::Write(FILE* to)
519{
520 fprintf(to, "return ");
521 this->expression->Write(to);
522 fprintf(to, ";\n");
523}
524
525TryStatement::TryStatement()
526 :statements(new StatementBlock)
527{
528}
529
530TryStatement::~TryStatement()
531{
532}
533
534void
535TryStatement::Write(FILE* to)
536{
537 fprintf(to, "try ");
538 this->statements->Write(to);
539}
540
541CatchStatement::CatchStatement(Variable* e)
542 :statements(new StatementBlock),
543 exception(e)
544{
545}
546
547CatchStatement::~CatchStatement()
548{
549}
550
551void
552CatchStatement::Write(FILE* to)
553{
554 fprintf(to, "catch ");
555 if (this->exception != NULL) {
556 fprintf(to, "(");
557 this->exception->WriteDeclaration(to);
558 fprintf(to, ") ");
559 }
560 this->statements->Write(to);
561}
562
563FinallyStatement::FinallyStatement()
564 :statements(new StatementBlock)
565{
566}
567
568FinallyStatement::~FinallyStatement()
569{
570}
571
572void
573FinallyStatement::Write(FILE* to)
574{
575 fprintf(to, "finally ");
576 this->statements->Write(to);
577}
578
579Case::Case()
580 :statements(new StatementBlock)
581{
582}
583
584Case::Case(const string& c)
585 :statements(new StatementBlock)
586{
587 cases.push_back(c);
588}
589
590Case::~Case()
591{
592}
593
594void
595Case::Write(FILE* to)
596{
597 int N = this->cases.size();
598 if (N > 0) {
599 for (int i=0; i<N; i++) {
600 string s = this->cases[i];
601 if (s.length() != 0) {
602 fprintf(to, "case %s:\n", s.c_str());
603 } else {
604 fprintf(to, "default:\n");
605 }
606 }
607 } else {
608 fprintf(to, "default:\n");
609 }
610 statements->Write(to);
611}
612
613SwitchStatement::SwitchStatement(Expression* e)
614 :expression(e)
615{
616}
617
618SwitchStatement::~SwitchStatement()
619{
620}
621
622void
623SwitchStatement::Write(FILE* to)
624{
625 fprintf(to, "switch (");
626 this->expression->Write(to);
627 fprintf(to, ")\n{\n");
628 int N = this->cases.size();
629 for (int i=0; i<N; i++) {
630 this->cases[i]->Write(to);
631 }
632 fprintf(to, "}\n");
633}
634
635Method::Method()
636 :ClassElement(),
637 modifiers(0),
638 returnType(NULL), // (NULL means constructor)
639 returnTypeDimension(0),
640 statements(NULL)
641{
642}
643
644Method::~Method()
645{
646}
647
648void
649Method::GatherTypes(set<Type*>* types) const
650{
651 size_t N, i;
652
653 if (this->returnType) {
654 types->insert(this->returnType);
655 }
656
657 N = this->parameters.size();
658 for (i=0; i<N; i++) {
659 this->parameters[i]->GatherTypes(types);
660 }
661
662 N = this->exceptions.size();
663 for (i=0; i<N; i++) {
664 types->insert(this->exceptions[i]);
665 }
666}
667
668void
669Method::Write(FILE* to)
670{
671 size_t N, i;
672
673 if (this->comment.length() != 0) {
674 fprintf(to, "%s\n", this->comment.c_str());
675 }
676
677 WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL);
678
679 if (this->returnType != NULL) {
680 string dim;
681 for (i=0; i<this->returnTypeDimension; i++) {
682 dim += "[]";
683 }
684 fprintf(to, "%s%s ", this->returnType->QualifiedName().c_str(),
685 dim.c_str());
686 }
687
688 fprintf(to, "%s(", this->name.c_str());
689
690 N = this->parameters.size();
691 for (i=0; i<N; i++) {
692 this->parameters[i]->WriteDeclaration(to);
693 if (i != N-1) {
694 fprintf(to, ", ");
695 }
696 }
697
698 fprintf(to, ")");
699
700 N = this->exceptions.size();
701 for (i=0; i<N; i++) {
702 if (i == 0) {
703 fprintf(to, " throws ");
704 } else {
705 fprintf(to, ", ");
706 }
707 fprintf(to, "%s", this->exceptions[i]->QualifiedName().c_str());
708 }
709
710 if (this->statements == NULL) {
711 fprintf(to, ";\n");
712 } else {
713 fprintf(to, "\n");
714 this->statements->Write(to);
715 }
716}
717
718Class::Class()
719 :modifiers(0),
720 what(CLASS),
721 type(NULL),
722 extends(NULL)
723{
724}
725
726Class::~Class()
727{
728}
729
730void
731Class::GatherTypes(set<Type*>* types) const
732{
733 int N, i;
734
735 types->insert(this->type);
736 if (this->extends != NULL) {
737 types->insert(this->extends);
738 }
739
740 N = this->interfaces.size();
741 for (i=0; i<N; i++) {
742 types->insert(this->interfaces[i]);
743 }
744
745 N = this->elements.size();
746 for (i=0; i<N; i++) {
747 this->elements[i]->GatherTypes(types);
748 }
749}
750
751void
752Class::Write(FILE* to)
753{
754 size_t N, i;
755
756 if (this->comment.length() != 0) {
757 fprintf(to, "%s\n", this->comment.c_str());
758 }
759
760 WriteModifiers(to, this->modifiers, ALL_MODIFIERS);
761
762 if (this->what == Class::CLASS) {
763 fprintf(to, "class ");
764 } else {
765 fprintf(to, "interface ");
766 }
767
768 string name = this->type->Name();
769 size_t pos = name.rfind('.');
770 if (pos != string::npos) {
771 name = name.c_str() + pos + 1;
772 }
773
774 fprintf(to, "%s", name.c_str());
775
776 if (this->extends != NULL) {
777 fprintf(to, " extends %s", this->extends->QualifiedName().c_str());
778 }
779
780 N = this->interfaces.size();
781 if (N != 0) {
782 if (this->what == Class::CLASS) {
783 fprintf(to, " implements");
784 } else {
785 fprintf(to, " extends");
786 }
787 for (i=0; i<N; i++) {
788 fprintf(to, " %s", this->interfaces[i]->QualifiedName().c_str());
789 }
790 }
791
792 fprintf(to, "\n");
793 fprintf(to, "{\n");
794
795 N = this->elements.size();
796 for (i=0; i<N; i++) {
797 this->elements[i]->Write(to);
798 }
799
800 fprintf(to, "}\n");
801
802}
803
804Document::Document()
805{
806}
807
808Document::~Document()
809{
810}
811
812static string
813escape_backslashes(const string& str)
814{
815 string result;
816 const size_t I=str.length();
817 for (size_t i=0; i<I; i++) {
818 char c = str[i];
819 if (c == '\\') {
820 result += "\\\\";
821 } else {
822 result += c;
823 }
824 }
825 return result;
826}
827
828void
829Document::Write(FILE* to)
830{
831 size_t N, i;
832
833 if (this->comment.length() != 0) {
834 fprintf(to, "%s\n", this->comment.c_str());
835 }
836 fprintf(to, "/*\n"
837 " * This file is auto-generated. DO NOT MODIFY.\n"
838 " * Original file: %s\n"
839 " */\n", escape_backslashes(this->originalSrc).c_str());
840 if (this->package.length() != 0) {
841 fprintf(to, "package %s;\n", this->package.c_str());
842 }
843
844 // gather the types for the import statements
845 set<Type*> types;
846 N = this->classes.size();
847 for (i=0; i<N; i++) {
848 Class* c = this->classes[i];
849 c->GatherTypes(&types);
850 }
851
852 set<Type*>::iterator it;
853 for (it=types.begin(); it!=types.end(); it++) {
854 Type* t = *it;
855 string pkg = t->Package();
856 if (pkg.length() != 0 && pkg != this->package) {
857 fprintf(to, "import %s;\n", t->ImportType().c_str());
858 }
859 }
860
861 N = this->classes.size();
862 for (i=0; i<N; i++) {
863 Class* c = this->classes[i];
864 c->Write(to);
865 }
866}
867