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 MethodDecl::MethodDecl(const std::string& return_type,
    161                        const std::string& name,
    162                        ArgList&& arg_list)
    163     : MethodDecl(return_type, name, std::move(arg_list), 0u) {}
    164 
    165 MethodDecl::MethodDecl(const std::string& return_type,
    166                        const std::string& name,
    167                        ArgList&& arg_list,
    168                        uint32_t modifiers)
    169     : return_type_(return_type),
    170       name_(name),
    171       arguments_(std::move(arg_list)),
    172       is_const_(modifiers & IS_CONST),
    173       is_virtual_(modifiers & IS_VIRTUAL),
    174       is_override_(modifiers & IS_OVERRIDE),
    175       is_pure_virtual_(modifiers & IS_PURE_VIRTUAL) {}
    176 
    177 void MethodDecl::Write(CodeWriter* to) const {
    178   if (is_virtual_)
    179     to->Write("virtual ");
    180 
    181   to->Write("%s %s", return_type_.c_str(), name_.c_str());
    182 
    183   arguments_.Write(to);
    184 
    185   if (is_const_)
    186     to->Write(" const");
    187 
    188   if (is_override_)
    189     to->Write(" override");
    190 
    191   if (is_pure_virtual_)
    192     to->Write(" = 0");
    193 
    194   to->Write(";\n");
    195 }
    196 
    197 void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
    198   statements_.push_back(std::move(statement));
    199 }
    200 
    201 void StatementBlock::AddStatement(AstNode* statement) {
    202   statements_.emplace_back(statement);
    203 }
    204 
    205 void StatementBlock::AddLiteral(const std::string& expression_str,
    206                                 bool add_semicolon) {
    207   if (add_semicolon) {
    208     statements_.push_back(unique_ptr<AstNode>(new Statement(expression_str)));
    209   } else {
    210     statements_.push_back(unique_ptr<AstNode>(
    211         new LiteralExpression(expression_str)));
    212   }
    213 }
    214 
    215 void StatementBlock::Write(CodeWriter* to) const {
    216   to->Write("{\n");
    217   for (const auto& statement : statements_) {
    218     statement->Write(to);
    219   }
    220   to->Write("}\n");
    221 }
    222 
    223 ConstructorImpl::ConstructorImpl(const string& class_name,
    224                                  ArgList&& arg_list,
    225                                  const vector<string>& initializer_list)
    226       : class_name_(class_name),
    227         arguments_(std::move(arg_list)),
    228         initializer_list_(initializer_list) {}
    229 
    230 void ConstructorImpl::Write(CodeWriter* to) const {
    231   to->Write("%s::%s", class_name_.c_str(), class_name_.c_str());
    232   arguments_.Write(to);
    233   to->Write("\n");
    234 
    235   bool is_first = true;
    236   for (const string& i : initializer_list_) {
    237     if (is_first) {
    238       to->Write("    : %s", i.c_str());
    239     } else {
    240       to->Write(",\n      %s", i.c_str());
    241     }
    242     is_first = false;
    243   }
    244 
    245   body_.Write(to);
    246 }
    247 
    248 MethodImpl::MethodImpl(const string& return_type,
    249                        const string& class_name,
    250                        const string& method_name,
    251                        ArgList&& arg_list,
    252                        bool is_const_method)
    253     : return_type_(return_type),
    254       method_name_(method_name),
    255       arguments_(std::move(arg_list)),
    256       is_const_method_(is_const_method) {
    257   if (!class_name.empty()) {
    258     method_name_ = class_name + "::" + method_name;
    259   }
    260 }
    261 
    262 StatementBlock* MethodImpl::GetStatementBlock() {
    263   return &statements_;
    264 }
    265 
    266 void MethodImpl::Write(CodeWriter* to) const {
    267   to->Write("%s %s", return_type_.c_str(), method_name_.c_str());
    268   arguments_.Write(to);
    269   to->Write("%s ", (is_const_method_) ? " const" : "");
    270   statements_.Write(to);
    271 }
    272 
    273 SwitchStatement::SwitchStatement(const std::string& expression)
    274     : switch_expression_(expression) {}
    275 
    276 StatementBlock* SwitchStatement::AddCase(const string& value_expression) {
    277   auto it = std::find(case_values_.begin(), case_values_.end(), value_expression);
    278   if (it != case_values_.end()) {
    279     LOG(ERROR) << "internal error: duplicate switch case labels";
    280     return nullptr;
    281   }
    282   StatementBlock* ret = new StatementBlock();
    283   case_values_.push_back(value_expression);
    284   case_logic_.push_back(unique_ptr<StatementBlock>{ret});
    285   return ret;
    286 }
    287 
    288 void SwitchStatement::Write(CodeWriter* to) const {
    289   to->Write("switch (%s) {\n", switch_expression_.c_str());
    290   for (size_t i = 0; i < case_values_.size(); ++i) {
    291     const string& case_value = case_values_[i];
    292     const unique_ptr<StatementBlock>& statements = case_logic_[i];
    293     if (case_value.empty()) {
    294       to->Write("default:\n");
    295     } else {
    296       to->Write("case %s:\n", case_value.c_str());
    297     }
    298     statements->Write(to);
    299     to->Write("break;\n");
    300   }
    301   to->Write("}\n");
    302 }
    303 
    304 
    305 Assignment::Assignment(const std::string& left, const std::string& right)
    306     : Assignment(left, new LiteralExpression{right}) {}
    307 
    308 Assignment::Assignment(const std::string& left, AstNode* right)
    309     : lhs_(left),
    310       rhs_(right) {}
    311 
    312 void Assignment::Write(CodeWriter* to) const {
    313   to->Write("%s = ", lhs_.c_str());
    314   rhs_->Write(to);
    315   to->Write(";\n");
    316 }
    317 
    318 MethodCall::MethodCall(const std::string& method_name,
    319                        const std::string& single_argument)
    320     : MethodCall(method_name, ArgList{single_argument}) {}
    321 
    322 MethodCall::MethodCall(const std::string& method_name,
    323                        ArgList&& arg_list)
    324     : method_name_(method_name),
    325       arguments_{std::move(arg_list)} {}
    326 
    327 void MethodCall::Write(CodeWriter* to) const {
    328   to->Write("%s", method_name_.c_str());
    329   arguments_.Write(to);
    330 }
    331 
    332 IfStatement::IfStatement(AstNode* expression, bool invert_expression)
    333     : expression_(expression),
    334       invert_expression_(invert_expression) {}
    335 
    336 void IfStatement::Write(CodeWriter* to) const {
    337   to->Write("if (%s", (invert_expression_) ? "!(" : "");
    338   expression_->Write(to);
    339   to->Write(")%s ", (invert_expression_) ? ")" : "");
    340   on_true_.Write(to);
    341 
    342   if (!on_false_.Empty()) {
    343     to->Write("else ");
    344     on_false_.Write(to);
    345   }
    346 }
    347 
    348 Statement::Statement(unique_ptr<AstNode> expression)
    349     : expression_(std::move(expression)) {}
    350 
    351 Statement::Statement(AstNode* expression) : expression_(expression) {}
    352 
    353 Statement::Statement(const string& expression)
    354     : expression_(new LiteralExpression(expression)) {}
    355 
    356 void Statement::Write(CodeWriter* to) const {
    357   expression_->Write(to);
    358   to->Write(";\n");
    359 }
    360 
    361 Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs)
    362     : left_(lhs),
    363       right_(rhs),
    364       operator_(comparison) {}
    365 
    366 void Comparison::Write(CodeWriter* to) const {
    367   to->Write("((");
    368   left_->Write(to);
    369   to->Write(") %s (", operator_.c_str());
    370   right_->Write(to);
    371   to->Write("))");
    372 }
    373 
    374 LiteralExpression::LiteralExpression(const std::string& expression)
    375     : expression_(expression) {}
    376 
    377 void LiteralExpression::Write(CodeWriter* to) const {
    378   to->Write("%s", expression_.c_str());
    379 }
    380 
    381 CppNamespace::CppNamespace(const std::string& name,
    382                            std::vector<unique_ptr<Declaration>> declarations)
    383     : declarations_(std::move(declarations)),
    384       name_(name) {}
    385 
    386 CppNamespace::CppNamespace(const std::string& name,
    387                            unique_ptr<Declaration> declaration)
    388     : name_(name) {
    389   declarations_.push_back(std::move(declaration));
    390 }
    391 CppNamespace::CppNamespace(const std::string& name)
    392     : name_(name) {}
    393 
    394 void CppNamespace::Write(CodeWriter* to) const {
    395   to->Write("namespace %s {\n\n", name_.c_str());
    396 
    397   for (const auto& dec : declarations_) {
    398     dec->Write(to);
    399     to->Write("\n");
    400   }
    401 
    402   to->Write("}  // namespace %s\n", name_.c_str());
    403 }
    404 
    405 Document::Document(const std::vector<std::string>& include_list,
    406                    unique_ptr<CppNamespace> a_namespace)
    407     : include_list_(include_list),
    408       namespace_(std::move(a_namespace)) {}
    409 
    410 void Document::Write(CodeWriter* to) const {
    411   for (const auto& include : include_list_) {
    412     to->Write("#include <%s>\n", include.c_str());
    413   }
    414   to->Write("\n");
    415 
    416   namespace_->Write(to);
    417 }
    418 
    419 CppHeader::CppHeader(const std::string& include_guard,
    420                      const std::vector<std::string>& include_list,
    421                      unique_ptr<CppNamespace> a_namespace)
    422     : Document(include_list, std::move(a_namespace)),
    423       include_guard_(include_guard) {}
    424 
    425 void CppHeader::Write(CodeWriter* to) const {
    426   to->Write("#ifndef %s\n", include_guard_.c_str());
    427   to->Write("#define %s\n\n", include_guard_.c_str());
    428 
    429   Document::Write(to);
    430   to->Write("\n");
    431 
    432   to->Write("#endif  // %s", include_guard_.c_str());
    433 }
    434 
    435 CppSource::CppSource(const std::vector<std::string>& include_list,
    436                      unique_ptr<CppNamespace> a_namespace)
    437     : Document(include_list, std::move(a_namespace)) {}
    438 
    439 }  // namespace cpp
    440 }  // namespace aidl
    441 }  // namespace android
    442