blob: ce1063a37c27551294d414bb7532b88d0e21e180 [file] [log] [blame]
Christopher Wileyda695992015-10-05 11:31:41 -07001/*
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
Christopher Wileyf600a552015-09-12 14:07:44 -070017#include "ast_cpp.h"
18
Christopher Wileyda695992015-10-05 11:31:41 -070019#include <algorithm>
20
Christopher Wileyf600a552015-09-12 14:07:44 -070021#include "code_writer.h"
Christopher Wileyda695992015-10-05 11:31:41 -070022#include "logging.h"
Christopher Wileyf600a552015-09-12 14:07:44 -070023
Christopher Wileya7a5c102015-09-29 16:26:52 -070024using std::string;
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -070025using std::unique_ptr;
Christopher Wileyda695992015-10-05 11:31:41 -070026using std::vector;
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -070027
Christopher Wileyf600a552015-09-12 14:07:44 -070028namespace android {
29namespace aidl {
Christopher Wileyf944e792015-09-29 10:00:46 -070030namespace cpp {
Christopher Wileyf600a552015-09-12 14:07:44 -070031
Christopher Wiley0c732db2015-09-29 14:36:44 -070032ClassDecl::ClassDecl(const std::string& name, const std::string& parent)
33 : name_(name),
34 parent_(parent) {}
35
Christopher Wileyf944e792015-09-29 10:00:46 -070036ClassDecl::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)
Casey Dahlin60a49162015-09-17 14:23:10 -070039 : name_(name),
40 parent_(parent),
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -070041 public_members_(std::move(public_members)),
42 private_members_(std::move(private_members)) {}
Casey Dahlin60a49162015-09-17 14:23:10 -070043
Christopher Wileyf944e792015-09-29 10:00:46 -070044void ClassDecl::Write(CodeWriter* to) const {
Casey Dahlin60a49162015-09-17 14:23:10 -070045 to->Write("class %s ", name_.c_str());
46
47 if (parent_.length() > 0)
48 to->Write(": public %s ", parent_.c_str());
49
Casey Dahlin88924d62015-09-17 16:28:24 -070050 to->Write("{\n");
Casey Dahlin60a49162015-09-17 14:23:10 -070051
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
Casey Dahlin88924d62015-09-17 16:28:24 -070064 to->Write("}; // class %s\n", name_.c_str());
65}
66
Christopher Wiley0c732db2015-09-29 14:36:44 -070067void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) {
68 public_members_.push_back(std::move(member));
69}
70
71void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) {
72 private_members_.push_back(std::move(member));
73}
74
Christopher Wileya7a5c102015-09-29 16:26:52 -070075Enum::EnumField::EnumField(const string& k, const string&v)
76 : key(k),
77 value(v) {}
78
79Enum::Enum(const string& name) : enum_name_(name) {}
80
81void Enum::Write(CodeWriter* to) const {
82 to->Write("enum %s {\n", enum_name_.c_str());
83 for (const auto& field : fields_) {
84 if (field.value.empty()) {
85 to->Write(" %s,\n", field.key.c_str());
86 } else {
87 to->Write(" %s = %s,\n", field.key.c_str(), field.value.c_str());
88 }
89 }
Christopher Wiley3bb6bc12015-10-14 10:58:27 -070090 to->Write("};\n");
Christopher Wileya7a5c102015-09-29 16:26:52 -070091}
92
93void Enum::AddValue(const string& key, const string& value) {
94 fields_.emplace_back(key, value);
95}
96
Christopher Wiley23285262015-10-09 15:06:14 -070097ArgList::ArgList(const std::string& single_argument)
98 : ArgList(vector<string>{single_argument}) {}
99
100ArgList::ArgList(const std::vector<std::string>& arg_list)
101 : arguments_(arg_list) {}
102
Christopher Wileyade4b452015-10-10 11:06:03 -0700103ArgList::ArgList(ArgList&& arg_list)
104 : arguments_(std::move(arg_list.arguments_)) {}
105
Christopher Wiley23285262015-10-09 15:06:14 -0700106void ArgList::Write(CodeWriter* to) const {
107 to->Write("(");
108 bool is_first = true;
109 for (const auto& s : arguments_) {
110 if (!is_first) { to->Write(", "); }
111 is_first = false;
112 to->Write("%s", s.c_str());
113 }
114 to->Write(")");
115}
116
Christopher Wileya7a5c102015-09-29 16:26:52 -0700117ConstructorDecl::ConstructorDecl(
118 const std::string& name,
Christopher Wileyade4b452015-10-10 11:06:03 -0700119 ArgList&& arg_list)
Christopher Wileyb23149d2015-10-14 13:52:21 -0700120 : ConstructorDecl(name, std::move(arg_list), 0u) {}
Christopher Wileya7a5c102015-09-29 16:26:52 -0700121
Christopher Wileyf944e792015-09-29 10:00:46 -0700122ConstructorDecl::ConstructorDecl(
Casey Dahlina834dd42015-09-23 11:52:15 -0700123 const std::string& name,
Christopher Wileyade4b452015-10-10 11:06:03 -0700124 ArgList&& arg_list,
Christopher Wileyb23149d2015-10-14 13:52:21 -0700125 uint32_t modifiers)
Casey Dahlina834dd42015-09-23 11:52:15 -0700126 : name_(name),
Christopher Wileyade4b452015-10-10 11:06:03 -0700127 arguments_(std::move(arg_list)),
Christopher Wileyb23149d2015-10-14 13:52:21 -0700128 modifiers_(modifiers) {}
Casey Dahlina834dd42015-09-23 11:52:15 -0700129
Christopher Wileyf944e792015-09-29 10:00:46 -0700130void ConstructorDecl::Write(CodeWriter* to) const {
Christopher Wileyb23149d2015-10-14 13:52:21 -0700131 if (modifiers_ & Modifiers::IS_VIRTUAL)
Casey Dahlina834dd42015-09-23 11:52:15 -0700132 to->Write("virtual ");
133
Christopher Wileyb23149d2015-10-14 13:52:21 -0700134 if (modifiers_ & Modifiers::IS_EXPLICIT)
135 to->Write("explicit ");
136
Christopher Wileyade4b452015-10-10 11:06:03 -0700137 to->Write("%s", name_.c_str());
Casey Dahlina834dd42015-09-23 11:52:15 -0700138
Christopher Wileyade4b452015-10-10 11:06:03 -0700139 arguments_.Write(to);
Casey Dahlina834dd42015-09-23 11:52:15 -0700140
Christopher Wileyb23149d2015-10-14 13:52:21 -0700141 if (modifiers_ & Modifiers::IS_DEFAULT)
Christopher Wileyf094d582015-10-08 15:50:15 -0700142 to->Write(" = default");
143
144 to->Write(";\n");
Casey Dahlina834dd42015-09-23 11:52:15 -0700145}
146
Christopher Wileyf944e792015-09-29 10:00:46 -0700147MethodDecl::MethodDecl(const std::string& return_type,
148 const std::string& name,
Christopher Wileyade4b452015-10-10 11:06:03 -0700149 ArgList&& arg_list)
150 : MethodDecl(return_type, name, std::move(arg_list), 0u) {}
Christopher Wiley0c732db2015-09-29 14:36:44 -0700151
152MethodDecl::MethodDecl(const std::string& return_type,
153 const std::string& name,
Christopher Wileyade4b452015-10-10 11:06:03 -0700154 ArgList&& arg_list,
Christopher Wiley0c732db2015-09-29 14:36:44 -0700155 uint32_t modifiers)
Casey Dahlin88924d62015-09-17 16:28:24 -0700156 : return_type_(return_type),
157 name_(name),
Christopher Wileyade4b452015-10-10 11:06:03 -0700158 arguments_(std::move(arg_list)),
Christopher Wiley0c732db2015-09-29 14:36:44 -0700159 is_const_(modifiers & IS_CONST),
160 is_virtual_(modifiers & IS_VIRTUAL),
161 is_override_(modifiers & IS_OVERRIDE),
162 is_pure_virtual_(modifiers & IS_PURE_VIRTUAL) {}
Casey Dahlin88924d62015-09-17 16:28:24 -0700163
Christopher Wileyf944e792015-09-29 10:00:46 -0700164void MethodDecl::Write(CodeWriter* to) const {
Casey Dahlin88924d62015-09-17 16:28:24 -0700165 if (is_virtual_)
166 to->Write("virtual ");
167
Christopher Wileyda695992015-10-05 11:31:41 -0700168 to->Write("%s %s", return_type_.c_str(), name_.c_str());
Casey Dahlin88924d62015-09-17 16:28:24 -0700169
Christopher Wileyade4b452015-10-10 11:06:03 -0700170 arguments_.Write(to);
Casey Dahlin88924d62015-09-17 16:28:24 -0700171
172 if (is_const_)
173 to->Write(" const");
174
Christopher Wiley0c732db2015-09-29 14:36:44 -0700175 if (is_override_)
176 to->Write(" override");
177
178 if (is_pure_virtual_)
179 to->Write(" = 0");
180
Casey Dahlin88924d62015-09-17 16:28:24 -0700181 to->Write(";\n");
Casey Dahlin60a49162015-09-17 14:23:10 -0700182}
183
Christopher Wileyda695992015-10-05 11:31:41 -0700184void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
185 statements_.push_back(std::move(statement));
186}
187
Christopher Wiley23285262015-10-09 15:06:14 -0700188void StatementBlock::AddStatement(AstNode* statement) {
189 statements_.emplace_back(statement);
190}
191
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700192void StatementBlock::AddLiteral(const std::string& expression_str,
Christopher Wileyda695992015-10-05 11:31:41 -0700193 bool add_semicolon) {
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700194 if (add_semicolon) {
195 statements_.push_back(unique_ptr<AstNode>(new Statement(expression_str)));
196 } else {
197 statements_.push_back(unique_ptr<AstNode>(
198 new LiteralExpression(expression_str)));
199 }
Christopher Wileyda695992015-10-05 11:31:41 -0700200}
201
202void StatementBlock::Write(CodeWriter* to) const {
203 to->Write("{\n");
204 for (const auto& statement : statements_) {
205 statement->Write(to);
206 }
207 to->Write("}\n");
208}
209
Christopher Wileyf9688b02015-10-08 17:17:50 -0700210ConstructorImpl::ConstructorImpl(const string& class_name,
211 ArgList&& arg_list,
212 const vector<string>& initializer_list)
213 : class_name_(class_name),
214 arguments_(std::move(arg_list)),
215 initializer_list_(initializer_list) {}
216
217void ConstructorImpl::Write(CodeWriter* to) const {
218 to->Write("%s::%s", class_name_.c_str(), class_name_.c_str());
219 arguments_.Write(to);
220 to->Write("\n");
221
222 bool is_first = true;
223 for (const string& i : initializer_list_) {
224 if (is_first) {
225 to->Write(" : %s", i.c_str());
226 } else {
227 to->Write(",\n %s", i.c_str());
228 }
229 is_first = false;
230 }
231
232 body_.Write(to);
233}
234
Christopher Wileyda695992015-10-05 11:31:41 -0700235MethodImpl::MethodImpl(const string& return_type,
236 const string& class_name,
237 const string& method_name,
Christopher Wileyade4b452015-10-10 11:06:03 -0700238 ArgList&& arg_list,
Christopher Wileyda695992015-10-05 11:31:41 -0700239 bool is_const_method)
240 : return_type_(return_type),
241 method_name_(method_name),
Christopher Wileyade4b452015-10-10 11:06:03 -0700242 arguments_(std::move(arg_list)),
Christopher Wileyda695992015-10-05 11:31:41 -0700243 is_const_method_(is_const_method) {
244 if (!class_name.empty()) {
245 method_name_ = class_name + "::" + method_name;
246 }
247}
248
Christopher Wileyf9688b02015-10-08 17:17:50 -0700249StatementBlock* MethodImpl::GetStatementBlock() {
250 return &statements_;
Christopher Wileyda695992015-10-05 11:31:41 -0700251}
252
253void MethodImpl::Write(CodeWriter* to) const {
254 to->Write("%s %s", return_type_.c_str(), method_name_.c_str());
Christopher Wileyade4b452015-10-10 11:06:03 -0700255 arguments_.Write(to);
Christopher Wileyda695992015-10-05 11:31:41 -0700256 to->Write("%s ", (is_const_method_) ? " const" : "");
257 statements_.Write(to);
258}
259
260SwitchStatement::SwitchStatement(const std::string& expression)
261 : switch_expression_(expression) {}
262
263StatementBlock* SwitchStatement::AddCase(const string& value_expression) {
264 auto it = std::find(case_values_.begin(), case_values_.end(), value_expression);
265 if (it != case_values_.end()) {
266 LOG(ERROR) << "internal error: duplicate switch case labels";
267 return nullptr;
268 }
269 StatementBlock* ret = new StatementBlock();
270 case_values_.push_back(value_expression);
271 case_logic_.push_back(unique_ptr<StatementBlock>{ret});
272 return ret;
273}
274
275void SwitchStatement::Write(CodeWriter* to) const {
276 to->Write("switch (%s) {\n", switch_expression_.c_str());
277 for (size_t i = 0; i < case_values_.size(); ++i) {
278 const string& case_value = case_values_[i];
279 const unique_ptr<StatementBlock>& statements = case_logic_[i];
280 if (case_value.empty()) {
281 to->Write("default:\n");
282 } else {
283 to->Write("case %s:\n", case_value.c_str());
284 }
285 statements->Write(to);
286 to->Write("break;\n");
287 }
288 to->Write("}\n");
289}
290
Christopher Wiley23285262015-10-09 15:06:14 -0700291
292Assignment::Assignment(const std::string& left, const std::string& right)
293 : Assignment(left, new LiteralExpression{right}) {}
294
295Assignment::Assignment(const std::string& left, AstNode* right)
296 : lhs_(left),
297 rhs_(right) {}
298
299void Assignment::Write(CodeWriter* to) const {
300 to->Write("%s = ", lhs_.c_str());
301 rhs_->Write(to);
302 to->Write(";\n");
303}
304
305MethodCall::MethodCall(const std::string& method_name,
306 const std::string& single_argument)
Christopher Wileyade4b452015-10-10 11:06:03 -0700307 : MethodCall(method_name, ArgList{single_argument}) {}
Christopher Wiley23285262015-10-09 15:06:14 -0700308
Christopher Wileyade4b452015-10-10 11:06:03 -0700309MethodCall::MethodCall(const std::string& method_name,
310 ArgList&& arg_list)
Christopher Wiley23285262015-10-09 15:06:14 -0700311 : method_name_(method_name),
Christopher Wileyade4b452015-10-10 11:06:03 -0700312 arguments_{std::move(arg_list)} {}
Christopher Wiley23285262015-10-09 15:06:14 -0700313
314void MethodCall::Write(CodeWriter* to) const {
315 to->Write("%s", method_name_.c_str());
Christopher Wileyade4b452015-10-10 11:06:03 -0700316 arguments_.Write(to);
Christopher Wiley23285262015-10-09 15:06:14 -0700317}
318
Christopher Wiley0eb903e2015-10-20 17:07:08 -0700319IfStatement::IfStatement(AstNode* expression, bool invert_expression)
320 : expression_(expression),
321 invert_expression_(invert_expression) {}
322
323void IfStatement::Write(CodeWriter* to) const {
Christopher Wiley864bc092015-11-10 11:45:23 -0800324 to->Write("if (%s", (invert_expression_) ? "!(" : "");
Christopher Wiley0eb903e2015-10-20 17:07:08 -0700325 expression_->Write(to);
326 to->Write(")%s ", (invert_expression_) ? ")" : "");
327 on_true_.Write(to);
328
329 if (!on_false_.Empty()) {
330 to->Write("else ");
331 on_false_.Write(to);
332 }
333}
334
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700335Statement::Statement(unique_ptr<AstNode> expression)
336 : expression_(std::move(expression)) {}
Christopher Wileyda695992015-10-05 11:31:41 -0700337
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700338Statement::Statement(AstNode* expression) : expression_(expression) {}
339
340Statement::Statement(const string& expression)
341 : expression_(new LiteralExpression(expression)) {}
342
343void Statement::Write(CodeWriter* to) const {
344 expression_->Write(to);
345 to->Write(";\n");
Christopher Wileyda695992015-10-05 11:31:41 -0700346}
347
Christopher Wileyd55db282015-10-20 18:16:47 -0700348Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs)
349 : left_(lhs),
350 right_(rhs),
351 operator_(comparison) {}
352
353void Comparison::Write(CodeWriter* to) const {
354 to->Write("((");
355 left_->Write(to);
356 to->Write(") %s (", operator_.c_str());
357 right_->Write(to);
358 to->Write("))");
359}
360
Christopher Wiley23285262015-10-09 15:06:14 -0700361LiteralExpression::LiteralExpression(const std::string& expression)
362 : expression_(expression) {}
363
364void LiteralExpression::Write(CodeWriter* to) const {
365 to->Write("%s", expression_.c_str());
366}
367
Casey Dahlin34b86102015-09-16 16:03:06 -0700368CppNamespace::CppNamespace(const std::string& name,
Christopher Wileyf944e792015-09-29 10:00:46 -0700369 std::vector<unique_ptr<Declaration>> declarations)
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700370 : declarations_(std::move(declarations)),
Casey Dahlin34b86102015-09-16 16:03:06 -0700371 name_(name) {}
Christopher Wileyf600a552015-09-12 14:07:44 -0700372
Christopher Wiley0c732db2015-09-29 14:36:44 -0700373CppNamespace::CppNamespace(const std::string& name,
374 unique_ptr<Declaration> declaration)
375 : name_(name) {
376 declarations_.push_back(std::move(declaration));
377}
378CppNamespace::CppNamespace(const std::string& name)
379 : name_(name) {}
380
Casey Dahlin34b86102015-09-16 16:03:06 -0700381void CppNamespace::Write(CodeWriter* to) const {
382 to->Write("namespace %s {\n\n", name_.c_str());
383
Casey Dahlin60a49162015-09-17 14:23:10 -0700384 for (const auto& dec : declarations_) {
Casey Dahlin34b86102015-09-16 16:03:06 -0700385 dec->Write(to);
Casey Dahlin60a49162015-09-17 14:23:10 -0700386 to->Write("\n");
387 }
Casey Dahlin34b86102015-09-16 16:03:06 -0700388
Casey Dahlin60a49162015-09-17 14:23:10 -0700389 to->Write("} // namespace %s\n", name_.c_str());
Casey Dahlin34b86102015-09-16 16:03:06 -0700390}
391
Christopher Wileyf944e792015-09-29 10:00:46 -0700392Document::Document(const std::vector<std::string>& include_list,
393 unique_ptr<CppNamespace> a_namespace)
Casey Dahlin34b86102015-09-16 16:03:06 -0700394 : include_list_(include_list),
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700395 namespace_(std::move(a_namespace)) {}
Casey Dahlin34b86102015-09-16 16:03:06 -0700396
Christopher Wileyf944e792015-09-29 10:00:46 -0700397void Document::Write(CodeWriter* to) const {
Casey Dahlin34b86102015-09-16 16:03:06 -0700398 for (const auto& include : include_list_) {
Christopher Wileyf600a552015-09-12 14:07:44 -0700399 to->Write("#include <%s>\n", include.c_str());
400 }
401 to->Write("\n");
402
Casey Dahlin34b86102015-09-16 16:03:06 -0700403 namespace_->Write(to);
Christopher Wileyf600a552015-09-12 14:07:44 -0700404}
405
Christopher Wileyf600a552015-09-12 14:07:44 -0700406CppHeader::CppHeader(const std::string& include_guard,
407 const std::vector<std::string>& include_list,
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700408 unique_ptr<CppNamespace> a_namespace)
Christopher Wileyf944e792015-09-29 10:00:46 -0700409 : Document(include_list, std::move(a_namespace)),
Casey Dahlin34b86102015-09-16 16:03:06 -0700410 include_guard_(include_guard) {}
Christopher Wileyf600a552015-09-12 14:07:44 -0700411
412void CppHeader::Write(CodeWriter* to) const {
413 to->Write("#ifndef %s\n", include_guard_.c_str());
414 to->Write("#define %s\n\n", include_guard_.c_str());
415
Christopher Wileyf944e792015-09-29 10:00:46 -0700416 Document::Write(to);
Christopher Wileyf600a552015-09-12 14:07:44 -0700417 to->Write("\n");
418
419 to->Write("#endif // %s", include_guard_.c_str());
420}
421
Casey Dahlin34b86102015-09-16 16:03:06 -0700422CppSource::CppSource(const std::vector<std::string>& include_list,
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700423 unique_ptr<CppNamespace> a_namespace)
Christopher Wileyf944e792015-09-29 10:00:46 -0700424 : Document(include_list, std::move(a_namespace)) {}
Christopher Wileyf600a552015-09-12 14:07:44 -0700425
Christopher Wileyf944e792015-09-29 10:00:46 -0700426} // namespace cpp
Christopher Wileyf600a552015-09-12 14:07:44 -0700427} // namespace aidl
428} // namespace android