blob: 3181ce43cd12c9e3cacb714f00393c9c508155bc [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 Wileyda695992015-10-05 11:31:41 -070031namespace {
32
33void WriteArgList(CodeWriter* to, const vector<string>& arguments_) {
34 bool first = true;
35
36 to->Write("(");
37
38 for (const auto& arg : arguments_) {
39 if (!first)
40 to->Write(", ");
41 to->Write("%s", arg.c_str());
42 first = false;
43 }
44
45 to->Write(")");
46}
47
48} // namespace
Christopher Wileyf600a552015-09-12 14:07:44 -070049
Christopher Wiley0c732db2015-09-29 14:36:44 -070050ClassDecl::ClassDecl(const std::string& name, const std::string& parent)
51 : name_(name),
52 parent_(parent) {}
53
Christopher Wileyf944e792015-09-29 10:00:46 -070054ClassDecl::ClassDecl(const std::string& name, const std::string& parent,
55 std::vector<unique_ptr<Declaration>> public_members,
56 std::vector<unique_ptr<Declaration>> private_members)
Casey Dahlin60a49162015-09-17 14:23:10 -070057 : name_(name),
58 parent_(parent),
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -070059 public_members_(std::move(public_members)),
60 private_members_(std::move(private_members)) {}
Casey Dahlin60a49162015-09-17 14:23:10 -070061
Christopher Wileyf944e792015-09-29 10:00:46 -070062void ClassDecl::Write(CodeWriter* to) const {
Casey Dahlin60a49162015-09-17 14:23:10 -070063 to->Write("class %s ", name_.c_str());
64
65 if (parent_.length() > 0)
66 to->Write(": public %s ", parent_.c_str());
67
Casey Dahlin88924d62015-09-17 16:28:24 -070068 to->Write("{\n");
Casey Dahlin60a49162015-09-17 14:23:10 -070069
70 if (!public_members_.empty())
71 to->Write("public:\n");
72
73 for (const auto& dec : public_members_)
74 dec->Write(to);
75
76 if (!private_members_.empty())
77 to->Write("private:\n");
78
79 for (const auto& dec : private_members_)
80 dec->Write(to);
81
Casey Dahlin88924d62015-09-17 16:28:24 -070082 to->Write("}; // class %s\n", name_.c_str());
83}
84
Christopher Wiley0c732db2015-09-29 14:36:44 -070085void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) {
86 public_members_.push_back(std::move(member));
87}
88
89void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) {
90 private_members_.push_back(std::move(member));
91}
92
Christopher Wileya7a5c102015-09-29 16:26:52 -070093Enum::EnumField::EnumField(const string& k, const string&v)
94 : key(k),
95 value(v) {}
96
97Enum::Enum(const string& name) : enum_name_(name) {}
98
99void Enum::Write(CodeWriter* to) const {
100 to->Write("enum %s {\n", enum_name_.c_str());
101 for (const auto& field : fields_) {
102 if (field.value.empty()) {
103 to->Write(" %s,\n", field.key.c_str());
104 } else {
105 to->Write(" %s = %s,\n", field.key.c_str(), field.value.c_str());
106 }
107 }
108 to->Write("}\n");
109}
110
111void Enum::AddValue(const string& key, const string& value) {
112 fields_.emplace_back(key, value);
113}
114
Christopher Wiley23285262015-10-09 15:06:14 -0700115ArgList::ArgList(const std::string& single_argument)
116 : ArgList(vector<string>{single_argument}) {}
117
118ArgList::ArgList(const std::vector<std::string>& arg_list)
119 : arguments_(arg_list) {}
120
121void ArgList::Write(CodeWriter* to) const {
122 to->Write("(");
123 bool is_first = true;
124 for (const auto& s : arguments_) {
125 if (!is_first) { to->Write(", "); }
126 is_first = false;
127 to->Write("%s", s.c_str());
128 }
129 to->Write(")");
130}
131
Christopher Wileya7a5c102015-09-29 16:26:52 -0700132ConstructorDecl::ConstructorDecl(
133 const std::string& name,
134 std::vector<std::string> arguments)
135 : name_(name),
136 arguments_(arguments) {}
137
Christopher Wileyf944e792015-09-29 10:00:46 -0700138ConstructorDecl::ConstructorDecl(
Casey Dahlina834dd42015-09-23 11:52:15 -0700139 const std::string& name,
140 std::vector<std::string> arguments,
Casey Dahlina834dd42015-09-23 11:52:15 -0700141 bool is_virtual)
142 : name_(name),
143 arguments_(arguments),
Casey Dahlina834dd42015-09-23 11:52:15 -0700144 is_virtual_(is_virtual) {}
145
Christopher Wileyf944e792015-09-29 10:00:46 -0700146void ConstructorDecl::Write(CodeWriter* to) const {
Casey Dahlina834dd42015-09-23 11:52:15 -0700147 if (is_virtual_)
148 to->Write("virtual ");
149
150 to->Write("%s(", name_.c_str());
151
152 bool not_first = false;
153
154 for (const auto& arg : arguments_) {
155 if (not_first)
156 to->Write(", ");
157 not_first = true;
158 to->Write("%s", arg.c_str());
159 }
160
Christopher Wileya7a5c102015-09-29 16:26:52 -0700161 to->Write(");\n");
Casey Dahlina834dd42015-09-23 11:52:15 -0700162}
163
Christopher Wileyf944e792015-09-29 10:00:46 -0700164MethodDecl::MethodDecl(const std::string& return_type,
165 const std::string& name,
Christopher Wiley0c732db2015-09-29 14:36:44 -0700166 std::vector<std::string> arguments)
167 : return_type_(return_type),
168 name_(name),
169 arguments_(arguments) {}
170
171MethodDecl::MethodDecl(const std::string& return_type,
172 const std::string& name,
Christopher Wileyf944e792015-09-29 10:00:46 -0700173 std::vector<std::string> arguments,
Christopher Wiley0c732db2015-09-29 14:36:44 -0700174 uint32_t modifiers)
Casey Dahlin88924d62015-09-17 16:28:24 -0700175 : return_type_(return_type),
176 name_(name),
177 arguments_(arguments),
Christopher Wiley0c732db2015-09-29 14:36:44 -0700178 is_const_(modifiers & IS_CONST),
179 is_virtual_(modifiers & IS_VIRTUAL),
180 is_override_(modifiers & IS_OVERRIDE),
181 is_pure_virtual_(modifiers & IS_PURE_VIRTUAL) {}
Casey Dahlin88924d62015-09-17 16:28:24 -0700182
Christopher Wileyf944e792015-09-29 10:00:46 -0700183void MethodDecl::Write(CodeWriter* to) const {
Casey Dahlin88924d62015-09-17 16:28:24 -0700184 if (is_virtual_)
185 to->Write("virtual ");
186
Christopher Wileyda695992015-10-05 11:31:41 -0700187 to->Write("%s %s", return_type_.c_str(), name_.c_str());
Casey Dahlin88924d62015-09-17 16:28:24 -0700188
Christopher Wileyda695992015-10-05 11:31:41 -0700189 WriteArgList(to, arguments_);
Casey Dahlin88924d62015-09-17 16:28:24 -0700190
191 if (is_const_)
192 to->Write(" const");
193
Christopher Wiley0c732db2015-09-29 14:36:44 -0700194 if (is_override_)
195 to->Write(" override");
196
197 if (is_pure_virtual_)
198 to->Write(" = 0");
199
Casey Dahlin88924d62015-09-17 16:28:24 -0700200 to->Write(";\n");
Casey Dahlin60a49162015-09-17 14:23:10 -0700201}
202
Christopher Wileyda695992015-10-05 11:31:41 -0700203void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
204 statements_.push_back(std::move(statement));
205}
206
Christopher Wiley23285262015-10-09 15:06:14 -0700207void StatementBlock::AddStatement(AstNode* statement) {
208 statements_.emplace_back(statement);
209}
210
Christopher Wileyda695992015-10-05 11:31:41 -0700211void StatementBlock::AddLiteral(const std::string& expression,
212 bool add_semicolon) {
213 statements_.push_back(unique_ptr<AstNode>{
214 new LiteralStatement{expression, add_semicolon}});
215}
216
217void StatementBlock::Write(CodeWriter* to) const {
218 to->Write("{\n");
219 for (const auto& statement : statements_) {
220 statement->Write(to);
221 }
222 to->Write("}\n");
223}
224
225MethodImpl::MethodImpl(const string& return_type,
226 const string& class_name,
227 const string& method_name,
228 vector<string> arguments,
229 bool is_const_method)
230 : return_type_(return_type),
231 method_name_(method_name),
232 arguments_(arguments),
233 is_const_method_(is_const_method) {
234 if (!class_name.empty()) {
235 method_name_ = class_name + "::" + method_name;
236 }
237}
238
239void MethodImpl::AddStatement(unique_ptr<AstNode> statement) {
240 statements_.AddStatement(std::move(statement));
241}
242
243void MethodImpl::Write(CodeWriter* to) const {
244 to->Write("%s %s", return_type_.c_str(), method_name_.c_str());
245 WriteArgList(to, arguments_);
246 to->Write("%s ", (is_const_method_) ? " const" : "");
247 statements_.Write(to);
248}
249
250SwitchStatement::SwitchStatement(const std::string& expression)
251 : switch_expression_(expression) {}
252
253StatementBlock* SwitchStatement::AddCase(const string& value_expression) {
254 auto it = std::find(case_values_.begin(), case_values_.end(), value_expression);
255 if (it != case_values_.end()) {
256 LOG(ERROR) << "internal error: duplicate switch case labels";
257 return nullptr;
258 }
259 StatementBlock* ret = new StatementBlock();
260 case_values_.push_back(value_expression);
261 case_logic_.push_back(unique_ptr<StatementBlock>{ret});
262 return ret;
263}
264
265void SwitchStatement::Write(CodeWriter* to) const {
266 to->Write("switch (%s) {\n", switch_expression_.c_str());
267 for (size_t i = 0; i < case_values_.size(); ++i) {
268 const string& case_value = case_values_[i];
269 const unique_ptr<StatementBlock>& statements = case_logic_[i];
270 if (case_value.empty()) {
271 to->Write("default:\n");
272 } else {
273 to->Write("case %s:\n", case_value.c_str());
274 }
275 statements->Write(to);
276 to->Write("break;\n");
277 }
278 to->Write("}\n");
279}
280
Christopher Wiley23285262015-10-09 15:06:14 -0700281
282Assignment::Assignment(const std::string& left, const std::string& right)
283 : Assignment(left, new LiteralExpression{right}) {}
284
285Assignment::Assignment(const std::string& left, AstNode* right)
286 : lhs_(left),
287 rhs_(right) {}
288
289void Assignment::Write(CodeWriter* to) const {
290 to->Write("%s = ", lhs_.c_str());
291 rhs_->Write(to);
292 to->Write(";\n");
293}
294
295MethodCall::MethodCall(const std::string& method_name,
296 const std::string& single_argument)
297 : MethodCall(method_name, new ArgList{single_argument}) {}
298
299MethodCall::MethodCall(const std::string& method_name, ArgList* arg_list)
300 : method_name_(method_name),
301 arg_list_{arg_list} {}
302
303void MethodCall::Write(CodeWriter* to) const {
304 to->Write("%s", method_name_.c_str());
305 arg_list_->Write(to);
306}
307
Christopher Wileyda695992015-10-05 11:31:41 -0700308LiteralStatement::LiteralStatement(const string& expression, bool use_semicolon)
309 : expression_(expression),
310 use_semicolon_(use_semicolon) {}
311
312void LiteralStatement::Write(CodeWriter* to) const {
313 to->Write("%s%s\n", expression_.c_str(), (use_semicolon_) ? ";" : "");
314}
315
Christopher Wiley23285262015-10-09 15:06:14 -0700316LiteralExpression::LiteralExpression(const std::string& expression)
317 : expression_(expression) {}
318
319void LiteralExpression::Write(CodeWriter* to) const {
320 to->Write("%s", expression_.c_str());
321}
322
Casey Dahlin34b86102015-09-16 16:03:06 -0700323CppNamespace::CppNamespace(const std::string& name,
Christopher Wileyf944e792015-09-29 10:00:46 -0700324 std::vector<unique_ptr<Declaration>> declarations)
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700325 : declarations_(std::move(declarations)),
Casey Dahlin34b86102015-09-16 16:03:06 -0700326 name_(name) {}
Christopher Wileyf600a552015-09-12 14:07:44 -0700327
Christopher Wiley0c732db2015-09-29 14:36:44 -0700328CppNamespace::CppNamespace(const std::string& name,
329 unique_ptr<Declaration> declaration)
330 : name_(name) {
331 declarations_.push_back(std::move(declaration));
332}
333CppNamespace::CppNamespace(const std::string& name)
334 : name_(name) {}
335
Casey Dahlin34b86102015-09-16 16:03:06 -0700336void CppNamespace::Write(CodeWriter* to) const {
337 to->Write("namespace %s {\n\n", name_.c_str());
338
Casey Dahlin60a49162015-09-17 14:23:10 -0700339 for (const auto& dec : declarations_) {
Casey Dahlin34b86102015-09-16 16:03:06 -0700340 dec->Write(to);
Casey Dahlin60a49162015-09-17 14:23:10 -0700341 to->Write("\n");
342 }
Casey Dahlin34b86102015-09-16 16:03:06 -0700343
Casey Dahlin60a49162015-09-17 14:23:10 -0700344 to->Write("} // namespace %s\n", name_.c_str());
Casey Dahlin34b86102015-09-16 16:03:06 -0700345}
346
Christopher Wileyf944e792015-09-29 10:00:46 -0700347Document::Document(const std::vector<std::string>& include_list,
348 unique_ptr<CppNamespace> a_namespace)
Casey Dahlin34b86102015-09-16 16:03:06 -0700349 : include_list_(include_list),
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700350 namespace_(std::move(a_namespace)) {}
Casey Dahlin34b86102015-09-16 16:03:06 -0700351
Christopher Wileyf944e792015-09-29 10:00:46 -0700352void Document::Write(CodeWriter* to) const {
Casey Dahlin34b86102015-09-16 16:03:06 -0700353 for (const auto& include : include_list_) {
Christopher Wileyf600a552015-09-12 14:07:44 -0700354 to->Write("#include <%s>\n", include.c_str());
355 }
356 to->Write("\n");
357
Casey Dahlin34b86102015-09-16 16:03:06 -0700358 namespace_->Write(to);
Christopher Wileyf600a552015-09-12 14:07:44 -0700359}
360
Christopher Wileyf600a552015-09-12 14:07:44 -0700361CppHeader::CppHeader(const std::string& include_guard,
362 const std::vector<std::string>& include_list,
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700363 unique_ptr<CppNamespace> a_namespace)
Christopher Wileyf944e792015-09-29 10:00:46 -0700364 : Document(include_list, std::move(a_namespace)),
Casey Dahlin34b86102015-09-16 16:03:06 -0700365 include_guard_(include_guard) {}
Christopher Wileyf600a552015-09-12 14:07:44 -0700366
367void CppHeader::Write(CodeWriter* to) const {
368 to->Write("#ifndef %s\n", include_guard_.c_str());
369 to->Write("#define %s\n\n", include_guard_.c_str());
370
Christopher Wileyf944e792015-09-29 10:00:46 -0700371 Document::Write(to);
Christopher Wileyf600a552015-09-12 14:07:44 -0700372 to->Write("\n");
373
374 to->Write("#endif // %s", include_guard_.c_str());
375}
376
Casey Dahlin34b86102015-09-16 16:03:06 -0700377CppSource::CppSource(const std::vector<std::string>& include_list,
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700378 unique_ptr<CppNamespace> a_namespace)
Christopher Wileyf944e792015-09-29 10:00:46 -0700379 : Document(include_list, std::move(a_namespace)) {}
Christopher Wileyf600a552015-09-12 14:07:44 -0700380
Christopher Wileyf944e792015-09-29 10:00:46 -0700381} // namespace cpp
Christopher Wileyf600a552015-09-12 14:07:44 -0700382} // namespace aidl
383} // namespace android