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