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_cpp.h" 18 19 #include <algorithm> 20 21 #include <android-base/strings.h> 22 23 #include "code_writer.h" 24 #include "logging.h" 25 26 using std::string; 27 using std::unique_ptr; 28 using std::vector; 29 30 namespace android { 31 namespace aidl { 32 namespace cpp { 33 34 std::string AstNode::ToString() { 35 std::string str; 36 Write(CodeWriter::ForString(&str).get()); 37 return str; 38 } 39 40 LiteralDecl::LiteralDecl(const std::string& expression) : expression_(expression) {} 41 42 void LiteralDecl::Write(CodeWriter* to) const { 43 to->Write("%s", expression_.c_str()); 44 } 45 46 ClassDecl::ClassDecl(const std::string& name, const std::string& parent, 47 const std::vector<std::string>& template_params, const std::string& attributes) 48 : name_(name), parent_(parent), attributes_(attributes), template_params_(template_params) {} 49 50 ClassDecl::ClassDecl(const std::string& name, const std::string& parent, 51 const std::vector<std::string>& template_params, 52 std::vector<unique_ptr<Declaration>> public_members, 53 std::vector<unique_ptr<Declaration>> private_members, 54 const std::string& attributes) 55 : name_(name), 56 parent_(parent), 57 attributes_(attributes), 58 template_params_(template_params), 59 public_members_(std::move(public_members)), 60 private_members_(std::move(private_members)) {} 61 62 void ClassDecl::Write(CodeWriter* to) const { 63 if (!template_params_.empty()) 64 to->Write("template <typename %s>\n", base::Join(template_params_, ", typename ").c_str()); 65 66 to->Write("class"); 67 if (!attributes_.empty()) { 68 to->Write(" %s", attributes_.c_str()); 69 } 70 to->Write(" %s ", name_.c_str()); 71 72 if (parent_.length() > 0) to->Write(": public %s ", parent_.c_str()); 73 74 to->Write("{\n"); 75 76 if (!public_members_.empty()) to->Write("public:\n"); 77 78 to->Indent(); 79 for (const auto& dec : public_members_) 80 dec->Write(to); 81 to->Dedent(); 82 83 if (!private_members_.empty()) to->Write("private:\n"); 84 85 to->Indent(); 86 for (const auto& dec : private_members_) 87 dec->Write(to); 88 to->Dedent(); 89 90 to->Write("}; // class %s\n", name_.c_str()); 91 } 92 93 void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) { 94 public_members_.push_back(std::move(member)); 95 } 96 97 void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) { 98 private_members_.push_back(std::move(member)); 99 } 100 101 Enum::EnumField::EnumField(const string& k, const string& v, const string& a) 102 : key(k), value(v), attribute(a) {} 103 104 Enum::Enum(const string& name, const string& base_type, bool is_class, 105 const std::string& attributes) 106 : enum_name_(name), underlying_type_(base_type), attributes_(attributes), is_class_(is_class) {} 107 108 void Enum::Write(CodeWriter* to) const { 109 to->Write("enum "); 110 if (is_class_) { 111 to->Write("class "); 112 } 113 if (!attributes_.empty()) { 114 to->Write("%s ", attributes_.c_str()); 115 } 116 if (underlying_type_.empty()) { 117 to->Write("%s {\n", enum_name_.c_str()); 118 } else { 119 to->Write("%s : %s {\n", enum_name_.c_str(), underlying_type_.c_str()); 120 } 121 to->Indent(); 122 for (const auto& field : fields_) { 123 to->Write("%s", field.key.c_str()); 124 if (!field.attribute.empty()) { 125 to->Write(" %s", field.attribute.c_str()); 126 } 127 if (!field.value.empty()) { 128 to->Write(" = %s", field.value.c_str()); 129 } 130 to->Write(",\n"); 131 } 132 to->Dedent(); 133 to->Write("};\n"); 134 } 135 136 void Enum::AddValue(const string& key, const string& value, const string& attribute) { 137 fields_.emplace_back(key, value, attribute); 138 } 139 140 ArgList::ArgList(const std::string& single_argument) 141 : ArgList(vector<string>{single_argument}) {} 142 143 ArgList::ArgList(const std::vector<std::string>& arg_list) { 144 for (const auto& s : arg_list) { 145 arguments_.emplace_back(new LiteralExpression(s)); 146 } 147 } 148 149 ArgList::ArgList(std::vector<std::unique_ptr<AstNode>> arg_list) 150 : arguments_(std::move(arg_list)) {} 151 152 ArgList::ArgList(ArgList&& arg_list) noexcept : arguments_(std::move(arg_list.arguments_)) {} 153 154 void ArgList::Write(CodeWriter* to) const { 155 to->Write("("); 156 bool is_first = true; 157 for (const auto& s : arguments_) { 158 if (!is_first) { to->Write(", "); } 159 is_first = false; 160 s->Write(to); 161 } 162 to->Write(")"); 163 } 164 165 ConstructorDecl::ConstructorDecl( 166 const std::string& name, 167 ArgList&& arg_list) 168 : ConstructorDecl(name, std::move(arg_list), 0u) {} 169 170 ConstructorDecl::ConstructorDecl( 171 const std::string& name, 172 ArgList&& arg_list, 173 uint32_t modifiers) 174 : name_(name), 175 arguments_(std::move(arg_list)), 176 modifiers_(modifiers) {} 177 178 void ConstructorDecl::Write(CodeWriter* to) const { 179 if (modifiers_ & Modifiers::IS_VIRTUAL) 180 to->Write("virtual "); 181 182 if (modifiers_ & Modifiers::IS_EXPLICIT) 183 to->Write("explicit "); 184 185 to->Write("%s", name_.c_str()); 186 187 arguments_.Write(to); 188 189 if (modifiers_ & Modifiers::IS_DEFAULT) 190 to->Write(" = default"); 191 192 to->Write(";\n"); 193 } 194 195 MacroDecl::MacroDecl(const std::string& name, ArgList&& arg_list) 196 : name_(name), 197 arguments_(std::move(arg_list)) {} 198 199 void MacroDecl::Write(CodeWriter* to) const { 200 to->Write("%s", name_.c_str()); 201 arguments_.Write(to); 202 to->Write("\n"); 203 } 204 205 MethodDecl::MethodDecl(const std::string& return_type, const std::string& name, ArgList&& arg_list, 206 const std::string& attributes) 207 : MethodDecl(return_type, name, std::move(arg_list), 0u, attributes) {} 208 209 MethodDecl::MethodDecl(const std::string& return_type, const std::string& name, ArgList&& arg_list, 210 uint32_t modifiers, const std::string& attributes) 211 : return_type_(return_type), 212 name_(name), 213 attributes_(attributes), 214 arguments_(std::move(arg_list)), 215 is_const_(modifiers & IS_CONST), 216 is_virtual_(modifiers & IS_VIRTUAL), 217 is_override_(modifiers & IS_OVERRIDE), 218 is_pure_virtual_(modifiers & IS_PURE_VIRTUAL), 219 is_static_(modifiers & IS_STATIC), 220 is_final_(modifiers & IS_FINAL) {} 221 222 void MethodDecl::Write(CodeWriter* to) const { 223 if (is_virtual_) 224 to->Write("virtual "); 225 226 if (is_static_) 227 to->Write("static "); 228 229 to->Write("%s %s", return_type_.c_str(), name_.c_str()); 230 231 arguments_.Write(to); 232 233 if (is_const_) 234 to->Write(" const"); 235 236 if (is_override_) 237 to->Write(" override"); 238 239 if (is_final_) to->Write(" final"); 240 241 if (!attributes_.empty()) to->Write(" %s", attributes_.c_str()); 242 243 if (is_pure_virtual_) 244 to->Write(" = 0"); 245 246 to->Write(";\n"); 247 } 248 249 void StatementBlock::AddStatement(unique_ptr<AstNode> statement) { 250 statements_.push_back(std::move(statement)); 251 } 252 253 void StatementBlock::AddStatement(AstNode* statement) { 254 statements_.emplace_back(statement); 255 } 256 257 void StatementBlock::AddLiteral(const std::string& expression_str, 258 bool add_semicolon) { 259 if (add_semicolon) { 260 statements_.push_back(unique_ptr<AstNode>(new Statement(expression_str))); 261 } else { 262 statements_.push_back(unique_ptr<AstNode>( 263 new LiteralExpression(expression_str))); 264 } 265 } 266 267 void StatementBlock::Write(CodeWriter* to) const { 268 to->Write("{\n"); 269 to->Indent(); 270 for (const auto& statement : statements_) { 271 statement->Write(to); 272 } 273 to->Dedent(); 274 to->Write("}\n"); 275 } 276 277 ConstructorImpl::ConstructorImpl(const string& class_name, 278 ArgList&& arg_list, 279 const vector<string>& initializer_list) 280 : class_name_(class_name), 281 arguments_(std::move(arg_list)), 282 initializer_list_(initializer_list) {} 283 284 StatementBlock* ConstructorImpl::GetStatementBlock() { 285 return &body_; 286 } 287 288 void ConstructorImpl::Write(CodeWriter* to) const { 289 to->Write("%s::%s", class_name_.c_str(), class_name_.c_str()); 290 arguments_.Write(to); 291 to->Write("\n"); 292 293 bool is_first = true; 294 for (const string& i : initializer_list_) { 295 if (is_first) { 296 to->Write(" : %s", i.c_str()); 297 } else { 298 to->Write(",\n %s", i.c_str()); 299 } 300 is_first = false; 301 } 302 303 body_.Write(to); 304 } 305 306 MethodImpl::MethodImpl(const string& return_type, const string& class_name, 307 const string& method_name, const std::vector<std::string>& template_params, 308 ArgList&& arg_list, bool is_const_method) 309 : return_type_(return_type), 310 method_name_(method_name), 311 arguments_(std::move(arg_list)), 312 is_const_method_(is_const_method), 313 template_params_(template_params) { 314 if (!class_name.empty()) { 315 if (!template_params.empty()) { 316 method_name_ = class_name + "<" + base::Join(template_params, ",") + ">::" + method_name; 317 } else { 318 method_name_ = class_name + "::" + method_name; 319 } 320 } 321 } 322 323 StatementBlock* MethodImpl::GetStatementBlock() { 324 return &statements_; 325 } 326 327 void MethodImpl::Write(CodeWriter* to) const { 328 if (!template_params_.empty()) 329 to->Write("template <typename %s>\n", base::Join(template_params_, ", typename ").c_str()); 330 to->Write("%s %s", return_type_.c_str(), method_name_.c_str()); 331 arguments_.Write(to); 332 to->Write("%s ", (is_const_method_) ? " const" : ""); 333 statements_.Write(to); 334 } 335 336 SwitchStatement::SwitchStatement(const std::string& expression) 337 : switch_expression_(expression) {} 338 339 StatementBlock* SwitchStatement::AddCase(const string& value_expression) { 340 auto it = std::find(case_values_.begin(), case_values_.end(), value_expression); 341 if (it != case_values_.end()) { 342 AIDL_ERROR(value_expression) << "Duplicate switch case labels"; 343 return nullptr; 344 } 345 StatementBlock* ret = new StatementBlock(); 346 case_values_.push_back(value_expression); 347 case_logic_.push_back(unique_ptr<StatementBlock>{ret}); 348 return ret; 349 } 350 351 void SwitchStatement::Write(CodeWriter* to) const { 352 to->Write("switch (%s) {\n", switch_expression_.c_str()); 353 for (size_t i = 0; i < case_values_.size(); ++i) { 354 const string& case_value = case_values_[i]; 355 const unique_ptr<StatementBlock>& statements = case_logic_[i]; 356 if (case_value.empty()) { 357 to->Write("default:\n"); 358 } else { 359 to->Write("case %s:\n", case_value.c_str()); 360 } 361 statements->Write(to); 362 to->Write("break;\n"); 363 } 364 to->Write("}\n"); 365 } 366 367 368 Assignment::Assignment(const std::string& left, const std::string& right) 369 : Assignment(left, new LiteralExpression{right}) {} 370 371 Assignment::Assignment(const std::string& left, AstNode* right) 372 : lhs_(left), 373 rhs_(right) {} 374 375 void Assignment::Write(CodeWriter* to) const { 376 to->Write("%s = ", lhs_.c_str()); 377 rhs_->Write(to); 378 to->Write(";\n"); 379 } 380 381 MethodCall::MethodCall(const std::string& method_name, 382 const std::string& single_argument) 383 : MethodCall(method_name, ArgList{single_argument}) {} 384 385 MethodCall::MethodCall(const std::string& method_name, 386 ArgList&& arg_list) 387 : method_name_(method_name), 388 arguments_{std::move(arg_list)} {} 389 390 void MethodCall::Write(CodeWriter* to) const { 391 to->Write("%s", method_name_.c_str()); 392 arguments_.Write(to); 393 } 394 395 IfStatement::IfStatement(AstNode* expression, bool invert_expression) 396 : expression_(expression), 397 invert_expression_(invert_expression) {} 398 399 void IfStatement::Write(CodeWriter* to) const { 400 to->Write("if (%s", (invert_expression_) ? "!(" : ""); 401 expression_->Write(to); 402 to->Write(")%s ", (invert_expression_) ? ")" : ""); 403 on_true_.Write(to); 404 405 if (!on_false_.Empty()) { 406 to->Write("else "); 407 on_false_.Write(to); 408 } 409 } 410 411 Statement::Statement(unique_ptr<AstNode> expression) 412 : expression_(std::move(expression)) {} 413 414 Statement::Statement(AstNode* expression) : expression_(expression) {} 415 416 Statement::Statement(const string& expression) 417 : expression_(new LiteralExpression(expression)) {} 418 419 void Statement::Write(CodeWriter* to) const { 420 expression_->Write(to); 421 to->Write(";\n"); 422 } 423 424 Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs) 425 : left_(lhs), 426 right_(rhs), 427 operator_(comparison) {} 428 429 void Comparison::Write(CodeWriter* to) const { 430 to->Write("(("); 431 left_->Write(to); 432 to->Write(") %s (", operator_.c_str()); 433 right_->Write(to); 434 to->Write("))"); 435 } 436 437 LiteralExpression::LiteralExpression(const std::string& expression) 438 : expression_(expression) {} 439 440 void LiteralExpression::Write(CodeWriter* to) const { 441 to->Write("%s", expression_.c_str()); 442 } 443 444 CppNamespace::CppNamespace(const std::string& name, 445 std::vector<unique_ptr<Declaration>> declarations) 446 : declarations_(std::move(declarations)), 447 name_(name) {} 448 449 CppNamespace::CppNamespace(const std::string& name, 450 unique_ptr<Declaration> declaration) 451 : name_(name) { 452 declarations_.push_back(std::move(declaration)); 453 } 454 CppNamespace::CppNamespace(const std::string& name) 455 : name_(name) {} 456 457 void CppNamespace::Write(CodeWriter* to) const { 458 to->Write("namespace %s {\n\n", name_.c_str()); 459 460 for (const auto& dec : declarations_) { 461 dec->Write(to); 462 to->Write("\n"); 463 } 464 465 to->Write("} // namespace %s\n", name_.c_str()); 466 } 467 468 Document::Document(const std::vector<std::string>& include_list, 469 std::vector<unique_ptr<Declaration>> declarations) 470 : include_list_(include_list), declarations_(std::move(declarations)) {} 471 472 void Document::Write(CodeWriter* to) const { 473 for (const auto& include : include_list_) { 474 to->Write("#include <%s>\n", include.c_str()); 475 } 476 to->Write("\n"); 477 478 for (const auto& declaration : declarations_) { 479 declaration->Write(to); 480 } 481 } 482 483 CppHeader::CppHeader(const std::vector<std::string>& include_list, 484 std::vector<std::unique_ptr<Declaration>> declarations) 485 : Document(include_list, std::move(declarations)) {} 486 487 void CppHeader::Write(CodeWriter* to) const { 488 to->Write("#pragma once\n\n"); 489 490 Document::Write(to); 491 } 492 493 CppSource::CppSource(const std::vector<std::string>& include_list, 494 std::vector<std::unique_ptr<Declaration>> declarations) 495 : Document(include_list, std::move(declarations)) {} 496 497 } // namespace cpp 498 } // namespace aidl 499 } // namespace android 500