Home | History | Annotate | Download | only in aidl
      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 
     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 
     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 
     67 Field::Field(int m, Variable* v) : ClassElement(), modifiers(m), variable(v) {}
     68 
     69 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 
     82 LiteralExpression::LiteralExpression(const string& v) : value(v) {}
     83 
     84 void LiteralExpression::Write(CodeWriter* to) const {
     85   to->Write("%s", this->value.c_str());
     86 }
     87 
     88 StringLiteralExpression::StringLiteralExpression(const string& v) : value(v) {}
     89 
     90 void StringLiteralExpression::Write(CodeWriter* to) const {
     91   to->Write("\"%s\"", this->value.c_str());
     92 }
     93 
     94 Variable::Variable(const Type* t, const string& n)
     95     : type(t), name(n), dimension(0) {}
     96 
     97 Variable::Variable(const Type* t, const string& n, int d)
     98     : type(t), name(n), dimension(d) {}
     99 
    100 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 
    109 void Variable::Write(CodeWriter* to) const { to->Write("%s", name.c_str()); }
    110 
    111 FieldVariable::FieldVariable(Expression* o, const string& n)
    112     : object(o), clazz(NULL), name(n) {}
    113 
    114 FieldVariable::FieldVariable(const Type* c, const string& n)
    115     : object(NULL), clazz(c), name(n) {}
    116 
    117 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 
    126 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 
    135 void StatementBlock::Add(Statement* statement) {
    136   this->statements.push_back(statement);
    137 }
    138 
    139 void StatementBlock::Add(Expression* expression) {
    140   this->statements.push_back(new ExpressionStatement(expression));
    141 }
    142 
    143 ExpressionStatement::ExpressionStatement(Expression* e) : expression(e) {}
    144 
    145 void ExpressionStatement::Write(CodeWriter* to) const {
    146   this->expression->Write(to);
    147   to->Write(";\n");
    148 }
    149 
    150 Assignment::Assignment(Variable* l, Expression* r)
    151     : lvalue(l), rvalue(r), cast(NULL) {}
    152 
    153 Assignment::Assignment(Variable* l, Expression* r, const Type* c)
    154     : lvalue(l), rvalue(r), cast(c) {}
    155 
    156 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 
    165 MethodCall::MethodCall(const string& n) : name(n) {}
    166 
    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 
    174 MethodCall::MethodCall(Expression* o, const string& n) : obj(o), name(n) {}
    175 
    176 MethodCall::MethodCall(const Type* t, const string& n) : clazz(t), name(n) {}
    177 
    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 
    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 
    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 
    201 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 
    213 Comparison::Comparison(Expression* l, const string& o, Expression* r)
    214     : lvalue(l), op(o), rvalue(r) {}
    215 
    216 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 
    224 NewExpression::NewExpression(const Type* t) : type(t) {}
    225 
    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 
    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 
    240 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 
    246 NewArrayExpression::NewArrayExpression(const Type* t, Expression* s)
    247     : type(t), size(s) {}
    248 
    249 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 
    255 Ternary::Ternary(Expression* a, Expression* b, Expression* c)
    256     : condition(a), ifpart(b), elsepart(c) {}
    257 
    258 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 
    268 Cast::Cast(const Type* t, Expression* e) : type(t), expression(e) {}
    269 
    270 void Cast::Write(CodeWriter* to) const {
    271   to->Write("((%s)", this->type->JavaType().c_str());
    272   expression->Write(to);
    273   to->Write(")");
    274 }
    275 
    276 VariableDeclaration::VariableDeclaration(Variable* l, Expression* r,
    277                                          const Type* c)
    278     : lvalue(l), cast(c), rvalue(r) {}
    279 
    280 VariableDeclaration::VariableDeclaration(Variable* l) : lvalue(l) {}
    281 
    282 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 
    294 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 
    307 ReturnStatement::ReturnStatement(Expression* e) : expression(e) {}
    308 
    309 void ReturnStatement::Write(CodeWriter* to) const {
    310   to->Write("return ");
    311   this->expression->Write(to);
    312   to->Write(";\n");
    313 }
    314 
    315 void TryStatement::Write(CodeWriter* to) const {
    316   to->Write("try ");
    317   this->statements->Write(to);
    318 }
    319 
    320 CatchStatement::CatchStatement(Variable* e)
    321     : statements(new StatementBlock), exception(e) {}
    322 
    323 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 
    333 void FinallyStatement::Write(CodeWriter* to) const {
    334   to->Write("finally ");
    335   this->statements->Write(to);
    336 }
    337 
    338 Case::Case(const string& c) { cases.push_back(c); }
    339 
    340 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 
    357 SwitchStatement::SwitchStatement(Expression* e) : expression(e) {}
    358 
    359 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 
    370 void Break::Write(CodeWriter* to) const { to->Write("break;\n"); }
    371 
    372 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 
    420 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 
    425 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 
    430 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 
    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 
    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 
    504 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