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
MethodDecl(const std::string & return_type,const std::string & name,ArgList && arg_list)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
MethodDecl(const std::string & return_type,const std::string & name,ArgList && arg_list,uint32_t modifiers)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
Write(CodeWriter * to) const177 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
AddStatement(unique_ptr<AstNode> statement)197 void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
198 statements_.push_back(std::move(statement));
199 }
200
AddStatement(AstNode * statement)201 void StatementBlock::AddStatement(AstNode* statement) {
202 statements_.emplace_back(statement);
203 }
204
AddLiteral(const std::string & expression_str,bool add_semicolon)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
Write(CodeWriter * to) const215 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
ConstructorImpl(const string & class_name,ArgList && arg_list,const vector<string> & initializer_list)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
Write(CodeWriter * to) const230 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
MethodImpl(const string & return_type,const string & class_name,const string & method_name,ArgList && arg_list,bool is_const_method)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
GetStatementBlock()262 StatementBlock* MethodImpl::GetStatementBlock() {
263 return &statements_;
264 }
265
Write(CodeWriter * to) const266 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
SwitchStatement(const std::string & expression)273 SwitchStatement::SwitchStatement(const std::string& expression)
274 : switch_expression_(expression) {}
275
AddCase(const string & value_expression)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
Write(CodeWriter * to) const288 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
Assignment(const std::string & left,const std::string & right)305 Assignment::Assignment(const std::string& left, const std::string& right)
306 : Assignment(left, new LiteralExpression{right}) {}
307
Assignment(const std::string & left,AstNode * right)308 Assignment::Assignment(const std::string& left, AstNode* right)
309 : lhs_(left),
310 rhs_(right) {}
311
Write(CodeWriter * to) const312 void Assignment::Write(CodeWriter* to) const {
313 to->Write("%s = ", lhs_.c_str());
314 rhs_->Write(to);
315 to->Write(";\n");
316 }
317
MethodCall(const std::string & method_name,const std::string & single_argument)318 MethodCall::MethodCall(const std::string& method_name,
319 const std::string& single_argument)
320 : MethodCall(method_name, ArgList{single_argument}) {}
321
MethodCall(const std::string & method_name,ArgList && arg_list)322 MethodCall::MethodCall(const std::string& method_name,
323 ArgList&& arg_list)
324 : method_name_(method_name),
325 arguments_{std::move(arg_list)} {}
326
Write(CodeWriter * to) const327 void MethodCall::Write(CodeWriter* to) const {
328 to->Write("%s", method_name_.c_str());
329 arguments_.Write(to);
330 }
331
IfStatement(AstNode * expression,bool invert_expression)332 IfStatement::IfStatement(AstNode* expression, bool invert_expression)
333 : expression_(expression),
334 invert_expression_(invert_expression) {}
335
Write(CodeWriter * to) const336 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
Statement(unique_ptr<AstNode> expression)348 Statement::Statement(unique_ptr<AstNode> expression)
349 : expression_(std::move(expression)) {}
350
Statement(AstNode * expression)351 Statement::Statement(AstNode* expression) : expression_(expression) {}
352
Statement(const string & expression)353 Statement::Statement(const string& expression)
354 : expression_(new LiteralExpression(expression)) {}
355
Write(CodeWriter * to) const356 void Statement::Write(CodeWriter* to) const {
357 expression_->Write(to);
358 to->Write(";\n");
359 }
360
Comparison(AstNode * lhs,const string & comparison,AstNode * rhs)361 Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs)
362 : left_(lhs),
363 right_(rhs),
364 operator_(comparison) {}
365
Write(CodeWriter * to) const366 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
LiteralExpression(const std::string & expression)374 LiteralExpression::LiteralExpression(const std::string& expression)
375 : expression_(expression) {}
376
Write(CodeWriter * to) const377 void LiteralExpression::Write(CodeWriter* to) const {
378 to->Write("%s", expression_.c_str());
379 }
380
CppNamespace(const std::string & name,std::vector<unique_ptr<Declaration>> declarations)381 CppNamespace::CppNamespace(const std::string& name,
382 std::vector<unique_ptr<Declaration>> declarations)
383 : declarations_(std::move(declarations)),
384 name_(name) {}
385
CppNamespace(const std::string & name,unique_ptr<Declaration> declaration)386 CppNamespace::CppNamespace(const std::string& name,
387 unique_ptr<Declaration> declaration)
388 : name_(name) {
389 declarations_.push_back(std::move(declaration));
390 }
CppNamespace(const std::string & name)391 CppNamespace::CppNamespace(const std::string& name)
392 : name_(name) {}
393
Write(CodeWriter * to) const394 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
Document(const std::vector<std::string> & include_list,unique_ptr<CppNamespace> a_namespace)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
Write(CodeWriter * to) const410 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
CppHeader(const std::string & include_guard,const std::vector<std::string> & include_list,unique_ptr<CppNamespace> a_namespace)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
Write(CodeWriter * to) const425 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
CppSource(const std::vector<std::string> & include_list,unique_ptr<CppNamespace> a_namespace)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