blob: 0d2ba53654db0a814c5c97354416062f20d9342f [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
Christopher Wileyb1bbdf82016-04-21 11:43:45 -070051const char kExpectedParcelableDepFileContents[] =
52R"( : \
53 p/Foo.aidl
54
55p/Foo.aidl :
56)";
57
Christopher Wileyf8136192016-04-12 14:19:35 -070058} // namespace
Christopher Wiley90be4e32015-10-20 14:55:25 -070059
60class AidlTest : public ::testing::Test {
61 protected:
Christopher Wiley56799522015-10-31 10:17:04 -070062 void SetUp() override {
63 java_types_.Init();
64 cpp_types_.Init();
65 }
66
Christopher Wiley90be4e32015-10-20 14:55:25 -070067 unique_ptr<AidlInterface> Parse(const string& path,
68 const string& contents,
Christopher Wiley69b44cf2016-05-03 13:43:33 -070069 TypeNamespace* types,
70 AidlError* error = nullptr) {
Christopher Wiley0522cd52015-10-28 15:39:44 -070071 io_delegate_.SetFileContents(path, contents);
Christopher Wiley90be4e32015-10-20 14:55:25 -070072 unique_ptr<AidlInterface> ret;
73 std::vector<std::unique_ptr<AidlImport>> imports;
Christopher Wiley69b44cf2016-05-03 13:43:33 -070074 AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
Christopher Wiley41544372015-11-03 14:52:29 -080075 preprocessed_files_,
Christopher Wiley0522cd52015-10-28 15:39:44 -070076 import_paths_,
Christopher Wiley90be4e32015-10-20 14:55:25 -070077 path,
Christopher Wiley0522cd52015-10-28 15:39:44 -070078 io_delegate_,
Christopher Wiley90be4e32015-10-20 14:55:25 -070079 types,
80 &ret,
81 &imports);
Christopher Wiley69b44cf2016-05-03 13:43:33 -070082 if (error != nullptr) {
83 *error = actual_error;
84 }
Christopher Wiley90be4e32015-10-20 14:55:25 -070085 return ret;
86 }
Christopher Wiley0522cd52015-10-28 15:39:44 -070087
88 FakeIoDelegate io_delegate_;
Christopher Wiley41544372015-11-03 14:52:29 -080089 vector<string> preprocessed_files_;
Christopher Wiley0522cd52015-10-28 15:39:44 -070090 vector<string> import_paths_;
Christopher Wiley56799522015-10-31 10:17:04 -070091 java::JavaTypeNamespace java_types_;
92 cpp::TypeNamespace cpp_types_;
Christopher Wiley90be4e32015-10-20 14:55:25 -070093};
94
95TEST_F(AidlTest, JavaAcceptsMissingPackage) {
Christopher Wiley56799522015-10-31 10:17:04 -070096 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -070097}
98
Christopher Wiley0522cd52015-10-28 15:39:44 -070099TEST_F(AidlTest, RejectsArraysOfBinders) {
100 import_paths_.push_back("");
101 io_delegate_.SetFileContents("bar/IBar.aidl",
102 "package bar; interface IBar {}");
103 string path = "foo/IFoo.aidl";
104 string contents = "package foo;\n"
105 "import bar.IBar;\n"
106 "interface IFoo { void f(in IBar[] input); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700107 EXPECT_EQ(nullptr, Parse(path, contents, &java_types_));
108 EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types_));
Christopher Wiley0522cd52015-10-28 15:39:44 -0700109}
110
Christopher Wiley90be4e32015-10-20 14:55:25 -0700111TEST_F(AidlTest, CppRejectsMissingPackage) {
Christopher Wiley56799522015-10-31 10:17:04 -0700112 EXPECT_EQ(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &cpp_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700113 EXPECT_NE(nullptr,
Christopher Wiley56799522015-10-31 10:17:04 -0700114 Parse("a/IFoo.aidl", "package a; interface IFoo { }", &cpp_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700115}
116
117TEST_F(AidlTest, RejectsOnewayOutParameters) {
Christopher Wiley90be4e32015-10-20 14:55:25 -0700118 string oneway_interface =
119 "package a; oneway interface IFoo { void f(out int bar); }";
120 string oneway_method =
121 "package a; interface IBar { oneway void f(out int bar); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700122 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &cpp_types_));
123 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &java_types_));
124 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &cpp_types_));
125 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700126}
127
128TEST_F(AidlTest, RejectsOnewayNonVoidReturn) {
Christopher Wiley90be4e32015-10-20 14:55:25 -0700129 string oneway_method = "package a; interface IFoo { oneway int f(); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700130 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
131 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700132}
133
Casey Dahlin57dbe242015-12-04 11:44:02 -0800134TEST_F(AidlTest, RejectsNullablePrimitive) {
135 string oneway_method = "package a; interface IFoo { @nullable int f(); }";
136 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
137 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
138}
139
Christopher Wileyec31a052016-01-25 07:28:51 -0800140TEST_F(AidlTest, ParsesNullableAnnotation) {
141 for (auto is_nullable: {true, false}) {
142 auto parse_result = Parse(
143 "a/IFoo.aidl",
144 StringPrintf( "package a; interface IFoo {%s String f(); }",
145 (is_nullable) ? "@nullable" : ""),
146 &cpp_types_);
147 ASSERT_NE(nullptr, parse_result);
148 ASSERT_FALSE(parse_result->GetMethods().empty());
149 EXPECT_EQ(parse_result->GetMethods()[0]->GetType().IsNullable(),
150 is_nullable);
151 }
152}
153
154TEST_F(AidlTest, ParsesUtf8Annotations) {
155 for (auto is_utf8: {true, false}) {
156 auto parse_result = Parse(
157 "a/IFoo.aidl",
158 StringPrintf( "package a; interface IFoo {%s String f(); }",
Christopher Wiley9f403722016-01-27 16:04:11 -0800159 (is_utf8) ? "@utf8InCpp" : ""),
Christopher Wileyb7e01172016-01-28 16:32:34 -0800160 &cpp_types_);
Christopher Wileyec31a052016-01-25 07:28:51 -0800161 ASSERT_NE(nullptr, parse_result);
162 ASSERT_FALSE(parse_result->GetMethods().empty());
Christopher Wiley9f403722016-01-27 16:04:11 -0800163 EXPECT_EQ(parse_result->GetMethods()[0]->GetType().IsUtf8InCpp(),
Christopher Wileyec31a052016-01-25 07:28:51 -0800164 is_utf8);
165 }
166}
167
Christopher Wiley90be4e32015-10-20 14:55:25 -0700168TEST_F(AidlTest, AcceptsOneway) {
Christopher Wiley90be4e32015-10-20 14:55:25 -0700169 string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
170 string oneway_interface =
171 "package a; oneway interface IBar { void f(int a); }";
Christopher Wiley56799522015-10-31 10:17:04 -0700172 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
173 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
174 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &cpp_types_));
175 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &java_types_));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700176}
Christopher Wileyef140932015-11-03 09:29:19 -0800177
178TEST_F(AidlTest, ParsesPreprocessedFile) {
179 string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
180 io_delegate_.SetFileContents("path", simple_content);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800181 EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
Christopher Wileyef140932015-11-03 09:29:19 -0800182 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_));
Christopher Wiley9ab06232016-01-27 14:55:18 -0800183 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
184 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
Christopher Wileyef140932015-11-03 09:29:19 -0800185}
186
187TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
188 string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
189 io_delegate_.SetFileContents("path", simple_content);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800190 EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
Christopher Wileyef140932015-11-03 09:29:19 -0800191 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_));
Christopher Wiley9ab06232016-01-27 14:55:18 -0800192 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
193 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
Christopher Wileyef140932015-11-03 09:29:19 -0800194}
195
Christopher Wiley41544372015-11-03 14:52:29 -0800196TEST_F(AidlTest, PreferImportToPreprocessed) {
197 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
198 io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
199 "interface IBar {}");
200 preprocessed_files_.push_back("preprocessed");
201 import_paths_.push_back("");
202 auto parse_result = Parse(
203 "p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
204 &java_types_);
205 EXPECT_NE(nullptr, parse_result);
206 // We expect to know about both kinds of IBar
Christopher Wiley9ab06232016-01-27 14:55:18 -0800207 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("one.IBar"));
208 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("another.IBar"));
Christopher Wiley41544372015-11-03 14:52:29 -0800209 // But if we request just "IBar" we should get our imported one.
Christopher Wiley9ab06232016-01-27 14:55:18 -0800210 AidlType ambiguous_type("IBar", 0, "", false /* not an array */);
211 const java::Type* type = java_types_.Find(ambiguous_type);
Christopher Wiley41544372015-11-03 14:52:29 -0800212 ASSERT_TRUE(type);
Christopher Wileyd21bfee2016-01-29 15:11:38 -0800213 EXPECT_EQ("one.IBar", type->CanonicalName());
Christopher Wiley41544372015-11-03 14:52:29 -0800214}
215
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800216TEST_F(AidlTest, WritePreprocessedFile) {
217 io_delegate_.SetFileContents("p/Outer.aidl",
218 "package p; parcelable Outer.Inner;");
219 io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
220 "interface IBar {}");
221
222 JavaOptions options;
223 options.output_file_name_ = "preprocessed";
224 options.files_to_preprocess_.resize(2);
225 options.files_to_preprocess_[0] = "p/Outer.aidl";
226 options.files_to_preprocess_[1] = "one/IBar.aidl";
227 EXPECT_TRUE(::android::aidl::preprocess_aidl(options, io_delegate_));
228
229 string output;
230 EXPECT_TRUE(io_delegate_.GetWrittenContents("preprocessed", &output));
231 EXPECT_EQ("parcelable p.Outer.Inner;\ninterface one.IBar;\n", output);
232}
233
Christopher Wiley63bce2a2015-11-03 14:55:03 -0800234TEST_F(AidlTest, RequireOuterClass) {
235 io_delegate_.SetFileContents("p/Outer.aidl",
236 "package p; parcelable Outer.Inner;");
237 import_paths_.push_back("");
238 auto parse_result = Parse(
239 "p/IFoo.aidl",
240 "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
241 &java_types_);
242 EXPECT_EQ(nullptr, parse_result);
243}
244
245TEST_F(AidlTest, ParseCompoundParcelableFromPreprocess) {
246 io_delegate_.SetFileContents("preprocessed",
247 "parcelable p.Outer.Inner;");
248 preprocessed_files_.push_back("preprocessed");
249 auto parse_result = Parse(
250 "p/IFoo.aidl",
251 "package p; interface IFoo { void f(in Inner c); }",
252 &java_types_);
253 // TODO(wiley): This should actually return nullptr because we require
254 // the outer class name. However, for legacy reasons,
255 // this behavior must be maintained. b/17415692
256 EXPECT_NE(nullptr, parse_result);
257}
258
Christopher Wiley632801d2015-11-05 14:15:49 -0800259TEST_F(AidlTest, FailOnParcelable) {
260 JavaOptions options;
261 options.input_file_name_ = "p/IFoo.aidl";
262 io_delegate_.SetFileContents(options.input_file_name_,
263 "package p; parcelable IFoo;");
264 // By default, we shouldn't fail on parcelable.
265 EXPECT_EQ(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
266 options.fail_on_parcelable_ = true;
267 EXPECT_NE(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
268}
269
Christopher Wiley69b44cf2016-05-03 13:43:33 -0700270TEST_F(AidlTest, FailOnDuplicateConstantNames) {
271 AidlError reported_error;
272 EXPECT_EQ(nullptr,
273 Parse("p/IFoo.aidl",
274 R"(package p;
275 interface IFoo {
276 const String DUPLICATED = "d";
277 const int DUPLICATED = 1;
278 }
279 )",
280 &cpp_types_,
281 &reported_error));
282 EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
283}
284
Roshan Pius3b2203d2016-07-22 16:13:20 -0700285TEST_F(AidlTest, FailOnMalformedConstHexValue) {
286 AidlError reported_error;
287 EXPECT_EQ(nullptr,
288 Parse("p/IFoo.aidl",
289 R"(package p;
290 interface IFoo {
291 const int BAD_HEX_VALUE = 0xffffffffffffffffff;
292 }
293 )",
294 &cpp_types_,
295 &reported_error));
296 EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
297}
298
299TEST_F(AidlTest, ParsePositiveConstHexValue) {
300 AidlError reported_error;
301 auto cpp_parse_result =
302 Parse("p/IFoo.aidl",
303 R"(package p;
304 interface IFoo {
305 const int POSITIVE_HEX_VALUE = 0xf5;
306 }
307 )",
308 &cpp_types_,
309 &reported_error);
310 EXPECT_NE(nullptr, cpp_parse_result);
311 const auto& cpp_int_constants = cpp_parse_result->GetIntConstants();
312 EXPECT_EQ((size_t)1, cpp_int_constants.size());
313 EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_int_constants[0]->GetName());
314 EXPECT_EQ(245, cpp_int_constants[0]->GetValue());
315}
316
317TEST_F(AidlTest, ParseNegativeConstHexValue) {
318 AidlError reported_error;
319 auto cpp_parse_result =
320 Parse("p/IFoo.aidl",
321 R"(package p;
322 interface IFoo {
323 const int NEGATIVE_HEX_VALUE = 0xffffffff;
324 }
325 )",
326 &cpp_types_,
327 &reported_error);
328 EXPECT_NE(nullptr, cpp_parse_result);
329 const auto& cpp_int_constants = cpp_parse_result->GetIntConstants();
330 EXPECT_EQ((size_t)1, cpp_int_constants.size());
331 EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_int_constants[0]->GetName());
332 EXPECT_EQ(-1, cpp_int_constants[0]->GetValue());
333}
334
Christopher Wiley9078d722015-11-17 10:23:49 -0800335TEST_F(AidlTest, UnderstandsNativeParcelables) {
336 io_delegate_.SetFileContents(
337 "p/Bar.aidl",
Casey Dahlincd639212015-12-15 12:51:04 -0800338 "package p; parcelable Bar cpp_header \"baz/header\";");
Christopher Wiley9078d722015-11-17 10:23:49 -0800339 import_paths_.push_back("");
340 const string input_path = "p/IFoo.aidl";
341 const string input = "package p; import p.Bar; interface IFoo { }";
342
343 // C++ understands C++ specific stuff
344 auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
345 EXPECT_NE(nullptr, cpp_parse_result);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800346 auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Bar");
Christopher Wiley9078d722015-11-17 10:23:49 -0800347 ASSERT_NE(nullptr, cpp_type);
Casey Dahlina2f77c42015-12-01 18:26:02 -0800348 EXPECT_EQ("::p::Bar", cpp_type->CppType());
Christopher Wiley9078d722015-11-17 10:23:49 -0800349 set<string> headers;
Casey Dahlina2f77c42015-12-01 18:26:02 -0800350 cpp_type->GetHeaders(&headers);
Christopher Wiley9078d722015-11-17 10:23:49 -0800351 EXPECT_EQ(1u, headers.size());
352 EXPECT_EQ(1u, headers.count("baz/header"));
353
354 // Java ignores C++ specific stuff
355 auto java_parse_result = Parse(input_path, input, &java_types_);
356 EXPECT_NE(nullptr, java_parse_result);
Christopher Wiley9ab06232016-01-27 14:55:18 -0800357 auto java_type = java_types_.FindTypeByCanonicalName("p.Bar");
Christopher Wiley9078d722015-11-17 10:23:49 -0800358 ASSERT_NE(nullptr, java_type);
359 EXPECT_EQ("p.Bar", java_type->InstantiableName());
360}
361
Christopher Wileyf8136192016-04-12 14:19:35 -0700362TEST_F(AidlTest, WritesCorrectDependencyFile) {
363 // While the in tree build system always gives us an output file name,
364 // other android tools take advantage of our ability to infer the intended
365 // file name. This test makes sure we handle this correctly.
366 JavaOptions options;
367 options.input_file_name_ = "p/IFoo.aidl";
368 options.output_base_folder_ = "place/for/output";
369 options.dep_file_name_ = "dep/file/path";
370 io_delegate_.SetFileContents(options.input_file_name_,
371 "package p; interface IFoo {}");
372 EXPECT_EQ(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
373 string actual_dep_file_contents;
374 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.dep_file_name_,
375 &actual_dep_file_contents));
376 EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
377}
378
Christopher Wileyb1bbdf82016-04-21 11:43:45 -0700379TEST_F(AidlTest, WritesTrivialDependencyFileForParcelable) {
380 // The SDK uses aidl to decide whether a .aidl file is a parcelable. It does
381 // this by calling aidl with every .aidl file it finds, then parsing the
382 // generated dependency files. Those that reference .java output files are
383 // for interfaces and those that do not are parcelables. However, for both
384 // parcelables and interfaces, we *must* generate a non-empty dependency file.
385 JavaOptions options;
386 options.input_file_name_ = "p/Foo.aidl";
387 options.output_base_folder_ = "place/for/output";
388 options.dep_file_name_ = "dep/file/path";
389 io_delegate_.SetFileContents(options.input_file_name_,
390 "package p; parcelable Foo;");
391 EXPECT_EQ(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
392 string actual_dep_file_contents;
393 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.dep_file_name_,
394 &actual_dep_file_contents));
395 EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDepFileContents);
396}
397
Christopher Wiley90be4e32015-10-20 14:55:25 -0700398} // namespace aidl
399} // namespace android