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 
ClassDecl(const std::string & name,const std::string & parent)32 ClassDecl::ClassDecl(const std::string& name, const std::string& parent)
33     : name_(name),
34       parent_(parent) {}
35 
ClassDecl(const std::string & name,const std::string & parent,std::vector<unique_ptr<Declaration>> public_members,std::vector<unique_ptr<Declaration>> private_members)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 
Write(CodeWriter * to) const44 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 
AddPublic(std::unique_ptr<Declaration> member)67 void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) {
68   public_members_.push_back(std::move(member));
69 }
70 
AddPrivate(std::unique_ptr<Declaration> member)71 void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) {
72   private_members_.push_back(std::move(member));
73 }
74 
EnumField(const string & k,const string & v)75 Enum::EnumField::EnumField(const string& k, const string& v)
76     : key(k),
77       value(v) {}
78 
Enum(const string & name,const string & base_type)79 Enum::Enum(const string& name, const string& base_type)
80     : enum_name_(name), underlying_type_(base_type) {}
81 
Enum(const string & name)82 Enum::Enum(const string& name) : Enum(name, "") {}
83 
Write(CodeWriter * to) const84 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 
AddValue(const string & key,const string & value)100 void Enum::AddValue(const string& key, const string& value) {
101   fields_.emplace_back(key, value);
102 }
103 
ArgList(const std::string & single_argument)104 ArgList::ArgList(const std::string& single_argument)
105     : ArgList(vector<string>{single_argument}) {}
106 
ArgList(const std::vector<std::string> & arg_list)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 
ArgList(std::vector<std::unique_ptr<AstNode>> arg_list)113 ArgList::ArgList(std::vector<std::unique_ptr<AstNode>> arg_list)
114     : arguments_(std::move(arg_list)) {}
115 
ArgList(ArgList && arg_list)116 ArgList::ArgList(ArgList&& arg_list)
117     : arguments_(std::move(arg_list.arguments_)) {}
118 
Write(CodeWriter * to) const119 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 
ConstructorDecl(const std::string & name,ArgList && arg_list)130 ConstructorDecl::ConstructorDecl(
131     const std::string& name,
132     ArgList&& arg_list)
133     : ConstructorDecl(name, std::move(arg_list), 0u) {}
134 
ConstructorDecl(const std::string & name,ArgList && arg_list,uint32_t modifiers)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 
Write(CodeWriter * to) const143 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 
MacroDecl(const std::string & name,ArgList && arg_list)160 MacroDecl::MacroDecl(const std::string& name, ArgList&& arg_list)
161     : name_(name),
162       arguments_(std::move(arg_list)) {}
163 
Write(CodeWriter * to) const164 void MacroDecl::Write(CodeWriter* to) const {
165   to->Write("%s", name_.c_str());
166   arguments_.Write(to);
167   to->Write("\n");
168 }
169 
MethodDecl(const std::string & return_type,const std::string & name,ArgList && arg_list)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 
MethodDecl(const std::string & return_type,const std::string & name,ArgList && arg_list,uint32_t modifiers)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 
Write(CodeWriter * to) const188 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 
AddStatement(unique_ptr<AstNode> statement)211 void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
212   statements_.push_back(std::move(statement));
213 }
214 
AddStatement(AstNode * statement)215 void StatementBlock::AddStatement(AstNode* statement) {
216   statements_.emplace_back(statement);
217 }
218 
AddLiteral(const std::string & expression_str,bool add_semicolon)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 
Write(CodeWriter * to) const229 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 
ConstructorImpl(const string & class_name,ArgList && arg_list,const vector<string> & initializer_list)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 
Write(CodeWriter * to) const244 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 
MethodImpl(const string & return_type,const string & class_name,const string & method_name,ArgList && arg_list,bool is_const_method)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 
GetStatementBlock()276 StatementBlock* MethodImpl::GetStatementBlock() {
277   return &statements_;
278 }
279 
Write(CodeWriter * to) const280 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 
SwitchStatement(const std::string & expression)287 SwitchStatement::SwitchStatement(const std::string& expression)
288     : switch_expression_(expression) {}
289 
AddCase(const string & value_expression)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 
Write(CodeWriter * to) const302 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 
Assignment(const std::string & left,const std::string & right)319 Assignment::Assignment(const std::string& left, const std::string& right)
320     : Assignment(left, new LiteralExpression{right}) {}
321 
Assignment(const std::string & left,AstNode * right)322 Assignment::Assignment(const std::string& left, AstNode* right)
323     : lhs_(left),
324       rhs_(right) {}
325 
Write(CodeWriter * to) const326 void Assignment::Write(CodeWriter* to) const {
327   to->Write("%s = ", lhs_.c_str());
328   rhs_->Write(to);
329   to->Write(";\n");
330 }
331 
MethodCall(const std::string & method_name,const std::string & single_argument)332 MethodCall::MethodCall(const std::string& method_name,
333                        const std::string& single_argument)
334     : MethodCall(method_name, ArgList{single_argument}) {}
335 
MethodCall(const std::string & method_name,ArgList && arg_list)336 MethodCall::MethodCall(const std::string& method_name,
337                        ArgList&& arg_list)
338     : method_name_(method_name),
339       arguments_{std::move(arg_list)} {}
340 
Write(CodeWriter * to) const341 void MethodCall::Write(CodeWriter* to) const {
342   to->Write("%s", method_name_.c_str());
343   arguments_.Write(to);
344 }
345 
IfStatement(AstNode * expression,bool invert_expression)346 IfStatement::IfStatement(AstNode* expression, bool invert_expression)
347     : expression_(expression),
348       invert_expression_(invert_expression) {}
349 
Write(CodeWriter * to) const350 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 
Statement(unique_ptr<AstNode> expression)362 Statement::Statement(unique_ptr<AstNode> expression)
363     : expression_(std::move(expression)) {}
364 
Statement(AstNode * expression)365 Statement::Statement(AstNode* expression) : expression_(expression) {}
366 
Statement(const string & expression)367 Statement::Statement(const string& expression)
368     : expression_(new LiteralExpression(expression)) {}
369 
Write(CodeWriter * to) const370 void Statement::Write(CodeWriter* to) const {
371   expression_->Write(to);
372   to->Write(";\n");
373 }
374 
Comparison(AstNode * lhs,const string & comparison,AstNode * rhs)375 Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs)
376     : left_(lhs),
377       right_(rhs),
378       operator_(comparison) {}
379 
Write(CodeWriter * to) const380 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 
LiteralExpression(const std::string & expression)388 LiteralExpression::LiteralExpression(const std::string& expression)
389     : expression_(expression) {}
390 
Write(CodeWriter * to) const391 void LiteralExpression::Write(CodeWriter* to) const {
392   to->Write("%s", expression_.c_str());
393 }
394 
CppNamespace(const std::string & name,std::vector<unique_ptr<Declaration>> declarations)395 CppNamespace::CppNamespace(const std::string& name,
396                            std::vector<unique_ptr<Declaration>> declarations)
397     : declarations_(std::move(declarations)),
398       name_(name) {}
399 
CppNamespace(const std::string & name,unique_ptr<Declaration> declaration)400 CppNamespace::CppNamespace(const std::string& name,
401                            unique_ptr<Declaration> declaration)
402     : name_(name) {
403   declarations_.push_back(std::move(declaration));
404 }
CppNamespace(const std::string & name)405 CppNamespace::CppNamespace(const std::string& name)
406     : name_(name) {}
407 
Write(CodeWriter * to) const408 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 
Document(const std::vector<std::string> & include_list,unique_ptr<CppNamespace> a_namespace)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 
Write(CodeWriter * to) const424 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 
CppHeader(const std::string & include_guard,const std::vector<std::string> & include_list,unique_ptr<CppNamespace> a_namespace)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 
Write(CodeWriter * to) const439 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 
CppSource(const std::vector<std::string> & include_list,unique_ptr<CppNamespace> a_namespace)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