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