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