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