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