blob: 361e3311a290a212609b825aa2d14bdbb8ffb58f [file] [log] [blame]
Christopher Wiley90be4e32015-10-20 14:55:25 -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 Wiley90be4e32015-10-20 14:55:25 -070017#include <memory>
Christopher Wiley12e894a2016-01-29 11:55:07 -080018#include <set>
19#include <string>
Christopher Wiley90be4e32015-10-20 14:55:25 -070020#include <vector>
21
Christopher Wileyec31a052016-01-25 07:28:51 -080022#include <android-base/stringprintf.h>
Christopher Wiley90be4e32015-10-20 14:55:25 -070023#include <gtest/gtest.h>
24
25#include "aidl.h"
26#include "aidl_language.h"
27#include "tests/fake_io_delegate.h"
28#include "type_cpp.h"
29#include "type_java.h"
30#include "type_namespace.h"
31
32using android::aidl::test::FakeIoDelegate;
Christopher Wileyec31a052016-01-25 07:28:51 -080033using android::base::StringPrintf;
Christopher Wiley12e894a2016-01-29 11:55:07 -080034using std::set;
Christopher Wiley90be4e32015-10-20 14:55:25 -070035using std::string;
36using std::unique_ptr;
Christopher Wiley12e894a2016-01-29 11:55:07 -080037using std::vector;
Christopher Wileyef140932015-11-03 09:29:19 -080038using android::aidl::internals::parse_preprocessed_file;
Christopher Wiley90be4e32015-10-20 14:55:25 -070039
40namespace android {
41namespace aidl {
Christopher Wileyf8136192016-04-12 14:19:35 -070042namespace {
43
44const char kExpectedDepFileContents[] =
45R"(place/for/output/p/IFoo.java : \
46 p/IFoo.aidl
47
48p/IFoo.aidl :
49)";
50
Dan Willemsen93298ee2016-11-10 23:55:55 -080051const char kExpectedNinjaDepFileContents[] =
52R"(place/for/output/p/IFoo.java : \
53 p/IFoo.aidl
54)";
55
Christopher Wileyb1bbdf82016-04-21 11:43:45 -070056const char kExpectedParcelableDepFileContents[] =
57R"( : \
58 p/Foo.aidl
59
60p/Foo.aidl :
61)";
62
Christopher Wileyf8136192016-04-12 14:19:35 -070063} // namespace
Christopher Wiley90be4e32015-10-20 14:55:25 -070064
65class AidlTest : public ::testing::Test {
66 protected:
Christopher Wiley56799522015-10-31 10:17:04 -070067 void SetUp() override {
68 java_types_.Init();
69 cpp_types_.Init();
70 }
71
Jiyong Parkb034bf02018-07-30 17:44:33 +090072 AidlDefinedType* Parse(const string& path, const string& contents,
73 TypeNamespace* types, AidlError* error = nullptr) {
Christopher Wiley0522cd52015-10-28 15:39:44 -070074 io_delegate_.SetFileContents(path, contents);
Jiyong Parkfbbfa932018-07-30 21:44:10 +090075 vector<string> args;
76 if (types == &java_types_) {
77 args.emplace_back("aidl");
78 } else {
79 args.emplace_back("aidl-cpp");
80 }
81 for (const auto& f : preprocessed_files_) {
82 args.emplace_back("--preprocessed=" + f);
83 }
84 for (const auto& i : import_paths_) {
85 args.emplace_back("--include=" + i);
86 }
87 args.emplace_back(path);
88 Options options = Options::From(args);
Jiyong Parkb034bf02018-07-30 17:44:33 +090089 vector<AidlDefinedType*> defined_types;
90 vector<string> imported_files;
91 ImportResolver import_resolver{io_delegate_, import_paths_, {}};
Christopher Wiley69b44cf2016-05-03 13:43:33 -070092 AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
Jiyong Parkb034bf02018-07-30 17:44:33 +090093 path, options, io_delegate_, types, &defined_types, &imported_files);
94
Christopher Wiley69b44cf2016-05-03 13:43:33 -070095 if (error != nullptr) {
96 *error = actual_error;
97 }
Jiyong Parkb034bf02018-07-30 17:44:33 +090098
99 if (actual_error != AidlError::OK) {
100 return nullptr;
101 }
102
103 EXPECT_EQ(1ul, defined_types.size());
104
105 return defined_types.front();
Christopher Wiley90be4e32015-10-20 14:55:25 -0700106 }
Christopher Wiley0522cd52015-10-28 15:39:44 -0700107
108 FakeIoDelegate io_delegate_;
Christopher Wiley41544372015-11-03 14:52:29 -0800109 vector<string> preprocessed_files_;
Christopher Wiley0522cd52015-10-28 15:39:44 -0700110 vector<string> import_paths_;
Christopher Wiley56799522015-10-31 10:17:04 -0700111 java::JavaTypeNamespace java_types_;
112 cpp::TypeNamespace cpp_types_;
Christopher Wiley90be4e32015-10-20 14:55:25 -0700113};
114
115TEST_F(AidlTest, JavaAcceptsMissingPackage) {
Christopher Wiley56799522015-10-31 10:17:04 -0700116 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700117}
118
Christopher Wiley0522cd52015-10-28 15:39:44 -0700119TEST_F(AidlTest, RejectsArraysOfBinders) {
120 import_paths_.push_back("");
121 io_delegate_.SetFileContents("bar/IBar.aidl",
122 "package bar; interface IBar {}");
123 string path = "foo/IFoo.aidl";
124 string contents = "package foo;\n"
125 "import bar.IBar;\n"
126 "interface IFoo { void f(in IBar[] input); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700127 EXPECT_EQ(nullptr, Parse(path, contents, &java_types_));
128 EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types_));
Christopher Wiley0522cd52015-10-28 15:39:44 -0700129}
130
Christopher Wiley90be4e32015-10-20 14:55:25 -0700131TEST_F(AidlTest, CppRejectsMissingPackage) {
Christopher Wiley56799522015-10-31 10:17:04 -0700132 EXPECT_EQ(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &cpp_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700133 EXPECT_NE(nullptr,
Christopher Wiley56799522015-10-31 10:17:04 -0700134 Parse("a/IFoo.aidl", "package a; interface IFoo { }", &cpp_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700135}
136
137TEST_F(AidlTest, RejectsOnewayOutParameters) {
Christopher Wiley90be4e32015-10-20 14:55:25 -0700138 string oneway_interface =
139 "package a; oneway interface IFoo { void f(out int bar); }";
140 string oneway_method =
141 "package a; interface IBar { oneway void f(out int bar); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700142 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &cpp_types_));
143 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &java_types_));
144 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &cpp_types_));
145 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700146}
147
148TEST_F(AidlTest, RejectsOnewayNonVoidReturn) {
Christopher Wiley90be4e32015-10-20 14:55:25 -0700149 string oneway_method = "package a; interface IFoo { oneway int f(); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700150 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
151 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700152}
153
Casey Dahlin57dbe242015-12-04 11:44:02 -0800154TEST_F(AidlTest, RejectsNullablePrimitive) {
155 string oneway_method = "package a; interface IFoo { @nullable int f(); }";
156 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
157 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
158}
159
Christopher Wileyec31a052016-01-25 07:28:51 -0800160TEST_F(AidlTest, ParsesNullableAnnotation) {
161 for (auto is_nullable: {true, false}) {
162 auto parse_result = Parse(
163 "a/IFoo.aidl",
164 StringPrintf( "package a; interface IFoo {%s String f(); }",
165 (is_nullable) ? "@nullable" : ""),
166 &cpp_types_);
167 ASSERT_NE(nullptr, parse_result);
Steven Moreland5557f1c2018-07-02 13:50:23 -0700168 const AidlInterface* interface = parse_result->AsInterface();
169 ASSERT_NE(nullptr, interface);
170 ASSERT_FALSE(interface->GetMethods().empty());
171 EXPECT_EQ(interface->GetMethods()[0]->GetType().IsNullable(), is_nullable);
Jiyong Parkb034bf02018-07-30 17:44:33 +0900172 cpp_types_.typenames_.Reset();
Christopher Wileyec31a052016-01-25 07:28:51 -0800173 }
174}
175
176TEST_F(AidlTest, ParsesUtf8Annotations) {
177 for (auto is_utf8: {true, false}) {
178 auto parse_result = Parse(
179 "a/IFoo.aidl",
180 StringPrintf( "package a; interface IFoo {%s String f(); }",
Christopher Wiley9f403722016-01-27 16:04:11 -0800181 (is_utf8) ? "@utf8InCpp" : ""),
Christopher Wileyb7e01172016-01-28 16:32:34 -0800182 &cpp_types_);
Christopher Wileyec31a052016-01-25 07:28:51 -0800183 ASSERT_NE(nullptr, parse_result);
Steven Moreland5557f1c2018-07-02 13:50:23 -0700184 const AidlInterface* interface = parse_result->AsInterface();
185 ASSERT_NE(nullptr, interface);
186 ASSERT_FALSE(interface->GetMethods().empty());
187 EXPECT_EQ(interface->GetMethods()[0]->GetType().IsUtf8InCpp(), is_utf8);
Jiyong Parkb034bf02018-07-30 17:44:33 +0900188 cpp_types_.typenames_.Reset();
Christopher Wileyec31a052016-01-25 07:28:51 -0800189 }
190}
191
Christopher Wiley90be4e32015-10-20 14:55:25 -0700192TEST_F(AidlTest, AcceptsOneway) {
Christopher Wiley90be4e32015-10-20 14:55:25 -0700193 string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
194 string oneway_interface =
195 "package a; oneway interface IBar { void f(int a); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700196 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
197 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
198 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &cpp_types_));
199 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700200}
Christopher Wileyef140932015-11-03 09:29:19 -0800201
202TEST_F(AidlTest, ParsesPreprocessedFile) {
203 string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
204 io_delegate_.SetFileContents("path", simple_content);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800205 EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900206 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
Christopher Wiley9ab06232016-01-27 14:55:18 -0800207 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
208 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
Christopher Wileyef140932015-11-03 09:29:19 -0800209}
210
211TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
212 string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
213 io_delegate_.SetFileContents("path", simple_content);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800214 EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900215 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
Christopher Wiley9ab06232016-01-27 14:55:18 -0800216 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
217 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
Christopher Wileyef140932015-11-03 09:29:19 -0800218}
219
Christopher Wiley41544372015-11-03 14:52:29 -0800220TEST_F(AidlTest, PreferImportToPreprocessed) {
221 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
222 io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
223 "interface IBar {}");
224 preprocessed_files_.push_back("preprocessed");
225 import_paths_.push_back("");
226 auto parse_result = Parse(
227 "p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
228 &java_types_);
229 EXPECT_NE(nullptr, parse_result);
230 // We expect to know about both kinds of IBar
Christopher Wiley9ab06232016-01-27 14:55:18 -0800231 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("one.IBar"));
232 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("another.IBar"));
Christopher Wiley41544372015-11-03 14:52:29 -0800233 // But if we request just "IBar" we should get our imported one.
Steven Moreland46e9da82018-07-27 15:45:29 -0700234 AidlTypeSpecifier ambiguous_type(AidlLocation::nowhere(), "IBar", false, nullptr, "");
Christopher Wiley9ab06232016-01-27 14:55:18 -0800235 const java::Type* type = java_types_.Find(ambiguous_type);
Christopher Wiley41544372015-11-03 14:52:29 -0800236 ASSERT_TRUE(type);
Christopher Wileyd21bfee2016-01-29 15:11:38 -0800237 EXPECT_EQ("one.IBar", type->CanonicalName());
Christopher Wiley41544372015-11-03 14:52:29 -0800238}
239
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800240TEST_F(AidlTest, WritePreprocessedFile) {
241 io_delegate_.SetFileContents("p/Outer.aidl",
242 "package p; parcelable Outer.Inner;");
243 io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
244 "interface IBar {}");
245
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900246 vector<string> args {
247 "aidl",
248 "--preprocess",
249 "preprocessed",
250 "p/Outer.aidl",
251 "one/IBar.aidl"};
252 Options options = Options::From(args);
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800253 EXPECT_TRUE(::android::aidl::preprocess_aidl(options, io_delegate_));
254
255 string output;
256 EXPECT_TRUE(io_delegate_.GetWrittenContents("preprocessed", &output));
257 EXPECT_EQ("parcelable p.Outer.Inner;\ninterface one.IBar;\n", output);
258}
259
Christopher Wiley63bce2a2015-11-03 14:55:03 -0800260TEST_F(AidlTest, RequireOuterClass) {
261 io_delegate_.SetFileContents("p/Outer.aidl",
262 "package p; parcelable Outer.Inner;");
263 import_paths_.push_back("");
264 auto parse_result = Parse(
265 "p/IFoo.aidl",
266 "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
267 &java_types_);
268 EXPECT_EQ(nullptr, parse_result);
269}
270
271TEST_F(AidlTest, ParseCompoundParcelableFromPreprocess) {
272 io_delegate_.SetFileContents("preprocessed",
273 "parcelable p.Outer.Inner;");
274 preprocessed_files_.push_back("preprocessed");
275 auto parse_result = Parse(
276 "p/IFoo.aidl",
277 "package p; interface IFoo { void f(in Inner c); }",
278 &java_types_);
279 // TODO(wiley): This should actually return nullptr because we require
280 // the outer class name. However, for legacy reasons,
281 // this behavior must be maintained. b/17415692
282 EXPECT_NE(nullptr, parse_result);
283}
284
Christopher Wiley632801d2015-11-05 14:15:49 -0800285TEST_F(AidlTest, FailOnParcelable) {
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900286 Options options1 = Options::From("aidl p/IFoo.aidl");
287 io_delegate_.SetFileContents(options1.InputFiles().front(), "package p; parcelable IFoo;");
Christopher Wiley632801d2015-11-05 14:15:49 -0800288 // By default, we shouldn't fail on parcelable.
Jiyong Parkb034bf02018-07-30 17:44:33 +0900289 EXPECT_EQ(0, ::android::aidl::compile_aidl(options1, io_delegate_));
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900290
291 Options options2 = Options::From("aidl -b p/IFoo.aidl");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900292 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
Christopher Wiley632801d2015-11-05 14:15:49 -0800293}
294
Christopher Wiley69b44cf2016-05-03 13:43:33 -0700295TEST_F(AidlTest, FailOnDuplicateConstantNames) {
296 AidlError reported_error;
297 EXPECT_EQ(nullptr,
298 Parse("p/IFoo.aidl",
299 R"(package p;
300 interface IFoo {
301 const String DUPLICATED = "d";
302 const int DUPLICATED = 1;
303 }
304 )",
305 &cpp_types_,
306 &reported_error));
307 EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
308}
309
Steven Morelandc258abc2018-07-10 14:03:38 -0700310TEST_F(AidlTest, FailOnManyDefinedTypes) {
311 AidlError reported_error;
312 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
313 R"(package p;
314 interface IFoo {}
315 parcelable Bar;
316 parcelable IBar {}
317 parcelable StructuredParcelable {}
318 interface IBaz {}
319 )",
320 &cpp_types_, &reported_error));
321 // Parse success is important for clear error handling even if the cases aren't
322 // actually supported in code generation.
323 EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
324}
325
326TEST_F(AidlTest, FailOnNoDefinedTypes) {
327 AidlError reported_error;
328 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", &cpp_types_, &reported_error));
Jiyong Parkb034bf02018-07-30 17:44:33 +0900329 EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
Steven Morelandc258abc2018-07-10 14:03:38 -0700330}
331
Roshan Pius3b2203d2016-07-22 16:13:20 -0700332TEST_F(AidlTest, FailOnMalformedConstHexValue) {
333 AidlError reported_error;
334 EXPECT_EQ(nullptr,
335 Parse("p/IFoo.aidl",
336 R"(package p;
337 interface IFoo {
338 const int BAD_HEX_VALUE = 0xffffffffffffffffff;
339 }
340 )",
341 &cpp_types_,
342 &reported_error));
343 EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
344}
345
346TEST_F(AidlTest, ParsePositiveConstHexValue) {
347 AidlError reported_error;
348 auto cpp_parse_result =
349 Parse("p/IFoo.aidl",
350 R"(package p;
351 interface IFoo {
352 const int POSITIVE_HEX_VALUE = 0xf5;
353 }
354 )",
355 &cpp_types_,
356 &reported_error);
357 EXPECT_NE(nullptr, cpp_parse_result);
Steven Moreland5557f1c2018-07-02 13:50:23 -0700358 const AidlInterface* interface = cpp_parse_result->AsInterface();
359 ASSERT_NE(nullptr, interface);
Steven Moreland693640b2018-07-19 13:46:27 -0700360 const auto& cpp_constants = interface->GetConstantDeclarations();
361 EXPECT_EQ((size_t)1, cpp_constants.size());
362 EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
363 ASSERT_EQ(AidlConstantValue::Type::INTEGER, cpp_constants[0]->GetValue().GetType());
364 EXPECT_EQ("245", cpp_constants[0]->GetValue().ToString());
Roshan Pius3b2203d2016-07-22 16:13:20 -0700365}
366
367TEST_F(AidlTest, ParseNegativeConstHexValue) {
368 AidlError reported_error;
369 auto cpp_parse_result =
370 Parse("p/IFoo.aidl",
371 R"(package p;
372 interface IFoo {
373 const int NEGATIVE_HEX_VALUE = 0xffffffff;
374 }
375 )",
376 &cpp_types_,
377 &reported_error);
378 EXPECT_NE(nullptr, cpp_parse_result);
Steven Moreland5557f1c2018-07-02 13:50:23 -0700379 const AidlInterface* interface = cpp_parse_result->AsInterface();
380 ASSERT_NE(nullptr, interface);
Steven Moreland693640b2018-07-19 13:46:27 -0700381 const auto& cpp_constants = interface->GetConstantDeclarations();
382 EXPECT_EQ((size_t)1, cpp_constants.size());
383 EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
384 ASSERT_EQ(AidlConstantValue::Type::INTEGER, cpp_constants[0]->GetValue().GetType());
385 EXPECT_EQ("-1", cpp_constants[0]->GetValue().ToString());
Roshan Pius3b2203d2016-07-22 16:13:20 -0700386}
387
Ningyuan Wangd17c58b2016-09-29 14:33:14 -0700388TEST_F(AidlTest, UnderstandsNestedParcelables) {
389 io_delegate_.SetFileContents(
390 "p/Outer.aidl",
391 "package p; parcelable Outer.Inner cpp_header \"baz/header\";");
392 import_paths_.push_back("");
393 const string input_path = "p/IFoo.aidl";
394 const string input = "package p; import p.Outer; interface IFoo"
395 " { Outer.Inner get(); }";
396
397 auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
398 EXPECT_NE(nullptr, cpp_parse_result);
399 auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Outer.Inner");
400 ASSERT_NE(nullptr, cpp_type);
401 // C++ uses "::" instead of "." to refer to a inner class.
402 EXPECT_EQ("::p::Outer::Inner", cpp_type->CppType());
403}
404
Christopher Wiley9078d722015-11-17 10:23:49 -0800405TEST_F(AidlTest, UnderstandsNativeParcelables) {
406 io_delegate_.SetFileContents(
407 "p/Bar.aidl",
Casey Dahlincd639212015-12-15 12:51:04 -0800408 "package p; parcelable Bar cpp_header \"baz/header\";");
Christopher Wiley9078d722015-11-17 10:23:49 -0800409 import_paths_.push_back("");
410 const string input_path = "p/IFoo.aidl";
411 const string input = "package p; import p.Bar; interface IFoo { }";
412
413 // C++ understands C++ specific stuff
414 auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
415 EXPECT_NE(nullptr, cpp_parse_result);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800416 auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Bar");
Christopher Wiley9078d722015-11-17 10:23:49 -0800417 ASSERT_NE(nullptr, cpp_type);
Casey Dahlina2f77c42015-12-01 18:26:02 -0800418 EXPECT_EQ("::p::Bar", cpp_type->CppType());
Christopher Wiley9078d722015-11-17 10:23:49 -0800419 set<string> headers;
Casey Dahlina2f77c42015-12-01 18:26:02 -0800420 cpp_type->GetHeaders(&headers);
Christopher Wiley9078d722015-11-17 10:23:49 -0800421 EXPECT_EQ(1u, headers.size());
422 EXPECT_EQ(1u, headers.count("baz/header"));
423
424 // Java ignores C++ specific stuff
425 auto java_parse_result = Parse(input_path, input, &java_types_);
426 EXPECT_NE(nullptr, java_parse_result);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800427 auto java_type = java_types_.FindTypeByCanonicalName("p.Bar");
Christopher Wiley9078d722015-11-17 10:23:49 -0800428 ASSERT_NE(nullptr, java_type);
429 EXPECT_EQ("p.Bar", java_type->InstantiableName());
430}
431
Christopher Wileyf8136192016-04-12 14:19:35 -0700432TEST_F(AidlTest, WritesCorrectDependencyFile) {
433 // While the in tree build system always gives us an output file name,
434 // other android tools take advantage of our ability to infer the intended
435 // file name. This test makes sure we handle this correctly.
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900436 vector<string> args = {
437 "aidl",
438 "-d dep/file/path",
439 "-o place/for/output",
440 "p/IFoo.aidl"};
441 Options options = Options::From(args);
442 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900443 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Christopher Wileyf8136192016-04-12 14:19:35 -0700444 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900445 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Christopher Wileyf8136192016-04-12 14:19:35 -0700446 EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
447}
448
Dan Willemsen93298ee2016-11-10 23:55:55 -0800449TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
450 // While the in tree build system always gives us an output file name,
451 // other android tools take advantage of our ability to infer the intended
452 // file name. This test makes sure we handle this correctly.
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900453 vector<string> args = {
454 "aidl",
455 "-d dep/file/path",
456 "--ninja",
457 "-o place/for/output",
458 "p/IFoo.aidl"};
459 Options options = Options::From(args);
460 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900461 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Dan Willemsen93298ee2016-11-10 23:55:55 -0800462 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900463 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Dan Willemsen93298ee2016-11-10 23:55:55 -0800464 EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
465}
466
Christopher Wileyb1bbdf82016-04-21 11:43:45 -0700467TEST_F(AidlTest, WritesTrivialDependencyFileForParcelable) {
468 // The SDK uses aidl to decide whether a .aidl file is a parcelable. It does
469 // this by calling aidl with every .aidl file it finds, then parsing the
470 // generated dependency files. Those that reference .java output files are
471 // for interfaces and those that do not are parcelables. However, for both
472 // parcelables and interfaces, we *must* generate a non-empty dependency file.
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900473 vector<string> args = {
474 "aidl",
475 "-o place/for/output",
476 "-d dep/file/path",
477 "p/Foo.aidl"};
478 Options options = Options::From(args);
479 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900480 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Christopher Wileyb1bbdf82016-04-21 11:43:45 -0700481 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900482 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Christopher Wileyb1bbdf82016-04-21 11:43:45 -0700483 EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDepFileContents);
484}
485
Jiyong Parkccf00f82018-07-17 01:39:23 +0900486/* not working until type_namespace.h is fixed
487TEST_F(AidlTest, AcceptsNestedContainerType) {
488 string nested_in_iface = "package a; interface IFoo {\n"
489 " List<int, List<String, bool>> foo(); }";
490 string nested_in_parcelable = "package a; parcelable IData {\n"
491 " List<int, List<String, bool>> foo;}";
492 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &java_types_));
493 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &cpp_types_));
494 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &java_types_));
495 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &cpp_types_));
496}
497*/
498
Jiyong Park02da7422018-07-16 16:00:26 +0900499TEST_F(AidlTest, ApiDump) {
500 io_delegate_.SetFileContents(
501 "foo/bar/IFoo.aidl",
502 "package foo.bar;\n"
503 "import foo.bar.Data;\n"
504 "interface IFoo {\n"
505 " int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
506 " int foo2(@utf8InCpp String x, inout List<String> y);\n"
507 " IFoo foo3(IFoo foo);\n"
508 " Data getData();\n"
509 "}\n");
510 io_delegate_.SetFileContents("foo/bar/Data.aidl",
511 "package foo.bar;\n"
512 "import foo.bar.IFoo;\n"
513 "parcelable Data {\n"
514 " int x;\n"
515 " int y;\n"
516 " IFoo foo;\n"
517 " List<IFoo> a;\n"
518 " List<foo.bar.IFoo> b;\n"
519 "}\n");
520 io_delegate_.SetFileContents("api.aidl", "");
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900521 vector<string> args = {
522 "aidl",
523 "--dumpapi",
524 "api.aidl",
525 "foo/bar/IFoo.aidl",
526 "foo/bar/Data.aidl"};
527 Options options = Options::From(args);
Jiyong Park02da7422018-07-16 16:00:26 +0900528 bool result = dump_api(options, io_delegate_);
529 ASSERT_TRUE(result);
530 string actual;
531 EXPECT_TRUE(io_delegate_.GetWrittenContents("api.aidl", &actual));
532 EXPECT_EQ(actual, R"(package foo.bar {
533 parcelable Data {
534 int x;
535 int y;
536 foo.bar.IFoo foo;
537 List<foo.bar.IFoo> a;
538 List<foo.bar.IFoo> b;
539 }
540
541 interface IFoo {
542 int foo(out int[] a, String b, boolean c, inout List<String> d);
543 int foo2(@utf8InCpp String x, inout List<String> y);
544 foo.bar.IFoo foo3(foo.bar.IFoo foo);
545 foo.bar.Data getData();
546 }
547
548}
549)");
550}
551
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900552TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900553 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
554 io_delegate_.SetFileContents(options.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900555 "package p; interface IFoo {"
556 "void foo(List<String, String> a);}");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900557 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900558
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900559 io_delegate_.SetFileContents(options.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900560 "package p; interface IFoo {"
561 "void foo(Map<String> a);}");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900562 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900563
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900564 Options options2 = Options::From("aidl p/Data.aidl Data.java");
565 io_delegate_.SetFileContents(options2.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900566 "package p; parcelable Data {"
567 "List<String, String> foo;}");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900568 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900569
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900570 io_delegate_.SetFileContents(options2.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900571 "package p; parcelable Data {"
572 "Map<String> foo;}");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900573 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
574}
575
576TEST_F(AidlTest, MultipleTypesInSingleFile) {
577 Options options = Options::From("aidl --lang=java -o out foo/bar/Foo.aidl");
578 io_delegate_.SetFileContents(options.InputFiles().front(),
579 "package foo.bar;\n"
580 "interface IFoo1 { int foo(); }\n"
581 "interface IFoo2 { int foo(); }\n"
582 "parcelable Data { int a; int b;}\n");
583
584 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
585
586 string content;
587 for (const auto file :
588 {"out/foo/bar/IFoo1.java", "out/foo/bar/IFoo2.java", "out/foo/bar/Data.java"}) {
589 content.clear();
590 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
591 EXPECT_FALSE(content.empty());
592 }
593}
594
595TEST_F(AidlTest, MultipleTypesInSingleFileCpp) {
596 Options options = Options::From("aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl");
597 io_delegate_.SetFileContents(options.InputFiles().front(),
598 "package foo.bar;\n"
599 "interface IFoo1 { int foo(); }\n"
600 "interface IFoo2 { int foo(); }\n"
601 "parcelable Data { int a; int b;}\n");
602
603 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
604
605 string content;
606 for (const auto file : {
607 "out/IFoo1.cpp", "out/IFoo2.cpp", "out/Data.cpp",
608 "out/include/foo/bar/IFoo1.h", "out/include/foo/bar/IFoo2.h", "out/include/foo/bar/Data.h",
609 "out/include/foo/bar/BpFoo1.h", "out/include/foo/bar/BpFoo2.h", "out/include/foo/bar/BpData.h",
610 "out/include/foo/bar/BnFoo1.h", "out/include/foo/bar/BnFoo2.h", "out/include/foo/bar/BnData.h"}) {
611 content.clear();
612 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
613 EXPECT_FALSE(content.empty());
614 }
615}
616
617TEST_F(AidlTest, MultipleInputFiles) {
618 Options options = Options::From(
619 "aidl --lang=java -o out foo/bar/IFoo.aidl foo/bar/Data.aidl");
620
621 io_delegate_.SetFileContents(options.InputFiles().at(0),
622 "package foo.bar;\n"
623 "import foo.bar.Data;\n"
624 "interface IFoo { Data getData(); }\n");
625
626 io_delegate_.SetFileContents(options.InputFiles().at(1),
627 "package foo.bar;\n"
628 "import foo.bar.IFoo;\n"
629 "parcelable Data { IFoo foo; }\n");
630
631 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
632
633 string content;
634 for (const auto file : {
635 "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
636 content.clear();
637 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
638 EXPECT_FALSE(content.empty());
639 }
640}
641
642TEST_F(AidlTest, MultipleInputFilesCpp) {
643 Options options = Options::From("aidl --lang=cpp -o out -h out/include "
644 "foo/bar/IFoo.aidl foo/bar/Data.aidl");
645
646 io_delegate_.SetFileContents(options.InputFiles().at(0),
647 "package foo.bar;\n"
648 "import foo.bar.Data;\n"
649 "interface IFoo { Data getData(); }\n");
650
651 io_delegate_.SetFileContents(options.InputFiles().at(1),
652 "package foo.bar;\n"
653 "import foo.bar.IFoo;\n"
654 "parcelable Data { IFoo foo; }\n");
655
656 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
657
658 string content;
659 for (const auto file : {
660 "out/IFoo.cpp", "out/Data.cpp",
661 "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
662 "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
663 "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
664 content.clear();
665 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
666 EXPECT_FALSE(content.empty());
667 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900668}
669
Jiyong Park309668e2018-07-28 16:55:44 +0900670TEST_F(AidlTest, ConflictWithMetaTransactions) {
671 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
672 // int getInterfaceVersion() is one of the meta transactions
673 io_delegate_.SetFileContents(options.InputFiles().front(),
674 "package p; interface IFoo {"
675 "int getInterfaceVersion(); }");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900676 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jiyong Park309668e2018-07-28 16:55:44 +0900677
678 // boolean getInterfaceVersion() is not, but should be prevented
679 // because return type is not part of a method signature
680 io_delegate_.SetFileContents(options.InputFiles().front(),
681 "package p; interface IFoo {"
682 "boolean getInterfaceVersion(); }");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900683 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jiyong Park309668e2018-07-28 16:55:44 +0900684
685 // this is another reserved name
686 io_delegate_.SetFileContents(options.InputFiles().front(),
687 "package p; interface IFoo {"
688 "String getTransactionName(int code); }");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900689 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jiyong Park309668e2018-07-28 16:55:44 +0900690
691 // this is not a meta interface method as it differs type arguments
692 io_delegate_.SetFileContents(options.InputFiles().front(),
693 "package p; interface IFoo {"
694 "String getTransactionName(); }");
Jiyong Parkb034bf02018-07-30 17:44:33 +0900695 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jiyong Park309668e2018-07-28 16:55:44 +0900696}
697
Christopher Wiley90be4e32015-10-20 14:55:25 -0700698} // namespace aidl
699} // namespace android