1 /*
2  * Copyright (C) 2015, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "ast_java.h"
18 
19 #include "code_writer.h"
20 #include "type_java.h"
21 
22 using std::vector;
23 using std::string;
24 
25 namespace android {
26 namespace aidl {
27 namespace java {
28 
WriteModifiers(CodeWriter * to,int mod,int mask)29 void WriteModifiers(CodeWriter* to, int mod, int mask) {
30   int m = mod & mask;
31 
32   if (m & OVERRIDE) {
33     to->Write("@Override ");
34   }
35 
36   if ((m & SCOPE_MASK) == PUBLIC) {
37     to->Write("public ");
38   } else if ((m & SCOPE_MASK) == PRIVATE) {
39     to->Write("private ");
40   } else if ((m & SCOPE_MASK) == PROTECTED) {
41     to->Write("protected ");
42   }
43 
44   if (m & STATIC) {
45     to->Write("static ");
46   }
47 
48   if (m & FINAL) {
49     to->Write("final ");
50   }
51 
52   if (m & ABSTRACT) {
53     to->Write("abstract ");
54   }
55 }
56 
WriteArgumentList(CodeWriter * to,const vector<Expression * > & arguments)57 void WriteArgumentList(CodeWriter* to, const vector<Expression*>& arguments) {
58   size_t N = arguments.size();
59   for (size_t i = 0; i < N; i++) {
60     arguments[i]->Write(to);
61     if (i != N - 1) {
62       to->Write(", ");
63     }
64   }
65 }
66 
Field(int m,Variable * v)67 Field::Field(int m, Variable* v) : ClassElement(), modifiers(m), variable(v) {}
68 
Write(CodeWriter * to) const69 void Field::Write(CodeWriter* to) const {
70   if (this->comment.length() != 0) {
71     to->Write("%s\n", this->comment.c_str());
72   }
73   WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE);
74   to->Write("%s %s", this->variable->type->JavaType().c_str(),
75             this->variable->name.c_str());
76   if (this->value.length() != 0) {
77     to->Write(" = %s", this->value.c_str());
78   }
79   to->Write(";\n");
80 }
81 
LiteralExpression(const string & v)82 LiteralExpression::LiteralExpression(const string& v) : value(v) {}
83 
Write(CodeWriter * to) const84 void LiteralExpression::Write(CodeWriter* to) const {
85   to->Write("%s", this->value.c_str());
86 }
87 
StringLiteralExpression(const string & v)88 StringLiteralExpression::StringLiteralExpression(const string& v) : value(v) {}
89 
Write(CodeWriter * to) const90 void StringLiteralExpression::Write(CodeWriter* to) const {
91   to->Write("\"%s\"", this->value.c_str());
92 }
93 
Variable(const Type * t,const string & n)94 Variable::Variable(const Type* t, const string& n)
95     : type(t), name(n), dimension(0) {}
96 
Variable(const Type * t,const string & n,int d)97 Variable::Variable(const Type* t, const string& n, int d)
98     : type(t), name(n), dimension(d) {}
99 
WriteDeclaration(CodeWriter * to) const100 void Variable::WriteDeclaration(CodeWriter* to) const {
101   string dim;
102   for (int i = 0; i < this->dimension; i++) {
103     dim += "[]";
104   }
105   to->Write("%s%s %s", this->type->JavaType().c_str(), dim.c_str(),
106             this->name.c_str());
107 }
108 
Write(CodeWriter * to) const109 void Variable::Write(CodeWriter* to) const { to->Write("%s", name.c_str()); }
110 
FieldVariable(Expression * o,const string & n)111 FieldVariable::FieldVariable(Expression* o, const string& n)
112     : object(o), clazz(NULL), name(n) {}
113 
FieldVariable(const Type * c,const string & n)114 FieldVariable::FieldVariable(const Type* c, const string& n)
115     : object(NULL), clazz(c), name(n) {}
116 
Write(CodeWriter * to) const117 void FieldVariable::Write(CodeWriter* to) const {
118   if (this->object != NULL) {
119     this->object->Write(to);
120   } else if (this->clazz != NULL) {
121     to->Write("%s", this->clazz->JavaType().c_str());
122   }
123   to->Write(".%s", name.c_str());
124 }
125 
Write(CodeWriter * to) const126 void StatementBlock::Write(CodeWriter* to) const {
127   to->Write("{\n");
128   int N = this->statements.size();
129   for (int i = 0; i < N; i++) {
130     this->statements[i]->Write(to);
131   }
132   to->Write("}\n");
133 }
134 
Add(Statement * statement)135 void StatementBlock::Add(Statement* statement) {
136   this->statements.push_back(statement);
137 }
138 
Add(Expression * expression)139 void StatementBlock::Add(Expression* expression) {
140   this->statements.push_back(new ExpressionStatement(expression));
141 }
142 
ExpressionStatement(Expression * e)143 ExpressionStatement::ExpressionStatement(Expression* e) : expression(e) {}
144 
Write(CodeWriter * to) const145 void ExpressionStatement::Write(CodeWriter* to) const {
146   this->expression->Write(to);
147   to->Write(";\n");
148 }
149 
Assignment(Variable * l,Expression * r)150 Assignment::Assignment(Variable* l, Expression* r)
151     : lvalue(l), rvalue(r), cast(NULL) {}
152 
Assignment(Variable * l,Expression * r,const Type * c)153 Assignment::Assignment(Variable* l, Expression* r, const Type* c)
154     : lvalue(l), rvalue(r), cast(c) {}
155 
Write(CodeWriter * to) const156 void Assignment::Write(CodeWriter* to) const {
157   this->lvalue->Write(to);
158   to->Write(" = ");
159   if (this->cast != NULL) {
160     to->Write("(%s)", this->cast->JavaType().c_str());
161   }
162   this->rvalue->Write(to);
163 }
164 
MethodCall(const string & n)165 MethodCall::MethodCall(const string& n) : name(n) {}
166 
MethodCall(const string & n,int argc=0,...)167 MethodCall::MethodCall(const string& n, int argc = 0, ...) : name(n) {
168   va_list args;
169   va_start(args, argc);
170   init(argc, args);
171   va_end(args);
172 }
173 
MethodCall(Expression * o,const string & n)174 MethodCall::MethodCall(Expression* o, const string& n) : obj(o), name(n) {}
175 
MethodCall(const Type * t,const string & n)176 MethodCall::MethodCall(const Type* t, const string& n) : clazz(t), name(n) {}
177 
MethodCall(Expression * o,const string & n,int argc=0,...)178 MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...)
179     : obj(o), name(n) {
180   va_list args;
181   va_start(args, argc);
182   init(argc, args);
183   va_end(args);
184 }
185 
MethodCall(const Type * t,const string & n,int argc=0,...)186 MethodCall::MethodCall(const Type* t, const string& n, int argc = 0, ...)
187     : clazz(t), name(n) {
188   va_list args;
189   va_start(args, argc);
190   init(argc, args);
191   va_end(args);
192 }
193 
init(int n,va_list args)194 void MethodCall::init(int n, va_list args) {
195   for (int i = 0; i < n; i++) {
196     Expression* expression = (Expression*)va_arg(args, void*);
197     this->arguments.push_back(expression);
198   }
199 }
200 
Write(CodeWriter * to) const201 void MethodCall::Write(CodeWriter* to) const {
202   if (this->obj != NULL) {
203     this->obj->Write(to);
204     to->Write(".");
205   } else if (this->clazz != NULL) {
206     to->Write("%s.", this->clazz->JavaType().c_str());
207   }
208   to->Write("%s(", this->name.c_str());
209   WriteArgumentList(to, this->arguments);
210   to->Write(")");
211 }
212 
Comparison(Expression * l,const string & o,Expression * r)213 Comparison::Comparison(Expression* l, const string& o, Expression* r)
214     : lvalue(l), op(o), rvalue(r) {}
215 
Write(CodeWriter * to) const216 void Comparison::Write(CodeWriter* to) const {
217   to->Write("(");
218   this->lvalue->Write(to);
219   to->Write("%s", this->op.c_str());
220   this->rvalue->Write(to);
221   to->Write(")");
222 }
223 
NewExpression(const Type * t)224 NewExpression::NewExpression(const Type* t) : type(t) {}
225 
NewExpression(const Type * t,int argc=0,...)226 NewExpression::NewExpression(const Type* t, int argc = 0, ...) : type(t) {
227   va_list args;
228   va_start(args, argc);
229   init(argc, args);
230   va_end(args);
231 }
232 
init(int n,va_list args)233 void NewExpression::init(int n, va_list args) {
234   for (int i = 0; i < n; i++) {
235     Expression* expression = (Expression*)va_arg(args, void*);
236     this->arguments.push_back(expression);
237   }
238 }
239 
Write(CodeWriter * to) const240 void NewExpression::Write(CodeWriter* to) const {
241   to->Write("new %s(", this->type->InstantiableName().c_str());
242   WriteArgumentList(to, this->arguments);
243   to->Write(")");
244 }
245 
NewArrayExpression(const Type * t,Expression * s)246 NewArrayExpression::NewArrayExpression(const Type* t, Expression* s)
247     : type(t), size(s) {}
248 
Write(CodeWriter * to) const249 void NewArrayExpression::Write(CodeWriter* to) const {
250   to->Write("new %s[", this->type->JavaType().c_str());
251   size->Write(to);
252   to->Write("]");
253 }
254 
Ternary(Expression * a,Expression * b,Expression * c)255 Ternary::Ternary(Expression* a, Expression* b, Expression* c)
256     : condition(a), ifpart(b), elsepart(c) {}
257 
Write(CodeWriter * to) const258 void Ternary::Write(CodeWriter* to) const {
259   to->Write("((");
260   this->condition->Write(to);
261   to->Write(")?(");
262   this->ifpart->Write(to);
263   to->Write("):(");
264   this->elsepart->Write(to);
265   to->Write("))");
266 }
267 
Cast(const Type * t,Expression * e)268 Cast::Cast(const Type* t, Expression* e) : type(t), expression(e) {}
269 
Write(CodeWriter * to) const270 void Cast::Write(CodeWriter* to) const {
271   to->Write("((%s)", this->type->JavaType().c_str());
272   expression->Write(to);
273   to->Write(")");
274 }
275 
VariableDeclaration(Variable * l,Expression * r,const Type * c)276 VariableDeclaration::VariableDeclaration(Variable* l, Expression* r,
277                                          const Type* c)
278     : lvalue(l), cast(c), rvalue(r) {}
279 
VariableDeclaration(Variable * l)280 VariableDeclaration::VariableDeclaration(Variable* l) : lvalue(l) {}
281 
Write(CodeWriter * to) const282 void VariableDeclaration::Write(CodeWriter* to) const {
283   this->lvalue->WriteDeclaration(to);
284   if (this->rvalue != NULL) {
285     to->Write(" = ");
286     if (this->cast != NULL) {
287       to->Write("(%s)", this->cast->JavaType().c_str());
288     }
289     this->rvalue->Write(to);
290   }
291   to->Write(";\n");
292 }
293 
Write(CodeWriter * to) const294 void IfStatement::Write(CodeWriter* to) const {
295   if (this->expression != NULL) {
296     to->Write("if (");
297     this->expression->Write(to);
298     to->Write(") ");
299   }
300   this->statements->Write(to);
301   if (this->elseif != NULL) {
302     to->Write("else ");
303     this->elseif->Write(to);
304   }
305 }
306 
ReturnStatement(Expression * e)307 ReturnStatement::ReturnStatement(Expression* e) : expression(e) {}
308 
Write(CodeWriter * to) const309 void ReturnStatement::Write(CodeWriter* to) const {
310   to->Write("return ");
311   this->expression->Write(to);
312   to->Write(";\n");
313 }
314 
Write(CodeWriter * to) const315 void TryStatement::Write(CodeWriter* to) const {
316   to->Write("try ");
317   this->statements->Write(to);
318 }
319 
CatchStatement(Variable * e)320 CatchStatement::CatchStatement(Variable* e)
321     : statements(new StatementBlock), exception(e) {}
322 
Write(CodeWriter * to) const323 void CatchStatement::Write(CodeWriter* to) const {
324   to->Write("catch ");
325   if (this->exception != NULL) {
326     to->Write("(");
327     this->exception->WriteDeclaration(to);
328     to->Write(") ");
329   }
330   this->statements->Write(to);
331 }
332 
Write(CodeWriter * to) const333 void FinallyStatement::Write(CodeWriter* to) const {
334   to->Write("finally ");
335   this->statements->Write(to);
336 }
337 
Case(const string & c)338 Case::Case(const string& c) { cases.push_back(c); }
339 
Write(CodeWriter * to) const340 void Case::Write(CodeWriter* to) const {
341   int N = this->cases.size();
342   if (N > 0) {
343     for (int i = 0; i < N; i++) {
344       string s = this->cases[i];
345       if (s.length() != 0) {
346         to->Write("case %s:\n", s.c_str());
347       } else {
348         to->Write("default:\n");
349       }
350     }
351   } else {
352     to->Write("default:\n");
353   }
354   statements->Write(to);
355 }
356 
SwitchStatement(Expression * e)357 SwitchStatement::SwitchStatement(Expression* e) : expression(e) {}
358 
Write(CodeWriter * to) const359 void SwitchStatement::Write(CodeWriter* to) const {
360   to->Write("switch (");
361   this->expression->Write(to);
362   to->Write(")\n{\n");
363   int N = this->cases.size();
364   for (int i = 0; i < N; i++) {
365     this->cases[i]->Write(to);
366   }
367   to->Write("}\n");
368 }
369 
Write(CodeWriter * to) const370 void Break::Write(CodeWriter* to) const { to->Write("break;\n"); }
371 
Write(CodeWriter * to) const372 void Method::Write(CodeWriter* to) const {
373   size_t N, i;
374 
375   if (this->comment.length() != 0) {
376     to->Write("%s\n", this->comment.c_str());
377   }
378 
379   WriteModifiers(to, this->modifiers,
380                  SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE);
381 
382   if (this->returnType != NULL) {
383     string dim;
384     for (i = 0; i < this->returnTypeDimension; i++) {
385       dim += "[]";
386     }
387     to->Write("%s%s ", this->returnType->JavaType().c_str(), dim.c_str());
388   }
389 
390   to->Write("%s(", this->name.c_str());
391 
392   N = this->parameters.size();
393   for (i = 0; i < N; i++) {
394     this->parameters[i]->WriteDeclaration(to);
395     if (i != N - 1) {
396       to->Write(", ");
397     }
398   }
399 
400   to->Write(")");
401 
402   N = this->exceptions.size();
403   for (i = 0; i < N; i++) {
404     if (i == 0) {
405       to->Write(" throws ");
406     } else {
407       to->Write(", ");
408     }
409     to->Write("%s", this->exceptions[i]->JavaType().c_str());
410   }
411 
412   if (this->statements == NULL) {
413     to->Write(";\n");
414   } else {
415     to->Write("\n");
416     this->statements->Write(to);
417   }
418 }
419 
Write(CodeWriter * to) const420 void IntConstant::Write(CodeWriter* to) const {
421   WriteModifiers(to, STATIC | FINAL | PUBLIC, ALL_MODIFIERS);
422   to->Write("int %s = %d;\n", name.c_str(), value);
423 }
424 
Write(CodeWriter * to) const425 void StringConstant::Write(CodeWriter* to) const {
426   WriteModifiers(to, STATIC | FINAL | PUBLIC, ALL_MODIFIERS);
427   to->Write("String %s = %s;\n", name.c_str(), value.c_str());
428 }
429 
Write(CodeWriter * to) const430 void Class::Write(CodeWriter* to) const {
431   size_t N, i;
432 
433   if (this->comment.length() != 0) {
434     to->Write("%s\n", this->comment.c_str());
435   }
436 
437   WriteModifiers(to, this->modifiers, ALL_MODIFIERS);
438 
439   if (this->what == Class::CLASS) {
440     to->Write("class ");
441   } else {
442     to->Write("interface ");
443   }
444 
445   string name = this->type->JavaType();
446   size_t pos = name.rfind('.');
447   if (pos != string::npos) {
448     name = name.c_str() + pos + 1;
449   }
450 
451   to->Write("%s", name.c_str());
452 
453   if (this->extends != NULL) {
454     to->Write(" extends %s", this->extends->JavaType().c_str());
455   }
456 
457   N = this->interfaces.size();
458   if (N != 0) {
459     if (this->what == Class::CLASS) {
460       to->Write(" implements");
461     } else {
462       to->Write(" extends");
463     }
464     for (i = 0; i < N; i++) {
465       to->Write(" %s", this->interfaces[i]->JavaType().c_str());
466     }
467   }
468 
469   to->Write("\n");
470   to->Write("{\n");
471 
472   N = this->elements.size();
473   for (i = 0; i < N; i++) {
474     this->elements[i]->Write(to);
475   }
476 
477   to->Write("}\n");
478 }
479 
escape_backslashes(const string & str)480 static string escape_backslashes(const string& str) {
481   string result;
482   const size_t I = str.length();
483   for (size_t i = 0; i < I; i++) {
484     char c = str[i];
485     if (c == '\\') {
486       result += "\\\\";
487     } else {
488       result += c;
489     }
490   }
491   return result;
492 }
493 
Document(const std::string & comment,const std::string & package,const std::string & original_src,std::unique_ptr<Class> clazz)494 Document::Document(const std::string& comment,
495                    const std::string& package,
496                    const std::string& original_src,
497                    std::unique_ptr<Class> clazz)
498     : comment_(comment),
499       package_(package),
500       original_src_(original_src),
501       clazz_(std::move(clazz)) {
502 }
503 
Write(CodeWriter * to) const504 void Document::Write(CodeWriter* to) const {
505   if (!comment_.empty()) {
506     to->Write("%s\n", comment_.c_str());
507   }
508   to->Write(
509       "/*\n"
510       " * This file is auto-generated.  DO NOT MODIFY.\n"
511       " * Original file: %s\n"
512       " */\n",
513       escape_backslashes(original_src_).c_str());
514   if (!package_.empty()) {
515     to->Write("package %s;\n", package_.c_str());
516   }
517 
518   if (clazz_) {
519     clazz_->Write(to);
520   }
521 }
522 
523 }  // namespace java
524 }  // namespace aidl
525 }  // namespace android
526