• 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 <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 
ToString()34 std::string AstNode::ToString() {
35   std::string str;
36   Write(CodeWriter::ForString(&str).get());
37   return str;
38 }
39 
LiteralDecl(const std::string & expression)40 LiteralDecl::LiteralDecl(const std::string& expression) : expression_(expression) {}
41 
Write(CodeWriter * to) const42 void LiteralDecl::Write(CodeWriter* to) const {
43   to->Write("%s", expression_.c_str());
44 }
45 
ClassDecl(const std::string & name,const std::string & parent,const std::vector<std::string> & template_params,const std::string & attributes)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 
ClassDecl(const std::string & name,const std::string & parent,const std::vector<std::string> & template_params,std::vector<unique_ptr<Declaration>> public_members,std::vector<unique_ptr<Declaration>> private_members,const std::string & attributes)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 
Write(CodeWriter * to) const62 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 
AddPublic(std::unique_ptr<Declaration> member)93 void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) {
94   public_members_.push_back(std::move(member));
95 }
96 
AddPrivate(std::unique_ptr<Declaration> member)97 void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) {
98   private_members_.push_back(std::move(member));
99 }
100 
EnumField(const string & k,const string & v,const string & a)101 Enum::EnumField::EnumField(const string& k, const string& v, const string& a)
102     : key(k), value(v), attribute(a) {}
103 
Enum(const string & name,const string & base_type,bool is_class,const std::string & attributes)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 
Write(CodeWriter * to) const108 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 
AddValue(const string & key,const string & value,const string & attribute)136 void Enum::AddValue(const string& key, const string& value, const string& attribute) {
137   fields_.emplace_back(key, value, attribute);
138 }
139 
ArgList(const std::string & single_argument)140 ArgList::ArgList(const std::string& single_argument)
141     : ArgList(vector<string>{single_argument}) {}
142 
ArgList(const std::vector<std::string> & arg_list)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 
ArgList(std::vector<std::unique_ptr<AstNode>> arg_list)149 ArgList::ArgList(std::vector<std::unique_ptr<AstNode>> arg_list)
150     : arguments_(std::move(arg_list)) {}
151 
ArgList(ArgList && arg_list)152 ArgList::ArgList(ArgList&& arg_list) noexcept : arguments_(std::move(arg_list.arguments_)) {}
153 
Write(CodeWriter * to) const154 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 
ConstructorDecl(const std::string & name,ArgList && arg_list)165 ConstructorDecl::ConstructorDecl(
166     const std::string& name,
167     ArgList&& arg_list)
168     : ConstructorDecl(name, std::move(arg_list), 0u) {}
169 
ConstructorDecl(const std::string & name,ArgList && arg_list,uint32_t modifiers)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 
Write(CodeWriter * to) const178 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 
MacroDecl(const std::string & name,ArgList && arg_list)195 MacroDecl::MacroDecl(const std::string& name, ArgList&& arg_list)
196     : name_(name),
197       arguments_(std::move(arg_list)) {}
198 
Write(CodeWriter * to) const199 void MacroDecl::Write(CodeWriter* to) const {
200   to->Write("%s", name_.c_str());
201   arguments_.Write(to);
202   to->Write("\n");
203 }
204 
MethodDecl(const std::string & return_type,const std::string & name,ArgList && arg_list,const std::string & attributes)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 
MethodDecl(const std::string & return_type,const std::string & name,ArgList && arg_list,uint32_t modifiers,const std::string & attributes)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 
Write(CodeWriter * to) const222 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 
AddStatement(unique_ptr<AstNode> statement)249 void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
250   statements_.push_back(std::move(statement));
251 }
252 
AddStatement(AstNode * statement)253 void StatementBlock::AddStatement(AstNode* statement) {
254   statements_.emplace_back(statement);
255 }
256 
AddLiteral(const std::string & expression_str,bool add_semicolon)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 
Write(CodeWriter * to) const267 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 
ConstructorImpl(const string & class_name,ArgList && arg_list,const vector<string> & initializer_list)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 
GetStatementBlock()284 StatementBlock* ConstructorImpl::GetStatementBlock() {
285   return &body_;
286 }
287 
Write(CodeWriter * to) const288 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 
MethodImpl(const string & return_type,const string & class_name,const string & method_name,const std::vector<std::string> & template_params,ArgList && arg_list,bool is_const_method)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 
GetStatementBlock()323 StatementBlock* MethodImpl::GetStatementBlock() {
324   return &statements_;
325 }
326 
Write(CodeWriter * to) const327 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 
SwitchStatement(const std::string & expression)336 SwitchStatement::SwitchStatement(const std::string& expression)
337     : switch_expression_(expression) {}
338 
AddCase(const string & value_expression)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 
Write(CodeWriter * to) const351 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 
Assignment(const std::string & left,const std::string & right)368 Assignment::Assignment(const std::string& left, const std::string& right)
369     : Assignment(left, new LiteralExpression{right}) {}
370 
Assignment(const std::string & left,AstNode * right)371 Assignment::Assignment(const std::string& left, AstNode* right)
372     : lhs_(left),
373       rhs_(right) {}
374 
Write(CodeWriter * to) const375 void Assignment::Write(CodeWriter* to) const {
376   to->Write("%s = ", lhs_.c_str());
377   rhs_->Write(to);
378   to->Write(";\n");
379 }
380 
MethodCall(const std::string & method_name,const std::string & single_argument)381 MethodCall::MethodCall(const std::string& method_name,
382                        const std::string& single_argument)
383     : MethodCall(method_name, ArgList{single_argument}) {}
384 
MethodCall(const std::string & method_name,ArgList && arg_list)385 MethodCall::MethodCall(const std::string& method_name,
386                        ArgList&& arg_list)
387     : method_name_(method_name),
388       arguments_{std::move(arg_list)} {}
389 
Write(CodeWriter * to) const390 void MethodCall::Write(CodeWriter* to) const {
391   to->Write("%s", method_name_.c_str());
392   arguments_.Write(to);
393 }
394 
IfStatement(AstNode * expression,bool invert_expression)395 IfStatement::IfStatement(AstNode* expression, bool invert_expression)
396     : expression_(expression),
397       invert_expression_(invert_expression) {}
398 
Write(CodeWriter * to) const399 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 
Statement(unique_ptr<AstNode> expression)411 Statement::Statement(unique_ptr<AstNode> expression)
412     : expression_(std::move(expression)) {}
413 
Statement(AstNode * expression)414 Statement::Statement(AstNode* expression) : expression_(expression) {}
415 
Statement(const string & expression)416 Statement::Statement(const string& expression)
417     : expression_(new LiteralExpression(expression)) {}
418 
Write(CodeWriter * to) const419 void Statement::Write(CodeWriter* to) const {
420   expression_->Write(to);
421   to->Write(";\n");
422 }
423 
Comparison(AstNode * lhs,const string & comparison,AstNode * rhs)424 Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs)
425     : left_(lhs),
426       right_(rhs),
427       operator_(comparison) {}
428 
Write(CodeWriter * to) const429 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 
LiteralExpression(const std::string & expression)437 LiteralExpression::LiteralExpression(const std::string& expression)
438     : expression_(expression) {}
439 
Write(CodeWriter * to) const440 void LiteralExpression::Write(CodeWriter* to) const {
441   to->Write("%s", expression_.c_str());
442 }
443 
CppNamespace(const std::string & name,std::vector<unique_ptr<Declaration>> declarations)444 CppNamespace::CppNamespace(const std::string& name,
445                            std::vector<unique_ptr<Declaration>> declarations)
446     : declarations_(std::move(declarations)),
447       name_(name) {}
448 
CppNamespace(const std::string & name,unique_ptr<Declaration> declaration)449 CppNamespace::CppNamespace(const std::string& name,
450                            unique_ptr<Declaration> declaration)
451     : name_(name) {
452   declarations_.push_back(std::move(declaration));
453 }
CppNamespace(const std::string & name)454 CppNamespace::CppNamespace(const std::string& name)
455     : name_(name) {}
456 
Write(CodeWriter * to) const457 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 
Document(const std::vector<std::string> & include_list,std::vector<unique_ptr<Declaration>> declarations)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 
Write(CodeWriter * to) const472 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 
CppHeader(const std::vector<std::string> & include_list,std::vector<std::unique_ptr<Declaration>> declarations)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 
Write(CodeWriter * to) const487 void CppHeader::Write(CodeWriter* to) const {
488   to->Write("#pragma once\n\n");
489 
490   Document::Write(to);
491 }
492 
CppSource(const std::vector<std::string> & include_list,std::vector<std::unique_ptr<Declaration>> declarations)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