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