blob: c8f1937f0c2565e462d182c9d97a680bf6699d36 [file] [log] [blame]
Christopher Wileyf600a552015-09-12 14:07:44 -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
17#include <string>
18
19#include <gtest/gtest.h>
20
21#include "ast_cpp.h"
22#include "code_writer.h"
23
24using std::string;
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -070025using std::vector;
26using std::unique_ptr;
Christopher Wileyf600a552015-09-12 14:07:44 -070027
28namespace android {
29namespace aidl {
Christopher Wileyf944e792015-09-29 10:00:46 -070030namespace cpp {
Christopher Wileyf600a552015-09-12 14:07:44 -070031namespace {
32
33const char kExpectedHeaderOutput[] =
34R"(#ifndef HEADER_INCLUDE_GUARD_H_
35#define HEADER_INCLUDE_GUARD_H_
36
37#include <string>
38#include <memory>
39
40namespace android {
Casey Dahlin34b86102015-09-16 16:03:06 -070041
Christopher Wileyf600a552015-09-12 14:07:44 -070042namespace test {
43
Casey Dahlin60a49162015-09-17 14:23:10 -070044class TestClass {
Casey Dahlin88924d62015-09-17 16:28:24 -070045public:
Jiyong Parka755dc72018-06-29 13:52:24 +090046 void NormalMethod(int normalarg, float normal2);
47 virtual void SubMethod(int subarg) const;
Casey Dahlin88924d62015-09-17 16:28:24 -070048}; // class TestClass
Casey Dahlin60a49162015-09-17 14:23:10 -070049
50class TestSubClass : public TestClass {
Casey Dahlin88924d62015-09-17 16:28:24 -070051public:
Jiyong Parka755dc72018-06-29 13:52:24 +090052 virtual void SubMethod(int subarg) const;
Casey Dahlin88924d62015-09-17 16:28:24 -070053}; // class TestSubClass
Casey Dahlin34b86102015-09-16 16:03:06 -070054
Christopher Wileyf600a552015-09-12 14:07:44 -070055} // namespace test
Casey Dahlin34b86102015-09-16 16:03:06 -070056
Christopher Wileyf600a552015-09-12 14:07:44 -070057} // namespace android
58
Christopher Wiley11a9d792016-02-24 17:20:33 -080059#endif // HEADER_INCLUDE_GUARD_H_
60)";
Christopher Wileyf600a552015-09-12 14:07:44 -070061
Christopher Wileyda695992015-10-05 11:31:41 -070062const char kExpectedSwitchOutput[] =
63R"(switch (var) {
64case 2:
65{
Jiyong Parka755dc72018-06-29 13:52:24 +090066 baz;
Christopher Wileyda695992015-10-05 11:31:41 -070067}
68break;
69case 1:
70{
Jiyong Parka755dc72018-06-29 13:52:24 +090071 foo;
72 bar;
Christopher Wileyda695992015-10-05 11:31:41 -070073}
74break;
75}
76)";
77
78const char kExpectedMethodImplOutput[] =
Christopher Wileyade4b452015-10-10 11:06:03 -070079R"(return_type ClassName::MethodName(arg 1, arg 2, arg 3) const {
Jiyong Parka755dc72018-06-29 13:52:24 +090080 foo;
81 bar;
Christopher Wileyda695992015-10-05 11:31:41 -070082}
83)";
Christopher Wileyf600a552015-09-12 14:07:44 -070084} // namespace
85
Christopher Wileyda695992015-10-05 11:31:41 -070086class AstCppTests : public ::testing::Test {
87 protected:
Christopher Wiley23285262015-10-09 15:06:14 -070088 void CompareGeneratedCode(const AstNode& node,
89 const string& expected_output) {
Christopher Wileyda695992015-10-05 11:31:41 -070090 string actual_output;
Jiyong Parkb78e15b2018-07-04 20:31:03 +090091 node.Write(CodeWriter::ForString(&actual_output).get());
Christopher Wileyda695992015-10-05 11:31:41 -070092 EXPECT_EQ(expected_output, actual_output);
93 }
94}; // class AstCppTests
95
96
97TEST_F(AstCppTests, GeneratesHeader) {
Christopher Wileyade4b452015-10-10 11:06:03 -070098 unique_ptr<MethodDecl> norm{new MethodDecl(
99 "void", "NormalMethod",
100 ArgList{vector<string>{"int normalarg", "float normal2"}})};
Christopher Wiley0c732db2015-09-29 14:36:44 -0700101 unique_ptr<MethodDecl> sub{
102 new MethodDecl("void", "SubMethod",
Christopher Wileyade4b452015-10-10 11:06:03 -0700103 ArgList{ "int subarg" },
Christopher Wiley0c732db2015-09-29 14:36:44 -0700104 MethodDecl::IS_CONST | MethodDecl::IS_VIRTUAL)};
105 unique_ptr<MethodDecl> sub2{
106 new MethodDecl("void", "SubMethod",
Christopher Wileyade4b452015-10-10 11:06:03 -0700107 ArgList{ "int subarg" },
Christopher Wiley0c732db2015-09-29 14:36:44 -0700108 MethodDecl::IS_CONST | MethodDecl::IS_VIRTUAL)};
Christopher Wileyf944e792015-09-29 10:00:46 -0700109 vector<unique_ptr<Declaration>> test_methods;
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700110 test_methods.push_back(std::move(norm));
111 test_methods.push_back(std::move(sub));
112
Christopher Wileyf944e792015-09-29 10:00:46 -0700113 vector<unique_ptr<Declaration>> test_sub_methods;
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700114 test_sub_methods.push_back(std::move(sub2));
115
Christopher Wileyf944e792015-09-29 10:00:46 -0700116 unique_ptr<Declaration> test{new ClassDecl { "TestClass", "",
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700117 std::move(test_methods), {} }};
118
Christopher Wileyf944e792015-09-29 10:00:46 -0700119 unique_ptr<Declaration> test_sub{new ClassDecl { "TestSubClass",
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700120 "TestClass", std::move(test_sub_methods), {} }};
121
Christopher Wileyf944e792015-09-29 10:00:46 -0700122 vector<unique_ptr<Declaration>> classes;
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700123 classes.push_back(std::move(test));
124 classes.push_back(std::move(test_sub));
125
126 unique_ptr<CppNamespace> test_ns{new CppNamespace {"test",
127 std::move(classes)}};
128
Christopher Wileyf944e792015-09-29 10:00:46 -0700129 vector<unique_ptr<Declaration>> test_ns_vec;
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700130 test_ns_vec.push_back(std::move(test_ns));
131
Christopher Wiley23285262015-10-09 15:06:14 -0700132 unique_ptr<CppNamespace> android_ns{new CppNamespace {"android",
133 std::move(test_ns_vec) }};
Casey Dahlinb7d0f7f2015-09-22 17:21:08 -0700134
Steven Morelandf3da0892018-10-05 14:52:01 -0700135 vector<unique_ptr<Declaration>> test_ns_globals;
136 test_ns_globals.push_back(std::move(android_ns));
137
138 CppHeader cpp_header{"HEADER_INCLUDE_GUARD_H_", {"string", "memory"}, std::move(test_ns_globals)};
Christopher Wiley23285262015-10-09 15:06:14 -0700139 CompareGeneratedCode(cpp_header, kExpectedHeaderOutput);
Christopher Wileyf600a552015-09-12 14:07:44 -0700140}
141
Daniel Norman85aed542019-08-21 12:01:14 -0700142TEST_F(AstCppTests, GeneratesUnscopedEnum) {
143 Enum e("Foo", "", false);
Christopher Wileya7a5c102015-09-29 16:26:52 -0700144 e.AddValue("BAR", "42");
145 e.AddValue("BAZ", "");
Daniel Norman85aed542019-08-21 12:01:14 -0700146
147 string expected =
148 R"(enum Foo {
149 BAR = 42,
150 BAZ,
151};
152)";
153
154 CompareGeneratedCode(e, expected);
155}
156
157TEST_F(AstCppTests, GeneratesScopedEnum) {
158 Enum e("Foo", "int32_t", true);
159 e.AddValue("BAR", "42");
160 e.AddValue("BAZ", "");
161
162 string expected =
163 R"(enum class Foo : int32_t {
164 BAR = 42,
165 BAZ,
166};
167)";
168
169 CompareGeneratedCode(e, expected);
Christopher Wiley23285262015-10-09 15:06:14 -0700170}
171
172TEST_F(AstCppTests, GeneratesArgList) {
173 ArgList simple("foo");
174 CompareGeneratedCode(simple, "(foo)");
175 ArgList compound({"foo", "bar", "baz"});
176 CompareGeneratedCode(compound, "(foo, bar, baz)");
Christopher Wileyf02facf2015-11-12 08:54:08 -0800177 std::vector<unique_ptr<AstNode>> args;
178 args.emplace_back(new LiteralExpression("foo()"));
179 ArgList nested(std::move(args));
180 CompareGeneratedCode(nested, "(foo())");
Christopher Wileyda695992015-10-05 11:31:41 -0700181}
182
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700183TEST_F(AstCppTests, GeneratesStatement) {
184 Statement s(new LiteralExpression("foo"));
Christopher Wiley23285262015-10-09 15:06:14 -0700185 CompareGeneratedCode(s, "foo;\n");
Christopher Wileyda695992015-10-05 11:31:41 -0700186}
187
Christopher Wileyd55db282015-10-20 18:16:47 -0700188TEST_F(AstCppTests, GeneratesComparison) {
189 Comparison c(
190 new LiteralExpression("lhs"), "&&", new LiteralExpression("rhs"));
191 CompareGeneratedCode(c, "((lhs) && (rhs))");
192}
193
Christopher Wileyda695992015-10-05 11:31:41 -0700194TEST_F(AstCppTests, GeneratesStatementBlock) {
195 StatementBlock block;
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700196 block.AddStatement(unique_ptr<AstNode>(new Statement("foo")));
197 block.AddStatement(unique_ptr<AstNode>(new Statement("bar")));
Jiyong Parka755dc72018-06-29 13:52:24 +0900198 CompareGeneratedCode(block, "{\n foo;\n bar;\n}\n");
Christopher Wiley23285262015-10-09 15:06:14 -0700199}
200
Christopher Wileyf9688b02015-10-08 17:17:50 -0700201TEST_F(AstCppTests, GeneratesConstructorImpl) {
202 ConstructorImpl c("ClassName", ArgList({"a", "b", "c"}),
203 {"baz_(foo)", "bar_(blah)"});
204 string expected = R"(ClassName::ClassName(a, b, c)
205 : baz_(foo),
206 bar_(blah){
207}
208)";
209 CompareGeneratedCode(c, expected);
210}
211
Christopher Wiley23285262015-10-09 15:06:14 -0700212TEST_F(AstCppTests, GeneratesAssignment) {
213 Assignment simple("foo", "8");
214 CompareGeneratedCode(simple, "foo = 8;\n");
215 Assignment less_simple("foo", new MethodCall("f", "8"));
216 CompareGeneratedCode(less_simple, "foo = f(8);\n");
217}
218
219TEST_F(AstCppTests, GeneratesMethodCall) {
220 MethodCall single("single", "arg");
221 CompareGeneratedCode(single, "single(arg)");
Christopher Wileyade4b452015-10-10 11:06:03 -0700222 MethodCall multi(
223 "multi",
224 ArgList({"has", "some", "args"}));
Christopher Wiley23285262015-10-09 15:06:14 -0700225 CompareGeneratedCode(multi, "multi(has, some, args)");
Christopher Wileyda695992015-10-05 11:31:41 -0700226}
227
Christopher Wiley0eb903e2015-10-20 17:07:08 -0700228TEST_F(AstCppTests, GeneratesIfStatement) {
229 IfStatement s(new LiteralExpression("foo"));
230 s.OnTrue()->AddLiteral("on true1");
231 s.OnFalse()->AddLiteral("on false");
Jiyong Parka755dc72018-06-29 13:52:24 +0900232 CompareGeneratedCode(s, "if (foo) {\n on true1;\n}\nelse {\n on false;\n}\n");
Christopher Wiley0eb903e2015-10-20 17:07:08 -0700233
234 IfStatement s2(new LiteralExpression("bar"));
235 s2.OnTrue()->AddLiteral("on true1");
Jiyong Parka755dc72018-06-29 13:52:24 +0900236 CompareGeneratedCode(s2, "if (bar) {\n on true1;\n}\n");
Christopher Wiley0eb903e2015-10-20 17:07:08 -0700237}
238
Christopher Wileyda695992015-10-05 11:31:41 -0700239TEST_F(AstCppTests, GeneratesSwitchStatement) {
240 SwitchStatement s("var");
241 // These are intentionally out of alphanumeric order. We're testing
242 // that switch respects case addition order.
243 auto case2 = s.AddCase("2");
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700244 case2->AddStatement(unique_ptr<AstNode>{new Statement{"baz"}});
Christopher Wileyda695992015-10-05 11:31:41 -0700245 auto case1 = s.AddCase("1");
Christopher Wiley3c5d28d2015-10-21 09:53:46 -0700246 case1->AddStatement(unique_ptr<AstNode>{new Statement{"foo"}});
247 case1->AddStatement(unique_ptr<AstNode>{new Statement{"bar"}});
Christopher Wiley23285262015-10-09 15:06:14 -0700248 CompareGeneratedCode(s, kExpectedSwitchOutput);
Christopher Wileyda695992015-10-05 11:31:41 -0700249}
250
251TEST_F(AstCppTests, GeneratesMethodImpl) {
252 MethodImpl m{"return_type", "ClassName", "MethodName",
Christopher Wileyade4b452015-10-10 11:06:03 -0700253 ArgList{{"arg 1", "arg 2", "arg 3"}},
254 true};
Christopher Wileyf9688b02015-10-08 17:17:50 -0700255 auto b = m.GetStatementBlock();
256 b->AddLiteral("foo");
257 b->AddLiteral("bar");
Christopher Wiley23285262015-10-09 15:06:14 -0700258 CompareGeneratedCode(m, kExpectedMethodImplOutput);
Christopher Wileya7a5c102015-09-29 16:26:52 -0700259}
260
Jiyong Park176905e2018-07-04 22:29:41 +0900261TEST_F(AstCppTests, ToString) {
262 std::string literal = "void foo() {}";
263 LiteralDecl decl(literal);
264 std::string actual = decl.ToString();
265 EXPECT_EQ(literal, actual);
266 std::string written;
267 decl.Write(CodeWriter::ForString(&written).get());
268 EXPECT_EQ(literal, written);
269}
270
Christopher Wileyf944e792015-09-29 10:00:46 -0700271} // namespace cpp
Christopher Wileyf600a552015-09-12 14:07:44 -0700272} // namespace aidl
273} // namespace android