1 /*
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 "aidl.h"
18
19 #include <android-base/format.h>
20 #include <android-base/stringprintf.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23
24 #include <map>
25 #include <memory>
26 #include <set>
27 #include <string>
28 #include <vector>
29
30 #include "aidl_checkapi.h"
31 #include "aidl_dumpapi.h"
32 #include "aidl_language.h"
33 #include "aidl_to_cpp.h"
34 #include "aidl_to_java.h"
35 #include "aidl_to_ndk.h"
36 #include "comments.h"
37 #include "logging.h"
38 #include "options.h"
39 #include "tests/fake_io_delegate.h"
40
41 using android::aidl::internals::parse_preprocessed_file;
42 using android::aidl::test::FakeIoDelegate;
43 using android::base::StringPrintf;
44 using std::map;
45 using std::set;
46 using std::string;
47 using std::unique_ptr;
48 using std::vector;
49 using testing::HasSubstr;
50 using testing::TestParamInfo;
51 using testing::internal::CaptureStderr;
52 using testing::internal::GetCapturedStderr;
53
54 namespace android {
55 namespace aidl {
56 namespace {
57
58 const char kExpectedDepFileContents[] =
59 R"(place/for/output/p/IFoo.java : \
60 p/IFoo.aidl
61
62 p/IFoo.aidl :
63 )";
64
65 const char kExpectedNinjaDepFileContents[] =
66 R"(place/for/output/p/IFoo.java : \
67 p/IFoo.aidl
68 )";
69
70 const char kExpectedParcelableDeclarationDepFileContents[] =
71 R"( : \
72 p/Foo.aidl
73
74 p/Foo.aidl :
75 )";
76
77 const char kExpectedStructuredParcelableDepFileContents[] =
78 R"(place/for/output/p/Foo.java : \
79 p/Foo.aidl
80
81 p/Foo.aidl :
82 )";
83
84 } // namespace
85
86 class AidlTest : public ::testing::TestWithParam<Options::Language> {
87 protected:
Parse(const string & path,const string & contents,AidlTypenames & typenames_,Options::Language lang,AidlError * error=nullptr,const vector<string> additional_arguments={})88 AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
89 Options::Language lang, AidlError* error = nullptr,
90 const vector<string> additional_arguments = {}) {
91 io_delegate_.SetFileContents(path, contents);
92 vector<string> args;
93 args.emplace_back("aidl");
94 args.emplace_back("--lang=" + to_string(lang));
95 for (const string& s : additional_arguments) {
96 args.emplace_back(s);
97 }
98 for (const string& f : preprocessed_files_) {
99 args.emplace_back("--preprocessed=" + f);
100 }
101 for (const string& i : import_paths_) {
102 args.emplace_back("--include=" + i);
103 }
104 args.emplace_back(path);
105 Options options = Options::From(args);
106 vector<string> imported_files;
107 ImportResolver import_resolver{io_delegate_, path, import_paths_, {}};
108 AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
109 path, options, io_delegate_, &typenames_, &imported_files);
110
111 if (error != nullptr) {
112 *error = actual_error;
113 }
114
115 if (actual_error != AidlError::OK) {
116 return nullptr;
117 }
118
119 const auto& defined_types = typenames_.MainDocument().DefinedTypes();
120 EXPECT_EQ(1ul, defined_types.size());
121
122 return defined_types.front().get();
123 }
124
GetLanguage()125 Options::Language GetLanguage() { return GetParam(); }
126
127 FakeIoDelegate io_delegate_;
128 vector<string> preprocessed_files_;
129 set<string> import_paths_;
130 AidlTypenames typenames_;
131 };
132
133 // Instantiate the AidlTest parameterized suite, calling all of the TEST_P
134 // tests with each of the supported languages as a parameter.
135 INSTANTIATE_TEST_SUITE_P(AidlTestSuite, AidlTest,
136 testing::Values(Options::Language::CPP, Options::Language::JAVA,
137 Options::Language::NDK, Options::Language::RUST),
__anon758595f20202(const testing::TestParamInfo<Options::Language>& info) 138 [](const testing::TestParamInfo<Options::Language>& info) {
139 return to_string(info.param);
140 });
141
TEST_P(AidlTest,AcceptMissingPackage)142 TEST_P(AidlTest, AcceptMissingPackage) {
143 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, GetLanguage()));
144 }
145
TEST_P(AidlTest,EndsInSingleLineComment)146 TEST_P(AidlTest, EndsInSingleLineComment) {
147 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, GetLanguage()));
148 }
149
TEST_P(AidlTest,InterfaceRequiresCorrectPath)150 TEST_P(AidlTest, InterfaceRequiresCorrectPath) {
151 const string expected_stderr =
152 "ERROR: a/Foo.aidl:1.11-21: IBar should be declared in a file called a/IBar.aidl\n";
153 const std::string file_contents = "package a; interface IBar {}";
154 CaptureStderr();
155 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
156 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
157 }
158
TEST_P(AidlTest,ParcelableRequiresCorrectPath)159 TEST_P(AidlTest, ParcelableRequiresCorrectPath) {
160 const string expected_stderr =
161 "ERROR: a/Foo.aidl:1.11-21: Bar should be declared in a file called a/Bar.aidl\n";
162 const std::string file_contents = "package a; interface Bar {}";
163 CaptureStderr();
164 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
165 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
166 }
167
TEST_P(AidlTest,UnstructuredParcelableRequiresCorrectPath)168 TEST_P(AidlTest, UnstructuredParcelableRequiresCorrectPath) {
169 const string expected_stderr =
170 "ERROR: a/Foo.aidl:1.22-26: Bar should be declared in a file called a/Bar.aidl\n";
171 const std::string file_contents = "package a; parcelable Bar cpp_header \"anything.h\";";
172 CaptureStderr();
173 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
174 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
175 }
176
TEST_P(AidlTest,EnumRequiresCorrectPath)177 TEST_P(AidlTest, EnumRequiresCorrectPath) {
178 const string expected_stderr =
179 "ERROR: a/Foo.aidl:1.16-20: Bar should be declared in a file called a/Bar.aidl\n";
180 const std::string file_contents = "package a; enum Bar { A, }";
181 CaptureStderr();
182 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
183 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
184 }
185
TEST_P(AidlTest,RejectsArraysOfBinders)186 TEST_P(AidlTest, RejectsArraysOfBinders) {
187 import_paths_.emplace("");
188 io_delegate_.SetFileContents("bar/IBar.aidl",
189 "package bar; interface IBar {}");
190 const string path = "foo/IFoo.aidl";
191 const string contents =
192 "package foo;\n"
193 "import bar.IBar;\n"
194 "interface IFoo { void f(in IBar[] input); }";
195 const string expected_stderr = "ERROR: foo/IFoo.aidl:3.27-32: Binder type cannot be an array\n";
196 CaptureStderr();
197 EXPECT_EQ(nullptr, Parse(path, contents, typenames_, GetLanguage()));
198 EXPECT_EQ(expected_stderr, GetCapturedStderr());
199 }
200
TEST_P(AidlTest,SupportOnlyOutParameters)201 TEST_P(AidlTest, SupportOnlyOutParameters) {
202 const string interface_list = "package a; interface IBar { void f(out List<String> bar); }";
203 EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, GetLanguage()));
204 }
205
TEST_P(AidlTest,RejectOutParametersForIBinder)206 TEST_P(AidlTest, RejectOutParametersForIBinder) {
207 const string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
208 const string expected_ibinder_stderr =
209 "ERROR: a/IBaz.aidl:1.47-51: 'bar' can't be an out parameter because IBinder can only be an "
210 "in parameter.\n";
211 CaptureStderr();
212 EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, GetLanguage()));
213 EXPECT_EQ(expected_ibinder_stderr, GetCapturedStderr());
214 }
215
TEST_P(AidlTest,RejectsOutParametersInOnewayInterface)216 TEST_P(AidlTest, RejectsOutParametersInOnewayInterface) {
217 const string oneway_interface = "package a; oneway interface IBar { void f(out int[] bar); }";
218 const string expected_stderr =
219 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
220 CaptureStderr();
221 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
222 EXPECT_EQ(expected_stderr, GetCapturedStderr());
223 }
224
TEST_P(AidlTest,RejectsOutParametersInOnewayMethod)225 TEST_P(AidlTest, RejectsOutParametersInOnewayMethod) {
226 const string oneway_method = "package a; interface IBar { oneway void f(out int[] bar); }";
227 const string expected_stderr =
228 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
229 CaptureStderr();
230 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, GetLanguage()));
231 EXPECT_EQ(expected_stderr, GetCapturedStderr());
232 }
233
TEST_P(AidlTest,RejectsOnewayNonVoidReturn)234 TEST_P(AidlTest, RejectsOnewayNonVoidReturn) {
235 const string oneway_method = "package a; interface IFoo { oneway int f(); }";
236 const string expected_stderr =
237 "ERROR: a/IFoo.aidl:1.39-41: oneway method 'f' cannot return a value\n";
238 CaptureStderr();
239 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
240 EXPECT_EQ(expected_stderr, GetCapturedStderr());
241 }
242
TEST_P(AidlTest,RejectsNullablePrimitive)243 TEST_P(AidlTest, RejectsNullablePrimitive) {
244 const string oneway_method = "package a; interface IFoo { @nullable int f(); }";
245 const string expected_stderr =
246 "ERROR: a/IFoo.aidl:1.38-42: Primitive type cannot get nullable annotation\n";
247 CaptureStderr();
248 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
249 EXPECT_EQ(expected_stderr, GetCapturedStderr());
250 }
251
TEST_P(AidlTest,AcceptNullableList)252 TEST_P(AidlTest, AcceptNullableList) {
253 const string oneway_method = "package a; interface IFoo { @nullable List<String> f(); }";
254 const string expected_stderr = "";
255 CaptureStderr();
256 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
257 EXPECT_EQ(expected_stderr, GetCapturedStderr());
258 }
259
TEST_P(AidlTest,RejectsDuplicatedArgumentNames)260 TEST_P(AidlTest, RejectsDuplicatedArgumentNames) {
261 const string method = "package a; interface IFoo { void f(int a, int a); }";
262 const string expected_stderr =
263 "ERROR: a/IFoo.aidl:1.33-35: method 'f' has duplicate argument name 'a'\n";
264 CaptureStderr();
265 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
266 EXPECT_EQ(expected_stderr, GetCapturedStderr());
267 }
268
TEST_P(AidlTest,RejectsDuplicatedFieldNames)269 TEST_P(AidlTest, RejectsDuplicatedFieldNames) {
270 const string method = "package a; parcelable Foo { int a; String a; }";
271 const string expected_stderr = "ERROR: a/Foo.aidl:1.42-44: 'Foo' has duplicate field name 'a'\n";
272 CaptureStderr();
273 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
274 EXPECT_EQ(expected_stderr, GetCapturedStderr());
275 }
276
TEST_P(AidlTest,RejectsRepeatedAnnotations)277 TEST_P(AidlTest, RejectsRepeatedAnnotations) {
278 const string method = R"(@Hide @Hide parcelable Foo {})";
279 const string expected_stderr =
280 "ERROR: Foo.aidl:1.23-27: 'Hide' is repeated, but not allowed. Previous location: "
281 "Foo.aidl:1.1-6\n";
282 CaptureStderr();
283 EXPECT_EQ(nullptr, Parse("Foo.aidl", method, typenames_, GetLanguage()));
284 EXPECT_EQ(expected_stderr, GetCapturedStderr());
285 }
286
TEST_P(AidlTest,AcceptsEmptyParcelable)287 TEST_P(AidlTest, AcceptsEmptyParcelable) {
288 CaptureStderr();
289 EXPECT_NE(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage()));
290 EXPECT_EQ("", GetCapturedStderr());
291 }
292
TEST_P(AidlTest,RejectsDuplicatedAnnotationParams)293 TEST_P(AidlTest, RejectsDuplicatedAnnotationParams) {
294 const string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
295 const string expected_stderr = "ERROR: a/IFoo.aidl:1.56-62: Trying to redefine parameter foo.\n";
296 CaptureStderr();
297 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
298 EXPECT_EQ(expected_stderr, GetCapturedStderr());
299 }
300
TEST_P(AidlTest,RejectUnsupportedInterfaceAnnotations)301 TEST_P(AidlTest, RejectUnsupportedInterfaceAnnotations) {
302 AidlError error;
303 const string method = "package a; @nullable interface IFoo { int f(); }";
304 CaptureStderr();
305 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
306 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
307 EXPECT_EQ(AidlError::BAD_TYPE, error);
308 }
309
TEST_P(AidlTest,RejectUnsupportedTypeAnnotations)310 TEST_P(AidlTest, RejectUnsupportedTypeAnnotations) {
311 AidlError error;
312 const string method = "package a; interface IFoo { @JavaOnlyStableParcelable int f(); }";
313 CaptureStderr();
314 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
315 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaOnlyStableParcelable is not available."));
316 EXPECT_EQ(AidlError::BAD_TYPE, error);
317 }
318
TEST_P(AidlTest,RejectUnsupportedParcelableAnnotations)319 TEST_P(AidlTest, RejectUnsupportedParcelableAnnotations) {
320 AidlError error;
321 const string method = "package a; @nullable parcelable IFoo cpp_header \"IFoo.h\";";
322 CaptureStderr();
323 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
324 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
325 EXPECT_EQ(AidlError::BAD_TYPE, error);
326 }
327
TEST_P(AidlTest,RejectUnsupportedParcelableDefineAnnotations)328 TEST_P(AidlTest, RejectUnsupportedParcelableDefineAnnotations) {
329 AidlError error;
330 const string method = "package a; @nullable parcelable IFoo { String a; String b; }";
331 CaptureStderr();
332 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
333 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
334 EXPECT_EQ(AidlError::BAD_TYPE, error);
335 }
336
TEST_P(AidlTest,ParsesNonNullableAnnotation)337 TEST_P(AidlTest, ParsesNonNullableAnnotation) {
338 auto parse_result =
339 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
340 ASSERT_NE(nullptr, parse_result);
341 const AidlInterface* interface = parse_result->AsInterface();
342 ASSERT_NE(nullptr, interface);
343 ASSERT_FALSE(interface->GetMethods().empty());
344 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsNullable());
345 }
346
TEST_P(AidlTest,ParsesNullableAnnotation)347 TEST_P(AidlTest, ParsesNullableAnnotation) {
348 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @nullable String f(); }",
349 typenames_, GetLanguage());
350 ASSERT_NE(nullptr, parse_result);
351 const AidlInterface* interface = parse_result->AsInterface();
352 ASSERT_NE(nullptr, interface);
353 ASSERT_FALSE(interface->GetMethods().empty());
354 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsNullable());
355 }
356
TEST_P(AidlTest,ParsesNonUtf8Annotations)357 TEST_P(AidlTest, ParsesNonUtf8Annotations) {
358 auto parse_result =
359 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
360 ASSERT_NE(nullptr, parse_result);
361 const AidlInterface* interface = parse_result->AsInterface();
362 ASSERT_NE(nullptr, interface);
363 ASSERT_FALSE(interface->GetMethods().empty());
364 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
365 }
366
TEST_P(AidlTest,ParsesUtf8Annotations)367 TEST_P(AidlTest, ParsesUtf8Annotations) {
368 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @utf8InCpp String f(); }",
369 typenames_, GetLanguage());
370 ASSERT_NE(nullptr, parse_result);
371 const AidlInterface* interface = parse_result->AsInterface();
372 ASSERT_NE(nullptr, interface);
373 ASSERT_FALSE(interface->GetMethods().empty());
374 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
375 }
376
TEST_P(AidlTest,VintfRequiresStructuredAndStability)377 TEST_P(AidlTest, VintfRequiresStructuredAndStability) {
378 AidlError error;
379 const string expected_stderr =
380 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
381 "\"vintf\"'\n"
382 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
383 "--structured\n";
384 CaptureStderr();
385 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
386 GetLanguage(), &error));
387 EXPECT_EQ(expected_stderr, GetCapturedStderr());
388 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
389 }
390
TEST_P(AidlTest,VintfRequiresStructured)391 TEST_P(AidlTest, VintfRequiresStructured) {
392 AidlError error;
393 const string expected_stderr =
394 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
395 "--structured\n";
396 CaptureStderr();
397 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
398 GetLanguage(), &error, {"--stability", "vintf"}));
399 EXPECT_EQ(expected_stderr, GetCapturedStderr());
400 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
401 }
402
TEST_P(AidlTest,VintfRequiresSpecifiedStability)403 TEST_P(AidlTest, VintfRequiresSpecifiedStability) {
404 AidlError error;
405 const string expected_stderr =
406 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
407 "\"vintf\"'\n";
408 CaptureStderr();
409 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
410 GetLanguage(), &error, {"--structured"}));
411 EXPECT_EQ(expected_stderr, GetCapturedStderr());
412 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
413 }
414
TEST_P(AidlTest,ParsesStabilityAnnotations)415 TEST_P(AidlTest, ParsesStabilityAnnotations) {
416 AidlError error;
417 auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
418 GetLanguage(), &error, {"--structured", "--stability", "vintf"});
419 ASSERT_EQ(AidlError::OK, error);
420 ASSERT_NE(nullptr, parse_result);
421 const AidlInterface* interface = parse_result->AsInterface();
422 ASSERT_NE(nullptr, interface);
423 ASSERT_TRUE(interface->IsVintfStability());
424 }
425
TEST_F(AidlTest,ParsesJavaOnlyStableParcelable)426 TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
427 Options java_options = Options::From("aidl -o out --structured a/Foo.aidl");
428 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out/include a/Foo.aidl");
429 Options cpp_structured_options =
430 Options::From("aidl --lang=cpp --structured -o out -h out/include a/Foo.aidl");
431 Options rust_options = Options::From("aidl --lang=rust -o out --structured a/Foo.aidl");
432 io_delegate_.SetFileContents(
433 "a/Foo.aidl",
434 StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
435
436 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
437 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
438 const string expected_stderr =
439 "ERROR: a/Foo.aidl:1.48-52: Cannot declared parcelable in a --structured interface. "
440 "Parcelable must be defined in AIDL directly.\n";
441 CaptureStderr();
442 EXPECT_NE(0, ::android::aidl::compile_aidl(cpp_structured_options, io_delegate_));
443 EXPECT_EQ(expected_stderr, GetCapturedStderr());
444
445 CaptureStderr();
446 EXPECT_NE(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
447 EXPECT_EQ(expected_stderr, GetCapturedStderr());
448 }
449
TEST_F(AidlTest,ParcelableSupportJavaDeriveToString)450 TEST_F(AidlTest, ParcelableSupportJavaDeriveToString) {
451 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
452 @JavaDerive(toString=true) parcelable Foo { int a; float b; })");
453 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
454 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
455
456 string java_out;
457 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
458 EXPECT_THAT(java_out, testing::HasSubstr("public String toString() {"));
459
460 // Other backends shouldn't be bothered
461 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
462 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
463
464 Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
465 EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
466 }
467
TEST_F(AidlTest,UnionSupportJavaDeriveToString)468 TEST_F(AidlTest, UnionSupportJavaDeriveToString) {
469 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
470 @JavaDerive(toString=true) union Foo { int a; int[] b; })");
471 CaptureStderr();
472 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
473 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
474 EXPECT_EQ("", GetCapturedStderr());
475
476 const string expected_to_string_method = R"--(
477 @Override
478 public String toString() {
479 switch (_tag) {
480 case a: return "a.Foo.a(" + (getA()) + ")";
481 case b: return "a.Foo.b(" + (java.util.Arrays.toString(getB())) + ")";
482 }
483 throw new IllegalStateException("unknown field: " + _tag);
484 }
485 )--";
486
487 string java_out;
488 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
489 EXPECT_THAT(java_out, testing::HasSubstr(expected_to_string_method));
490 }
491
TEST_F(AidlTest,ParcelableSupportJavaDeriveEquals)492 TEST_F(AidlTest, ParcelableSupportJavaDeriveEquals) {
493 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
494 @JavaDerive(equals=true) parcelable Foo { int a; float b; })");
495 CaptureStderr();
496 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
497 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
498 EXPECT_EQ("", GetCapturedStderr());
499
500 const std::string expected = R"--(
501 @Override
502 public boolean equals(Object other) {
503 if (this == other) return true;
504 if (other == null) return false;
505 if (!(other instanceof Foo)) return false;
506 Foo that = (Foo)other;
507 if (!java.util.Objects.deepEquals(a, that.a)) return false;
508 if (!java.util.Objects.deepEquals(b, that.b)) return false;
509 return true;
510 }
511
512 @Override
513 public int hashCode() {
514 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(a, b).toArray());
515 }
516 )--";
517
518 string java_out;
519 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
520 EXPECT_THAT(java_out, testing::HasSubstr(expected));
521 }
522
TEST_F(AidlTest,UnionSupportJavaDeriveEquals)523 TEST_F(AidlTest, UnionSupportJavaDeriveEquals) {
524 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
525 @JavaDerive(equals=true) union Foo { int a; int[] b; })");
526 CaptureStderr();
527 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
528 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
529 EXPECT_EQ("", GetCapturedStderr());
530
531 const std::string expected = R"--(
532 @Override
533 public boolean equals(Object other) {
534 if (this == other) return true;
535 if (other == null) return false;
536 if (!(other instanceof Foo)) return false;
537 Foo that = (Foo)other;
538 if (_tag != that._tag) return false;
539 if (!java.util.Objects.deepEquals(_value, that._value)) return false;
540 return true;
541 }
542
543 @Override
544 public int hashCode() {
545 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(_tag, _value).toArray());
546 }
547 )--";
548
549 string java_out;
550 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
551 EXPECT_THAT(java_out, testing::HasSubstr(expected));
552 }
553
TEST_F(AidlTest,RejectsJavaDeriveAnnotation)554 TEST_F(AidlTest, RejectsJavaDeriveAnnotation) {
555 {
556 io_delegate_.SetFileContents("a/Foo.aidl",
557 "package a; @JavaDerive(blah=true) parcelable Foo{}");
558 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
559 CaptureStderr();
560 EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
561 const std::string expected_stderr =
562 "ERROR: a/Foo.aidl:1.11-34: Parameter blah not supported for annotation JavaDerive.";
563 EXPECT_THAT(GetCapturedStderr(),
564 HasSubstr("Parameter blah not supported for annotation JavaDerive."));
565 }
566
567 {
568 io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive interface IFoo{}");
569 Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
570 CaptureStderr();
571 EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
572 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
573 }
574
575 {
576 io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive enum IFoo { A=1, }");
577 Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
578 CaptureStderr();
579 EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
580 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
581 }
582 }
583
TEST_P(AidlTest,ParseDescriptorAnnotation)584 TEST_P(AidlTest, ParseDescriptorAnnotation) {
585 AidlError error;
586 auto parse_result = Parse("IFoo.aidl", R"(@Descriptor(value="IBar") interface IFoo{})",
587 typenames_, GetLanguage(), &error, {"--structured"});
588 ASSERT_EQ(AidlError::OK, error);
589 ASSERT_NE(nullptr, parse_result);
590 const AidlInterface* interface = parse_result->AsInterface();
591 ASSERT_NE(nullptr, interface);
592 ASSERT_EQ("IBar", interface->GetDescriptor());
593 }
594
TEST_P(AidlTest,AcceptsOnewayMethod)595 TEST_P(AidlTest, AcceptsOnewayMethod) {
596 const string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
597 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
598 }
599
TEST_P(AidlTest,AcceptsOnewayInterface)600 TEST_P(AidlTest, AcceptsOnewayInterface) {
601 const string oneway_interface = "package a; oneway interface IBar { void f(int a); }";
602 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
603 }
604
TEST_P(AidlTest,AcceptsAnnotatedOnewayMethod)605 TEST_P(AidlTest, AcceptsAnnotatedOnewayMethod) {
606 const string oneway_method =
607 "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
608 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
609 }
610
TEST_P(AidlTest,AnnotationsInMultiplePlaces)611 TEST_P(AidlTest, AnnotationsInMultiplePlaces) {
612 const string oneway_method =
613 "package a; interface IFoo { @UnsupportedAppUsage oneway @Hide void f(int a); }";
614 const AidlDefinedType* defined = Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage());
615 ASSERT_NE(nullptr, defined);
616 const AidlInterface* iface = defined->AsInterface();
617 ASSERT_NE(nullptr, iface);
618
619 const auto& methods = iface->GetMethods();
620 ASSERT_EQ(1u, methods.size());
621 const auto& method = methods[0];
622 const AidlTypeSpecifier& ret_type = method->GetType();
623
624 // TODO(b/151102494): these annotations should be on the method
625 ASSERT_NE(nullptr, ret_type.UnsupportedAppUsage());
626 ASSERT_TRUE(ret_type.IsHide());
627 }
628
TEST_P(AidlTest,WritesComments)629 TEST_P(AidlTest, WritesComments) {
630 string foo_interface =
631 R"(package a;
632 /* foo */
633 interface IFoo {
634 /* i */
635 int i();
636 // j
637 @nullable String j();
638 // k1
639 /* k2 */
640 @UnsupportedAppUsage oneway void k(int a);
641 })";
642
643 CaptureStderr();
644 auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, GetLanguage());
645 EXPECT_NE(nullptr, parse_result);
646 EXPECT_EQ("", GetCapturedStderr());
647
648 EXPECT_EQ((Comments{{"/* foo */"}}), parse_result->GetComments());
649
650 const AidlInterface* interface = parse_result->AsInterface();
651 EXPECT_EQ((Comments{{"/* i */"}}), interface->GetMethods()[0]->GetComments());
652 EXPECT_EQ((Comments{{"// j\n"}}), interface->GetMethods()[1]->GetComments());
653 EXPECT_EQ((Comments{{"// k1\n"}, {"/* k2 */"}}), interface->GetMethods()[2]->GetComments());
654 }
655
TEST_P(AidlTest,CppHeaderCanBeIdentifierAsWell)656 TEST_P(AidlTest, CppHeaderCanBeIdentifierAsWell) {
657 io_delegate_.SetFileContents("p/cpp_header.aidl",
658 R"(package p;
659 parcelable cpp_header cpp_header "bar/header";)");
660 import_paths_.emplace("");
661 const string input_path = "p/IFoo.aidl";
662 const string input = R"(package p;
663 import p.cpp_header;
664 interface IFoo {
665 // get bar
666 cpp_header get();
667 })";
668
669 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
670 EXPECT_NE(nullptr, parse_result);
671 const AidlInterface* interface = parse_result->AsInterface();
672 EXPECT_EQ((Comments{{"// get bar\n"}}), interface->GetMethods()[0]->GetComments());
673 }
674
TEST_F(AidlTest,ParsesPreprocessedFile)675 TEST_F(AidlTest, ParsesPreprocessedFile) {
676 string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
677 io_delegate_.SetFileContents("path", simple_content);
678 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
679 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
680 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
681 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
682 }
683
TEST_F(AidlTest,ParsesPreprocessedFileWithWhitespace)684 TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
685 string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
686 io_delegate_.SetFileContents("path", simple_content);
687
688 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
689 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
690 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
691 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
692 }
693
TEST_P(AidlTest,PreferImportToPreprocessed)694 TEST_P(AidlTest, PreferImportToPreprocessed) {
695 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
696 io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
697 "interface IBar {}");
698 preprocessed_files_.push_back("preprocessed");
699 import_paths_.emplace("");
700 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
701 typenames_, GetLanguage());
702 EXPECT_NE(nullptr, parse_result);
703
704 // We expect to know about both kinds of IBar
705 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
706 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
707 // But if we request just "IBar" we should get our imported one.
708 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, {});
709 ambiguous_type.Resolve(typenames_);
710 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
711 }
712
713 // Special case of PreferImportToPreprocessed. Imported type should be preferred
714 // even when the preprocessed file already has the same type.
TEST_P(AidlTest,B147918827)715 TEST_P(AidlTest, B147918827) {
716 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;\ninterface one.IBar;");
717 io_delegate_.SetFileContents("one/IBar.aidl",
718 "package one; "
719 "interface IBar {}");
720 preprocessed_files_.push_back("preprocessed");
721 import_paths_.emplace("");
722 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
723 typenames_, GetLanguage());
724 EXPECT_NE(nullptr, parse_result);
725
726 // We expect to know about both kinds of IBar
727 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
728 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
729 // But if we request just "IBar" we should get our imported one.
730 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, {});
731 ambiguous_type.Resolve(typenames_);
732 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
733 }
734
TEST_F(AidlTest,WritePreprocessedFile)735 TEST_F(AidlTest, WritePreprocessedFile) {
736 io_delegate_.SetFileContents("p/Outer.aidl",
737 "package p; parcelable Outer.Inner;");
738 io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
739 "interface IBar {}");
740
741 vector<string> args {
742 "aidl",
743 "--preprocess",
744 "preprocessed",
745 "p/Outer.aidl",
746 "one/IBar.aidl"};
747 Options options = Options::From(args);
748 EXPECT_TRUE(::android::aidl::preprocess_aidl(options, io_delegate_));
749
750 string output;
751 EXPECT_TRUE(io_delegate_.GetWrittenContents("preprocessed", &output));
752 EXPECT_EQ("parcelable p.Outer.Inner;\ninterface one.IBar;\n", output);
753 }
754
TEST_P(AidlTest,SupportDeprecated)755 TEST_P(AidlTest, SupportDeprecated) {
756 struct TestCase {
757 std::string output_file;
758 std::string annotation;
759 };
760
761 auto CheckDeprecated = [&](const std::string& filename, const std::string& contents,
762 std::vector<std::pair<Options::Language, TestCase>> expectations) {
763 io_delegate_.SetFileContents(filename, contents);
764
765 auto options = Options::From("aidl --lang=" + to_string(GetLanguage()) + " " + filename +
766 " --out=out --header_out=out");
767 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
768 for (const auto& [lang, test_case] : expectations) {
769 if (lang != GetLanguage()) continue;
770 string output;
771 EXPECT_TRUE(io_delegate_.GetWrittenContents(test_case.output_file, &output));
772 EXPECT_THAT(output, HasSubstr(test_case.annotation));
773 }
774 };
775
776 // Emit escaped string for notes
777 CheckDeprecated(
778 "IFoo.aidl",
779 R"(interface IFoo {
780 /**
781 * @note asdf
782 * @deprecated a really long deprecation message
783 *
784 * which is really long
785 * @param foo bar
786 */
787 List<String> foo();
788 })",
789 {
790 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
791 {Options::Language::CPP,
792 {"out/IFoo.h",
793 R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
794 {Options::Language::NDK,
795 {"out/aidl/IFoo.h",
796 R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
797 {Options::Language::RUST,
798 {"out/IFoo.rs",
799 R"(#[deprecated = "a really long deprecation message which is really long"])"}},
800 });
801
802 // In AIDL @deprecated can be in block comments as well as javadoc style
803 CheckDeprecated(
804 "IFoo.aidl",
805 "interface IFoo {\n"
806 " /* @deprecated use bar() */\n"
807 " List<String> foo();\n"
808 "}",
809 {
810 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
811 {Options::Language::JAVA, {"out/IFoo.java", "/** @deprecated use bar() */"}},
812 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
813 {Options::Language::NDK,
814 {"out/aidl/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
815 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated = \"use bar()\"]"}},
816 });
817
818 // but not in line comments
819 auto parsed = Parse("IFoo.aidl", "// @deprecated\ninterface IFoo {}", typenames_, GetLanguage());
820 EXPECT_FALSE(parsed->IsDeprecated());
821
822 // parcelable
823 CheckDeprecated("Foo.aidl",
824 "parcelable Foo {\n"
825 " /** @deprecated use bar*/\n"
826 " int foo = 0;\n"
827 "}",
828 {
829 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
830 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
831 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
832 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
833 });
834
835 // interface constants
836 CheckDeprecated("IFoo.aidl",
837 "interface IFoo {\n"
838 " /** @deprecated use bar*/\n"
839 " const int FOO = 0;\n"
840 "}",
841 {
842 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
843 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
844 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
845 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
846 });
847
848 // union fields
849 CheckDeprecated("Foo.aidl",
850 "union Foo {\n"
851 " int bar = 0;\n"
852 " /** @deprecated use bar*/\n"
853 " int foo;\n"
854 "}",
855 {
856 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
857 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
858 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
859 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
860 });
861
862 CheckDeprecated("Foo.aidl",
863 "/** @deprecated use Bar */\n"
864 "parcelable Foo {}",
865 {
866 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
867 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
868 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
869 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
870 });
871
872 CheckDeprecated("Foo.aidl",
873 "/** @deprecated use Bar */\n"
874 "union Foo { int foo = 0; }",
875 {
876 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
877 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
878 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
879 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
880 });
881
882 CheckDeprecated("IFoo.aidl",
883 "/** @deprecated use IBar */\n"
884 "interface IFoo {}",
885 {
886 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
887 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
888 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
889 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
890 });
891
892 CheckDeprecated("Foo.aidl",
893 "/** @deprecated use IBar */\n"
894 "enum Foo { FOO }",
895 {
896 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
897 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
898 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
899 // TODO(b/177860423) support "deprecated" in Rust enum
900 // {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
901 });
902 }
903
TEST_P(AidlTest,RequireOuterClass)904 TEST_P(AidlTest, RequireOuterClass) {
905 const string expected_stderr = "ERROR: p/IFoo.aidl:1.54-60: Failed to resolve 'Inner'\n";
906 io_delegate_.SetFileContents("p/Outer.aidl",
907 "package p; parcelable Outer.Inner;");
908 import_paths_.emplace("");
909 CaptureStderr();
910 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
911 "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
912 typenames_, GetLanguage()));
913 EXPECT_EQ(expected_stderr, GetCapturedStderr());
914 }
915
TEST_P(AidlTest,ParseCompoundParcelableFromPreprocess)916 TEST_P(AidlTest, ParseCompoundParcelableFromPreprocess) {
917 io_delegate_.SetFileContents("preprocessed",
918 "parcelable p.Outer.Inner;");
919 preprocessed_files_.push_back("preprocessed");
920 auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
921 typenames_, GetLanguage());
922 // TODO(wiley): This should actually return nullptr because we require
923 // the outer class name. However, for legacy reasons,
924 // this behavior must be maintained. b/17415692
925 EXPECT_NE(nullptr, parse_result);
926 }
927
TEST_F(AidlTest,FailOnParcelable)928 TEST_F(AidlTest, FailOnParcelable) {
929 const string expected_foo_stderr =
930 "ERROR: p/IFoo.aidl:1.22-27: Refusing to generate code with unstructured parcelables. "
931 "Declared parcelables should be in their own file and/or cannot be used with --structured "
932 "interfaces.\n";
933 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; parcelable IFoo;");
934
935 // By default, we shouldn't fail on parcelable.
936 Options options1 = Options::From("aidl p/IFoo.aidl");
937 CaptureStderr();
938 EXPECT_EQ(0, ::android::aidl::compile_aidl(options1, io_delegate_));
939 EXPECT_EQ("", GetCapturedStderr());
940
941 // -b considers this an error
942 Options options2 = Options::From("aidl -b p/IFoo.aidl");
943 CaptureStderr();
944 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
945 EXPECT_EQ(expected_foo_stderr, GetCapturedStderr());
946
947 const string expected_bar_stderr =
948 "ERROR: p/IBar.aidl:1.22-26: Refusing to generate code with unstructured parcelables. "
949 "Declared parcelables should be in their own file and/or cannot be used with --structured "
950 "interfaces.\n";
951 io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
952
953 // With '-b' option, a parcelable and an interface should fail.
954 Options options3 = Options::From("aidl p/IBar.aidl");
955 CaptureStderr();
956 EXPECT_EQ(0, ::android::aidl::compile_aidl(options3, io_delegate_));
957 EXPECT_EQ("", GetCapturedStderr());
958 Options options4 = Options::From("aidl -b p/IBar.aidl");
959 CaptureStderr();
960 EXPECT_NE(0, ::android::aidl::compile_aidl(options4, io_delegate_));
961 EXPECT_EQ(expected_bar_stderr, GetCapturedStderr());
962 }
963
TEST_P(AidlTest,StructuredFailOnUnstructuredParcelable)964 TEST_P(AidlTest, StructuredFailOnUnstructuredParcelable) {
965 const string expected_stderr =
966 "ERROR: ./o/WhoKnowsWhat.aidl:1.22-35: o.WhoKnowsWhat is not structured, but this is a "
967 "structured interface.\n";
968 io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl", "package o; parcelable WhoKnowsWhat;");
969 import_paths_.emplace("");
970 AidlError error;
971 CaptureStderr();
972 EXPECT_EQ(
973 nullptr,
974 Parse("p/IFoo.aidl",
975 "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
976 typenames_, GetLanguage(), &error, {"--structured"}));
977 EXPECT_EQ(expected_stderr, GetCapturedStderr());
978 EXPECT_EQ(AidlError::NOT_STRUCTURED, error);
979 }
980
TEST_P(AidlTest,FailOnDuplicateConstantNames)981 TEST_P(AidlTest, FailOnDuplicateConstantNames) {
982 AidlError error;
983 const string expected_stderr =
984 "ERROR: p/IFoo.aidl:4.34-45: Found duplicate constant name 'DUPLICATED'\n";
985 CaptureStderr();
986 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
987 R"(package p;
988 interface IFoo {
989 const String DUPLICATED = "d";
990 const int DUPLICATED = 1;
991 }
992 )",
993 typenames_, GetLanguage(), &error));
994 EXPECT_EQ(expected_stderr, GetCapturedStderr());
995 EXPECT_EQ(AidlError::BAD_TYPE, error);
996 }
997
TEST_P(AidlTest,FailOnTooBigConstant)998 TEST_P(AidlTest, FailOnTooBigConstant) {
999 AidlError error;
1000 const string expected_stderr =
1001 "ERROR: p/IFoo.aidl:3.48-52: Invalid type specifier for an int32 literal: byte\n";
1002 CaptureStderr();
1003 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1004 R"(package p;
1005 interface IFoo {
1006 const byte type2small = 256;
1007 }
1008 )",
1009 typenames_, GetLanguage(), &error));
1010 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1011 EXPECT_EQ(AidlError::BAD_TYPE, error);
1012 }
1013
TEST_F(AidlTest,BoolConstantsEvaluatesToIntegers)1014 TEST_F(AidlTest, BoolConstantsEvaluatesToIntegers) {
1015 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { const int y = true; }");
1016 CaptureStderr();
1017 auto options = Options::From("aidl --lang java -o out a/Foo.aidl");
1018 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
1019 EXPECT_EQ("", GetCapturedStderr());
1020 string code;
1021 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
1022 EXPECT_THAT(code, testing::HasSubstr("public static final int y = 1;"));
1023 }
1024
TEST_F(AidlTest,AidlConstantValue_EvaluatedValue)1025 TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) {
1026 using Ptr = unique_ptr<AidlConstantValue>;
1027 const AidlLocation& loc = AIDL_LOCATION_HERE;
1028
1029 EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, "'c'"))->EvaluatedValue<char16_t>());
1030 EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>());
1031 EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>());
1032 EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>());
1033
1034 AidlBinaryConstExpression one_plus_one(loc, Ptr(AidlConstantValue::Integral(loc, "1")), "+",
1035 Ptr(AidlConstantValue::Integral(loc, "1")));
1036 EXPECT_EQ(2, one_plus_one.EvaluatedValue<int32_t>());
1037
1038 auto values = unique_ptr<vector<Ptr>>{new vector<Ptr>};
1039 values->emplace_back(AidlConstantValue::String(loc, "\"hello\""));
1040 values->emplace_back(AidlConstantValue::String(loc, "\"world\""));
1041 vector<string> expected{"hello", "world"};
1042 EXPECT_EQ(
1043 expected,
1044 Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>());
1045 }
1046
TEST_F(AidlTest,AidlConstantCharacterDefault)1047 TEST_F(AidlTest, AidlConstantCharacterDefault) {
1048 AidlTypeSpecifier char_type(AIDL_LOCATION_HERE, "char", false, nullptr, {});
1049 auto default_value = unique_ptr<AidlConstantValue>(AidlConstantValue::Default(char_type));
1050 EXPECT_EQ("'\\0'", default_value->ValueString(char_type, cpp::ConstantValueDecorator));
1051 EXPECT_EQ("'\\0'", default_value->ValueString(char_type, ndk::ConstantValueDecorator));
1052 EXPECT_EQ("'\\0'", default_value->ValueString(char_type, java::ConstantValueDecorator));
1053 }
1054
TEST_P(AidlTest,FailOnManyDefinedTypes)1055 TEST_P(AidlTest, FailOnManyDefinedTypes) {
1056 AidlError error;
1057 const string expected_stderr =
1058 "ERROR: p/IFoo.aidl:3.33-38: You must declare only one type per file.\n";
1059 CaptureStderr();
1060 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1061 R"(package p;
1062 interface IFoo {}
1063 parcelable IBar {}
1064 parcelable StructuredParcelable {}
1065 interface IBaz {}
1066 )",
1067 typenames_, GetLanguage(), &error));
1068 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1069 // Parse success is important for clear error handling even if the cases aren't
1070 // actually supported in code generation.
1071 EXPECT_EQ(AidlError::BAD_TYPE, error);
1072 }
1073
TEST_P(AidlTest,FailOnNoDefinedTypes)1074 TEST_P(AidlTest, FailOnNoDefinedTypes) {
1075 AidlError error;
1076 const string expected_stderr = "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected $end\n";
1077 CaptureStderr();
1078 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, GetLanguage(), &error));
1079 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1080 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1081 }
1082
TEST_P(AidlTest,FailOnEmptyListWithComma)1083 TEST_P(AidlTest, FailOnEmptyListWithComma) {
1084 AidlError error;
1085 const string expected_stderr =
1086 "ERROR: p/Foo.aidl:1.45-47: syntax error, unexpected ',', expecting '}'\n";
1087 CaptureStderr();
1088 EXPECT_EQ(nullptr, Parse("p/Foo.aidl", R"(package p; parcelable Foo { uint64_t[] a = { , }; })",
1089 typenames_, GetLanguage(), &error));
1090 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1091 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1092 }
1093
TEST_P(AidlTest,FailOnMalformedConstHexValue)1094 TEST_P(AidlTest, FailOnMalformedConstHexValue) {
1095 AidlError error;
1096 const string expected_stderr =
1097 "ERROR: p/IFoo.aidl:3.50-71: Could not parse hexvalue: 0xffffffffffffffffff\n";
1098 CaptureStderr();
1099 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1100 R"(package p;
1101 interface IFoo {
1102 const int BAD_HEX_VALUE = 0xffffffffffffffffff;
1103 }
1104 )",
1105 typenames_, GetLanguage(), &error));
1106 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1107 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1108 }
1109
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsIdentifier)1110 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsIdentifier) {
1111 AidlError error;
1112 const string expected_stderr =
1113 "ERROR: p/IFoo.aidl:1.25-26: syntax error, unexpected ';', expecting identifier or "
1114 "cpp_header (which can also be used as an identifier)\n";
1115 CaptureStderr();
1116 // Notice the trailing dot(.) in the name, which isn't a correct name
1117 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p; parcelable A.; )", typenames_,
1118 GetLanguage(), &error));
1119 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1120 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1121 }
1122
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsPackage)1123 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsPackage) {
1124 AidlError error;
1125 const string expected_stderr =
1126 "ERROR: p/IFoo.aidl:1.11-12: syntax error, unexpected ';', expecting identifier or "
1127 "cpp_header (which can also be used as an identifier)\n";
1128 CaptureStderr();
1129 // Notice the trailing dot(.) in the package name
1130 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p.; parcelable A; )", typenames_,
1131 GetLanguage(), &error));
1132 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1133 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1134 }
1135
TEST_P(AidlTest,ParsePositiveConstHexValue)1136 TEST_P(AidlTest, ParsePositiveConstHexValue) {
1137 AidlError error;
1138 auto parse_result = Parse("p/IFoo.aidl",
1139 R"(package p;
1140 interface IFoo {
1141 const int POSITIVE_HEX_VALUE = 0xf5;
1142 }
1143 )",
1144 typenames_, GetLanguage(), &error);
1145 EXPECT_NE(nullptr, parse_result);
1146 const AidlInterface* interface = parse_result->AsInterface();
1147 ASSERT_NE(nullptr, interface);
1148 const auto& cpp_constants = interface->GetConstantDeclarations();
1149 EXPECT_EQ((size_t)1, cpp_constants.size());
1150 EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
1151 EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
1152 EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1153 }
1154
TEST_P(AidlTest,ParseNegativeConstHexValue)1155 TEST_P(AidlTest, ParseNegativeConstHexValue) {
1156 AidlError error;
1157 auto parse_result = Parse("p/IFoo.aidl",
1158 R"(package p;
1159 interface IFoo {
1160 const int NEGATIVE_HEX_VALUE = 0xffffffff;
1161 }
1162 )",
1163 typenames_, GetLanguage(), &error);
1164 ASSERT_NE(nullptr, parse_result);
1165 const AidlInterface* interface = parse_result->AsInterface();
1166 ASSERT_NE(nullptr, interface);
1167 const auto& cpp_constants = interface->GetConstantDeclarations();
1168 EXPECT_EQ((size_t)1, cpp_constants.size());
1169 EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
1170 EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
1171 EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1172 }
1173
TEST_P(AidlTest,UnderstandsNestedParcelables)1174 TEST_P(AidlTest, UnderstandsNestedParcelables) {
1175 io_delegate_.SetFileContents(
1176 "p/Outer.aidl",
1177 "package p; parcelable Outer.Inner cpp_header \"baz/header\";");
1178 import_paths_.emplace("");
1179 const string input_path = "p/IFoo.aidl";
1180 const string input = "package p; import p.Outer; interface IFoo"
1181 " { Outer.Inner get(); }";
1182
1183 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1184 EXPECT_NE(nullptr, parse_result);
1185
1186 EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1187 // C++ uses "::" instead of "." to refer to a inner class.
1188 AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", false, nullptr, {});
1189 EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1190 }
1191
TEST_P(AidlTest,UnderstandsNativeParcelables)1192 TEST_P(AidlTest, UnderstandsNativeParcelables) {
1193 io_delegate_.SetFileContents(
1194 "p/Bar.aidl",
1195 "package p; parcelable Bar cpp_header \"baz/header\";");
1196 import_paths_.emplace("");
1197 const string input_path = "p/IFoo.aidl";
1198 const string input = "package p; import p.Bar; interface IFoo { }";
1199 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1200 EXPECT_NE(nullptr, parse_result);
1201 EXPECT_TRUE(typenames_.ResolveTypename("p.Bar").is_resolved);
1202 AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, {});
1203 native_type.Resolve(typenames_);
1204
1205 EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type, typenames_));
1206 // C++ understands C++ specific stuff
1207 EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
1208 set<string> headers;
1209 cpp::AddHeaders(native_type, typenames_, &headers);
1210 EXPECT_EQ(1u, headers.size());
1211 EXPECT_EQ(1u, headers.count("baz/header"));
1212 }
1213
TEST_F(AidlTest,WritesCorrectDependencyFile)1214 TEST_F(AidlTest, WritesCorrectDependencyFile) {
1215 // While the in tree build system always gives us an output file name,
1216 // other android tools take advantage of our ability to infer the intended
1217 // file name. This test makes sure we handle this correctly.
1218 vector<string> args = {
1219 "aidl",
1220 "-d dep/file/path",
1221 "-o place/for/output",
1222 "p/IFoo.aidl"};
1223 Options options = Options::From(args);
1224 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
1225 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1226 string actual_dep_file_contents;
1227 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1228 EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
1229 }
1230
TEST_F(AidlTest,WritesCorrectDependencyFileNinja)1231 TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
1232 // While the in tree build system always gives us an output file name,
1233 // other android tools take advantage of our ability to infer the intended
1234 // file name. This test makes sure we handle this correctly.
1235 vector<string> args = {
1236 "aidl",
1237 "-d dep/file/path",
1238 "--ninja",
1239 "-o place/for/output",
1240 "p/IFoo.aidl"};
1241 Options options = Options::From(args);
1242 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
1243 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1244 string actual_dep_file_contents;
1245 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1246 EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
1247 }
1248
TEST_F(AidlTest,WritesTrivialDependencyFileForParcelableDeclaration)1249 TEST_F(AidlTest, WritesTrivialDependencyFileForParcelableDeclaration) {
1250 // The SDK uses aidl to decide whether a .aidl file is a parcelable. It does
1251 // this by calling aidl with every .aidl file it finds, then parsing the
1252 // generated dependency files. Those that reference .java output files are
1253 // for interfaces and those that do not are parcelables. However, for both
1254 // parcelables and interfaces, we *must* generate a non-empty dependency file.
1255 vector<string> args = {
1256 "aidl",
1257 "-o place/for/output",
1258 "-d dep/file/path",
1259 "p/Foo.aidl"};
1260 Options options = Options::From(args);
1261 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
1262 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1263 string actual_dep_file_contents;
1264 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1265 EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDeclarationDepFileContents);
1266 }
1267
TEST_F(AidlTest,WritesDependencyFileForStructuredParcelable)1268 TEST_F(AidlTest, WritesDependencyFileForStructuredParcelable) {
1269 vector<string> args = {
1270 "aidl",
1271 "--structured",
1272 "-o place/for/output",
1273 "-d dep/file/path",
1274 "p/Foo.aidl"};
1275 Options options = Options::From(args);
1276 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo {int a;}");
1277 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1278 string actual_dep_file_contents;
1279 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1280 EXPECT_EQ(actual_dep_file_contents, kExpectedStructuredParcelableDepFileContents);
1281 }
1282
TEST_F(AidlTest,NoJavaOutputForParcelableDeclaration)1283 TEST_F(AidlTest, NoJavaOutputForParcelableDeclaration) {
1284 vector<string> args = {
1285 "aidl",
1286 "--lang=java",
1287 "-o place/for/output",
1288 "p/Foo.aidl"};
1289 Options options = Options::From(args);
1290 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
1291 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1292 string output_file_contents;
1293 EXPECT_FALSE(io_delegate_.GetWrittenContents(options.OutputFile(), &output_file_contents));
1294 }
1295
TEST_P(AidlTest,RejectsListArray)1296 TEST_P(AidlTest, RejectsListArray) {
1297 const string expected_stderr = "ERROR: a/Foo.aidl:2.1-7: List[] is not supported.\n";
1298 const string list_array_parcelable =
1299 "package a; parcelable Foo {\n"
1300 " List[] lists; }";
1301 CaptureStderr();
1302 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", list_array_parcelable, typenames_, GetLanguage()));
1303 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1304 }
1305
TEST_P(AidlTest,RejectsPrimitiveListInStableAidl)1306 TEST_P(AidlTest, RejectsPrimitiveListInStableAidl) {
1307 AidlError error;
1308 string expected_stderr =
1309 "ERROR: a/IFoo.aidl:2.7-11: "
1310 "Encountered an untyped List or Map. The use of untyped List/Map is "
1311 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
1312 "the receiving side. Consider switching to an array or a generic List/Map.\n";
1313 if (GetLanguage() != Options::Language::JAVA) {
1314 expected_stderr =
1315 "ERROR: a/IFoo.aidl:2.1-7: "
1316 "Currently, only the Java backend supports non-generic List.\n";
1317 }
1318
1319 const string primitive_interface =
1320 "package a; interface IFoo {\n"
1321 " List foo(); }";
1322 CaptureStderr();
1323 AidlTypenames tn1;
1324 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_interface, tn1, GetLanguage(), &error,
1325 {"--structured"}));
1326 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1327
1328 string primitive_parcelable =
1329 "package a; parcelable IFoo {\n"
1330 " List foo;}";
1331 CaptureStderr();
1332 AidlTypenames tn2;
1333 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_parcelable, tn2, GetLanguage(), &error,
1334 {"--structured"}));
1335 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1336 }
1337
TEST_P(AidlTest,ExtensionTest)1338 TEST_P(AidlTest, ExtensionTest) {
1339 CaptureStderr();
1340 string extendable_parcelable =
1341 "package a; parcelable Data {\n"
1342 " ParcelableHolder extension;\n"
1343 " ParcelableHolder extension2;\n"
1344 "}";
1345 if (GetLanguage() == Options::Language::RUST) {
1346 EXPECT_EQ(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1347 EXPECT_EQ(
1348 "ERROR: a/Data.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
1349 "yet.\n",
1350 GetCapturedStderr());
1351 } else {
1352 EXPECT_NE(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1353 EXPECT_EQ("", GetCapturedStderr());
1354 }
1355 }
TEST_P(AidlTest,ParcelableHolderAsReturnType)1356 TEST_P(AidlTest, ParcelableHolderAsReturnType) {
1357 CaptureStderr();
1358 string parcelableholder_return_interface =
1359 "package a; interface IFoo {\n"
1360 " ParcelableHolder foo();\n"
1361 "}";
1362 EXPECT_EQ(nullptr,
1363 Parse("a/IFoo.aidl", parcelableholder_return_interface, typenames_, GetLanguage()));
1364
1365 if (GetLanguage() == Options::Language::RUST) {
1366 EXPECT_EQ(
1367 "ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n"
1368 "ERROR: a/IFoo.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
1369 "yet.\n",
1370 GetCapturedStderr());
1371 return;
1372 }
1373 EXPECT_EQ("ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n",
1374 GetCapturedStderr());
1375 }
1376
TEST_P(AidlTest,ParcelableHolderAsArgumentType)1377 TEST_P(AidlTest, ParcelableHolderAsArgumentType) {
1378 CaptureStderr();
1379 string extendable_parcelable_arg_interface =
1380 "package a; interface IFoo {\n"
1381 " void foo(in ParcelableHolder ph);\n"
1382 "}";
1383 EXPECT_EQ(nullptr,
1384 Parse("a/IFoo.aidl", extendable_parcelable_arg_interface, typenames_, GetLanguage()));
1385
1386 if (GetLanguage() == Options::Language::RUST) {
1387 EXPECT_EQ(
1388 "ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n"
1389 "ERROR: a/IFoo.aidl:2.14-31: The Rust backend does not support ParcelableHolder "
1390 "yet.\n",
1391 GetCapturedStderr());
1392 return;
1393 }
1394 EXPECT_EQ("ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n",
1395 GetCapturedStderr());
1396 }
1397
TEST_P(AidlTest,RejectNullableParcelableHolderField)1398 TEST_P(AidlTest, RejectNullableParcelableHolderField) {
1399 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { @nullable ParcelableHolder ext; }");
1400 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
1401 const string expected_stderr = "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n";
1402 CaptureStderr();
1403 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1404 if (GetLanguage() == Options::Language::RUST) {
1405 EXPECT_EQ(
1406 "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n"
1407 "ERROR: Foo.aidl:1.27-44: The Rust backend does not support ParcelableHolder "
1408 "yet.\n",
1409 GetCapturedStderr());
1410 return;
1411 }
1412 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1413 }
1414
TEST_P(AidlTest,ParcelablesWithConstants)1415 TEST_P(AidlTest, ParcelablesWithConstants) {
1416 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { const int BIT = 0x1 << 3; }");
1417 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
1418 CaptureStderr();
1419 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1420 EXPECT_EQ("", GetCapturedStderr());
1421 }
1422
TEST_P(AidlTest,UnionWithConstants)1423 TEST_P(AidlTest, UnionWithConstants) {
1424 io_delegate_.SetFileContents("Foo.aidl", "union Foo { const int BIT = 0x1 << 3; int n; }");
1425 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
1426 CaptureStderr();
1427 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1428 EXPECT_EQ("", GetCapturedStderr());
1429 }
1430
TEST_F(AidlTest,ConstantsWithAnnotations)1431 TEST_F(AidlTest, ConstantsWithAnnotations) {
1432 io_delegate_.SetFileContents("IFoo.aidl",
1433 "interface IFoo {\n"
1434 " @JavaPassthrough(annotation=\"@Foo\")\n"
1435 " const @JavaPassthrough(annotation=\"@Bar\") int FOO = 0;\n"
1436 "}");
1437 Options options = Options::From("aidl IFoo.aidl --lang=java -o out");
1438 CaptureStderr();
1439 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1440 EXPECT_EQ("", GetCapturedStderr());
1441 string code;
1442 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/IFoo.java", &code));
1443 EXPECT_THAT(code, HasSubstr("@Foo\n"));
1444 EXPECT_THAT(code, HasSubstr("@Bar\n"));
1445 }
1446
TEST_F(AidlTest,ApiDump)1447 TEST_F(AidlTest, ApiDump) {
1448 io_delegate_.SetFileContents(
1449 "foo/bar/IFoo.aidl",
1450 "package foo.bar;\n"
1451 "import foo.bar.Data;\n"
1452 "// commented /* @hide */\n"
1453 "interface IFoo {\n"
1454 " /* @hide applied \n"
1455 " @deprecated use foo2 */\n"
1456 " int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
1457 " int foo2(@utf8InCpp String x, inout List<String> y);\n"
1458 " IFoo foo3(IFoo foo);\n"
1459 " Data getData();\n"
1460 " // @hide not applied\n"
1461 " /** blahblah\n"
1462 " @deprecated\n"
1463 " reason why... */\n"
1464 " const int A = 1;\n"
1465 " // @deprecated tags in line comments are ignored\n"
1466 " const String STR = \"Hello\";\n"
1467 "}\n");
1468 io_delegate_.SetFileContents("foo/bar/Data.aidl",
1469 "package foo.bar;\n"
1470 "import foo.bar.IFoo;\n"
1471 "/* @hide*/\n"
1472 "parcelable Data {\n"
1473 " // @hide\n"
1474 " int x = 10;\n"
1475 " // @hide\n"
1476 " int y;\n"
1477 " /*@hide2*/\n"
1478 " IFoo foo;\n"
1479 " // Ignore @hide property in line comment\n"
1480 " @nullable String[] c;\n"
1481 "}\n");
1482 io_delegate_.SetFileContents("api.aidl", "");
1483 vector<string> args = {"aidl", "--dumpapi", "--out=dump", "--include=.",
1484 "foo/bar/IFoo.aidl", "foo/bar/Data.aidl"};
1485 Options options = Options::From(args);
1486 bool result = dump_api(options, io_delegate_);
1487 ASSERT_TRUE(result);
1488 string actual;
1489 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
1490 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1491 interface IFoo {
1492 /**
1493 * @hide
1494 * @deprecated use foo2
1495 */
1496 int foo(out int[] a, String b, boolean c, inout List<String> d);
1497 int foo2(@utf8InCpp String x, inout List<String> y);
1498 foo.bar.IFoo foo3(foo.bar.IFoo foo);
1499 foo.bar.Data getData();
1500 /**
1501 * @deprecated reason why...
1502 */
1503 const int A = 1;
1504 const String STR = "Hello";
1505 }
1506 )"),
1507 actual);
1508
1509 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
1510 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1511 /* @hide */
1512 parcelable Data {
1513 int x = 10;
1514 int y;
1515 foo.bar.IFoo foo;
1516 @nullable String[] c;
1517 }
1518 )"),
1519 actual);
1520 }
1521
TEST_F(AidlTest,ApiDumpWithManualIds)1522 TEST_F(AidlTest, ApiDumpWithManualIds) {
1523 io_delegate_.SetFileContents(
1524 "foo/bar/IFoo.aidl",
1525 "package foo.bar;\n"
1526 "interface IFoo {\n"
1527 " int foo() = 1;\n"
1528 " int bar() = 2;\n"
1529 " int baz() = 10;\n"
1530 "}\n");
1531
1532 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1533 Options options = Options::From(args);
1534 bool result = dump_api(options, io_delegate_);
1535 ASSERT_TRUE(result);
1536 string actual;
1537 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
1538 EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
1539 interface IFoo {
1540 int foo() = 1;
1541 int bar() = 2;
1542 int baz() = 10;
1543 }
1544 )"));
1545 }
1546
TEST_F(AidlTest,ApiDumpWithManualIdsOnlyOnSomeMethods)1547 TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
1548 const string expected_stderr =
1549 "ERROR: foo/bar/IFoo.aidl:4.8-12: You must either assign id's to all methods or to none of "
1550 "them.\n";
1551 io_delegate_.SetFileContents(
1552 "foo/bar/IFoo.aidl",
1553 "package foo.bar;\n"
1554 "interface IFoo {\n"
1555 " int foo() = 1;\n"
1556 " int bar();\n"
1557 " int baz() = 10;\n"
1558 "}\n");
1559
1560 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1561 Options options = Options::From(args);
1562 CaptureStderr();
1563 EXPECT_FALSE(dump_api(options, io_delegate_));
1564 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1565 }
1566
TEST_F(AidlTest,ApiDumpConstWithAnnotation)1567 TEST_F(AidlTest, ApiDumpConstWithAnnotation) {
1568 io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
1569 "package foo.bar;\n"
1570 "interface IFoo {\n"
1571 " @utf8InCpp String foo();\n"
1572 " const @utf8InCpp String bar = \"bar\";\n"
1573 "}\n");
1574
1575 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1576 Options options = Options::From(args);
1577 CaptureStderr();
1578 EXPECT_TRUE(dump_api(options, io_delegate_));
1579 EXPECT_EQ("", GetCapturedStderr());
1580 string actual;
1581 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
1582 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1583 interface IFoo {
1584 @utf8InCpp String foo();
1585 const @utf8InCpp String bar = "bar";
1586 }
1587 )"),
1588 actual);
1589 }
1590
TEST_F(AidlTest,ApiDumpWithEnums)1591 TEST_F(AidlTest, ApiDumpWithEnums) {
1592 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1593 "package foo.bar;\n"
1594 "enum Enum {\n"
1595 " FOO,\n"
1596 " BAR = FOO + 1,\n"
1597 "}\n");
1598
1599 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Enum.aidl"};
1600 Options options = Options::From(args);
1601 CaptureStderr();
1602 EXPECT_TRUE(dump_api(options, io_delegate_));
1603 EXPECT_EQ("", GetCapturedStderr());
1604 string actual;
1605 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
1606 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1607 "enum Enum {\n"
1608 " FOO = 0,\n"
1609 " BAR = 1,\n"
1610 "}\n"),
1611 actual);
1612 }
1613
TEST_F(AidlTest,ApiDumpWithEnumDefaultValues)1614 TEST_F(AidlTest, ApiDumpWithEnumDefaultValues) {
1615 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1616 "package foo.bar;\n"
1617 "enum Enum {\n"
1618 " FOO,\n"
1619 "}\n");
1620 io_delegate_.SetFileContents("foo/bar/Foo.aidl",
1621 "package foo.bar;\n"
1622 "import foo.bar.Enum;\n"
1623 "parcelable Foo {\n"
1624 " Enum e = Enum.FOO;\n"
1625 "}\n");
1626
1627 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
1628 Options options = Options::From(args);
1629 CaptureStderr();
1630 EXPECT_TRUE(dump_api(options, io_delegate_));
1631 EXPECT_EQ("", GetCapturedStderr());
1632 string actual;
1633 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
1634 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1635 "parcelable Foo {\n"
1636 " foo.bar.Enum e = foo.bar.Enum.FOO;\n"
1637 "}\n"),
1638 actual);
1639 }
1640
TEST_F(AidlTest,ApiDumpWithGenerics)1641 TEST_F(AidlTest, ApiDumpWithGenerics) {
1642 io_delegate_.SetFileContents("foo/bar/Foo.aidl",
1643 "package foo.bar;\n"
1644 "parcelable Foo<T, U> {\n"
1645 "}\n");
1646
1647 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
1648 Options options = Options::From(args);
1649 CaptureStderr();
1650 EXPECT_TRUE(dump_api(options, io_delegate_));
1651 EXPECT_EQ("", GetCapturedStderr());
1652 string actual;
1653 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
1654 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1655 "parcelable Foo<T, U> {\n"
1656 "}\n"),
1657 actual);
1658 }
1659
TEST_F(AidlTest,CheckNumGenericTypeSecifier)1660 TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
1661 const string expected_list_stderr =
1662 "ERROR: p/IFoo.aidl:1.37-41: List can only have one type parameter, but got: "
1663 "'List<String,String>'\n";
1664 const string expected_map_stderr =
1665 "ERROR: p/IFoo.aidl:1.37-40: Map must have 0 or 2 type parameters, but got 'Map<String>'\n";
1666 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1667 io_delegate_.SetFileContents(options.InputFiles().front(),
1668 "package p; interface IFoo {"
1669 "void foo(List<String, String> a);}");
1670 CaptureStderr();
1671 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1672 EXPECT_EQ(expected_list_stderr, GetCapturedStderr());
1673
1674 io_delegate_.SetFileContents(options.InputFiles().front(),
1675 "package p; interface IFoo {"
1676 "void foo(Map<String> a);}");
1677 CaptureStderr();
1678 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1679 EXPECT_EQ(expected_map_stderr, GetCapturedStderr());
1680 }
1681
TEST_F(AidlTest,CheckTypeParameterInMapType)1682 TEST_F(AidlTest, CheckTypeParameterInMapType) {
1683 const string expected_stderr =
1684 "ERROR: p/IFoo.aidl:1.28-31: The type of key in map must be String, but it is 'p.Bar'\n";
1685 Options options = Options::From("aidl -I p p/IFoo.aidl");
1686 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar { String s; }");
1687
1688 io_delegate_.SetFileContents("p/IFoo.aidl",
1689 "package p; interface IFoo {"
1690 "Map<String, Bar> foo();}");
1691 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1692
1693 io_delegate_.SetFileContents("p/IFoo.aidl",
1694 "package p; interface IFoo {"
1695 "Map<Bar, Bar> foo();}");
1696 CaptureStderr();
1697 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1698 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1699
1700 io_delegate_.SetFileContents("p/IFoo.aidl",
1701 "package p; interface IFoo {"
1702 "Map<String, String> foo();}");
1703 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1704
1705 io_delegate_.SetFileContents("p/IFoo.aidl",
1706 "package p; interface IFoo {"
1707 "Map<String, ParcelFileDescriptor> foo();}");
1708 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1709 }
1710
TEST_F(AidlTest,WrongGenericType)1711 TEST_F(AidlTest, WrongGenericType) {
1712 const string expected_stderr = "ERROR: p/IFoo.aidl:1.28-34: String is not a generic type.\n";
1713 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1714 io_delegate_.SetFileContents(options.InputFiles().front(),
1715 "package p; interface IFoo {"
1716 "String<String> foo(); }");
1717 CaptureStderr();
1718 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1719 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1720 }
1721
TEST_F(AidlTest,UserDefinedUnstructuredGenericParcelableType)1722 TEST_F(AidlTest, UserDefinedUnstructuredGenericParcelableType) {
1723 Options optionsForParcelable = Options::From("aidl -I p p/Bar.aidl");
1724 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, T>;");
1725 CaptureStderr();
1726 EXPECT_NE(0, ::android::aidl::compile_aidl(optionsForParcelable, io_delegate_));
1727 EXPECT_EQ("ERROR: p/Bar.aidl:1.22-26: Every type parameter should be unique.\n",
1728 GetCapturedStderr());
1729
1730 Options options = Options::From("aidl -I p p/IFoo.aidl");
1731 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar;");
1732 io_delegate_.SetFileContents("p/IFoo.aidl",
1733 "package p; interface IFoo {"
1734 "Bar<String, String> foo();}");
1735 CaptureStderr();
1736 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1737 EXPECT_EQ("ERROR: p/IFoo.aidl:1.28-31: p.Bar is not a generic type.\n", GetCapturedStderr());
1738 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T>;");
1739 CaptureStderr();
1740 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1741 EXPECT_EQ("ERROR: p/IFoo.aidl:1.28-31: p.Bar must have 1 type parameters, but got 2\n",
1742 GetCapturedStderr());
1743 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, V>;");
1744 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1745 io_delegate_.SetFileContents("p/IFoo.aidl",
1746 "package p; interface IFoo {"
1747 "Bar<String, ParcelFileDescriptor> foo();}");
1748 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1749
1750 io_delegate_.SetFileContents("p/IFoo.aidl",
1751 "package p; interface IFoo {"
1752 "Bar<int, long> foo();}");
1753
1754 io_delegate_.SetFileContents("p/IFoo.aidl",
1755 "package p; interface IFoo {"
1756 "Bar<int[], long[]> foo();}");
1757
1758 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1759 }
1760
TEST_F(AidlTest,FailOnMultipleTypesInSingleFile)1761 TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
1762 std::vector<std::string> rawOptions{"aidl --lang=java -o out foo/bar/Foo.aidl",
1763 "aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl",
1764 "aidl --lang=rust -o out foo/bar/Foo.aidl"};
1765 for (const auto& rawOption : rawOptions) {
1766 string expected_stderr =
1767 "ERROR: foo/bar/Foo.aidl:3.1-10: You must declare only one type per file.\n";
1768 Options options = Options::From(rawOption);
1769 io_delegate_.SetFileContents(options.InputFiles().front(),
1770 "package foo.bar;\n"
1771 "interface IFoo1 { int foo(); }\n"
1772 "interface IFoo2 { int foo(); }\n"
1773 "parcelable Data1 { int a; int b;}\n"
1774 "parcelable Data2 { int a; int b;}\n");
1775 CaptureStderr();
1776 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1777 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1778
1779 io_delegate_.SetFileContents(options.InputFiles().front(),
1780 "package foo.bar;\n"
1781 "interface IFoo1 { int foo(); }\n"
1782 "interface IFoo2 { int foo(); }\n");
1783 CaptureStderr();
1784 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1785 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1786
1787 expected_stderr = "ERROR: foo/bar/Foo.aidl:3.11-17: You must declare only one type per file.\n";
1788 io_delegate_.SetFileContents(options.InputFiles().front(),
1789 "package foo.bar;\n"
1790 "parcelable Data1 { int a; int b;}\n"
1791 "parcelable Data2 { int a; int b;}\n");
1792 CaptureStderr();
1793 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1794 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1795 }
1796 }
1797
TEST_P(AidlTest,FailParseOnEmptyFile)1798 TEST_P(AidlTest, FailParseOnEmptyFile) {
1799 const string contents = "";
1800 const string expected_stderr = "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected $end\n";
1801 CaptureStderr();
1802 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", contents, typenames_, GetLanguage()));
1803 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1804 }
1805
TEST_F(AidlTest,MultipleInputFiles)1806 TEST_F(AidlTest, MultipleInputFiles) {
1807 Options options = Options::From(
1808 "aidl --lang=java -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
1809
1810 io_delegate_.SetFileContents(options.InputFiles().at(0),
1811 "package foo.bar;\n"
1812 "import foo.bar.Data;\n"
1813 "interface IFoo { Data getData(); }\n");
1814
1815 io_delegate_.SetFileContents(options.InputFiles().at(1),
1816 "package foo.bar;\n"
1817 "import foo.bar.IFoo;\n"
1818 "parcelable Data { IFoo foo; }\n");
1819
1820 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1821
1822 string content;
1823 for (const auto file : {
1824 "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
1825 content.clear();
1826 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1827 EXPECT_FALSE(content.empty());
1828 }
1829 }
1830
TEST_F(AidlTest,MultipleInputFilesCpp)1831 TEST_F(AidlTest, MultipleInputFilesCpp) {
1832 Options options = Options::From("aidl --lang=cpp -o out -h out/include "
1833 "-I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
1834
1835 io_delegate_.SetFileContents(options.InputFiles().at(0),
1836 "package foo.bar;\n"
1837 "import foo.bar.Data;\n"
1838 "interface IFoo { Data getData(); }\n");
1839
1840 io_delegate_.SetFileContents(options.InputFiles().at(1),
1841 "package foo.bar;\n"
1842 "import foo.bar.IFoo;\n"
1843 "parcelable Data { IFoo foo; }\n");
1844
1845 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1846
1847 string content;
1848 for (const auto file : {
1849 "out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp",
1850 "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
1851 "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
1852 "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
1853 content.clear();
1854 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1855 EXPECT_FALSE(content.empty());
1856 }
1857 }
1858
TEST_F(AidlTest,MultipleInputFilesRust)1859 TEST_F(AidlTest, MultipleInputFilesRust) {
1860 Options options =
1861 Options::From("aidl --lang=rust -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
1862
1863 io_delegate_.SetFileContents(options.InputFiles().at(0),
1864 "package foo.bar;\n"
1865 "import foo.bar.Data;\n"
1866 "interface IFoo { Data getData(); }\n");
1867
1868 io_delegate_.SetFileContents(options.InputFiles().at(1),
1869 "package foo.bar;\n"
1870 "import foo.bar.IFoo;\n"
1871 "parcelable Data { IFoo foo; }\n");
1872
1873 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1874
1875 string content;
1876 for (const auto file : {"out/foo/bar/IFoo.rs", "out/foo/bar/Data.rs"}) {
1877 content.clear();
1878 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1879 EXPECT_FALSE(content.empty());
1880 }
1881 }
1882
TEST_F(AidlTest,ConflictWithMetaTransactionGetVersion)1883 TEST_F(AidlTest, ConflictWithMetaTransactionGetVersion) {
1884 const string expected_stderr =
1885 "ERROR: p/IFoo.aidl:1.31-51: method getInterfaceVersion() is reserved for internal use.\n";
1886 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
1887 // int getInterfaceVersion() is one of the meta transactions
1888 io_delegate_.SetFileContents(options.InputFiles().front(),
1889 "package p; interface IFoo {"
1890 "int getInterfaceVersion(); }");
1891 CaptureStderr();
1892 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1893 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1894 }
1895
TEST_F(AidlTest,ConflictWithSimilarMetaTransaction)1896 TEST_F(AidlTest, ConflictWithSimilarMetaTransaction) {
1897 // boolean getInterfaceVersion() is not a meta transaction, but should be
1898 // prevented because return type is not part of a method signature
1899 const string expected_stderr =
1900 "ERROR: p/IFoo.aidl:1.35-55: method getInterfaceVersion() is reserved for internal use.\n";
1901 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
1902 io_delegate_.SetFileContents(options.InputFiles().front(),
1903 "package p; interface IFoo {"
1904 "boolean getInterfaceVersion(); }");
1905 CaptureStderr();
1906 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1907 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1908 }
1909
TEST_F(AidlTest,ConflictWithMetaTransactionGetName)1910 TEST_F(AidlTest, ConflictWithMetaTransactionGetName) {
1911 // this is another reserved name
1912 const string expected_stderr =
1913 "ERROR: p/IFoo.aidl:1.34-53: method getTransactionName(int) is reserved for internal use.\n";
1914 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
1915 io_delegate_.SetFileContents(options.InputFiles().front(),
1916 "package p; interface IFoo {"
1917 "String getTransactionName(int code); }");
1918 CaptureStderr();
1919 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1920 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1921
1922 // this is not a meta interface method as it differs type arguments
1923 io_delegate_.SetFileContents(options.InputFiles().front(),
1924 "package p; interface IFoo {"
1925 "String getTransactionName(); }");
1926 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1927 }
1928
TEST_F(AidlTest,CheckApiForEquality)1929 TEST_F(AidlTest, CheckApiForEquality) {
1930 CaptureStderr();
1931 Options options = Options::From("aidl --checkapi=equal old new");
1932
1933 io_delegate_.SetFileContents("old/p/IFoo.aidl",
1934 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
1935 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1936 "package p; interface IFoo{ @utf8InCpp String foo();}");
1937
1938 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1939 EXPECT_THAT(GetCapturedStderr(), HasSubstr("+ @utf8InCpp String foo();"));
1940 }
1941
TEST_F(AidlTest,DifferentOrderAnnotationsInCheckAPI)1942 TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
1943 Options options = Options::From("aidl --checkapi old new");
1944 io_delegate_.SetFileContents("old/p/IFoo.aidl",
1945 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
1946 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1947 "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
1948
1949 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1950 }
1951
TEST_F(AidlTest,SuccessOnIdenticalApiDumps)1952 TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
1953 Options options = Options::From("aidl --checkapi old new");
1954 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
1955 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
1956
1957 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1958 }
1959
TEST_F(AidlTest,CheckApi_EnumFieldsWithDefaultValues)1960 TEST_F(AidlTest, CheckApi_EnumFieldsWithDefaultValues) {
1961 Options options = Options::From("aidl --checkapi old new");
1962 const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
1963 const string enum_definition = "package p; enum Enum { FOO }";
1964 io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
1965 io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
1966 io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
1967 io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
1968
1969 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1970 }
1971
TEST_F(AidlTest,CheckApiEqual_EnumFieldsWithDefaultValues)1972 TEST_F(AidlTest, CheckApiEqual_EnumFieldsWithDefaultValues) {
1973 Options options = Options::From("aidl --checkapi=equal old new");
1974 const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
1975 const string enum_definition = "package p; enum Enum { FOO }";
1976 io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
1977 io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
1978 io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
1979 io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
1980 CaptureStderr();
1981 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1982 EXPECT_EQ("", GetCapturedStderr());
1983 }
1984
1985 class AidlTestCompatibleChanges : public AidlTest {
1986 protected:
1987 Options options_ = Options::From("aidl --checkapi old new");
1988 };
1989
TEST_F(AidlTestCompatibleChanges,NewType)1990 TEST_F(AidlTestCompatibleChanges, NewType) {
1991 io_delegate_.SetFileContents("old/p/IFoo.aidl",
1992 "package p;"
1993 "interface IFoo {"
1994 " void foo(int a);"
1995 "}");
1996 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1997 "package p;"
1998 "interface IFoo {"
1999 " void foo(int a);"
2000 "}");
2001 io_delegate_.SetFileContents("new/p/IBar.aidl",
2002 "package p;"
2003 "interface IBar {"
2004 " void bar();"
2005 "}");
2006 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2007 }
2008
TEST_F(AidlTestCompatibleChanges,NewMethod)2009 TEST_F(AidlTestCompatibleChanges, NewMethod) {
2010 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2011 "package p;"
2012 "interface IFoo {"
2013 " void foo(int a);"
2014 "}");
2015 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2016 "package p;"
2017 "interface IFoo {"
2018 " void foo(int a);"
2019 " void bar();"
2020 " void baz(in List<IFoo> arg);"
2021 "}");
2022 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2023 }
2024
TEST_F(AidlTestCompatibleChanges,NewField)2025 TEST_F(AidlTestCompatibleChanges, NewField) {
2026 io_delegate_.SetFileContents("old/p/Data.aidl",
2027 "package p;"
2028 "parcelable Data {"
2029 " int foo;"
2030 "}");
2031 io_delegate_.SetFileContents("new/p/Data.aidl",
2032 "package p;"
2033 "parcelable Data {"
2034 " int foo;"
2035 " int bar = 0;"
2036 " @nullable List<Data> list;"
2037 "}");
2038 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2039 }
2040
TEST_F(AidlTestCompatibleChanges,NewField2)2041 TEST_F(AidlTestCompatibleChanges, NewField2) {
2042 io_delegate_.SetFileContents("old/p/Data.aidl",
2043 "package p;"
2044 "parcelable Data {"
2045 "}");
2046 io_delegate_.SetFileContents("new/p/Data.aidl",
2047 "package p;"
2048 "parcelable Data {"
2049 " int foo = 0;"
2050 "}");
2051 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2052 }
2053
TEST_F(AidlTestCompatibleChanges,NewEnumerator)2054 TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
2055 io_delegate_.SetFileContents("old/p/Enum.aidl",
2056 "package p;"
2057 "enum Enum {"
2058 " FOO = 1,"
2059 "}");
2060 io_delegate_.SetFileContents("new/p/Enum.aidl",
2061 "package p;"
2062 "enum Enum {"
2063 " FOO = 1,"
2064 " BAR = 2,"
2065 "}");
2066 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2067 }
2068
TEST_F(AidlTestCompatibleChanges,ReorderedEnumerator)2069 TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
2070 io_delegate_.SetFileContents("old/p/Enum.aidl",
2071 "package p;"
2072 "enum Enum {"
2073 " FOO = 1,"
2074 " BAR = 2,"
2075 "}");
2076 io_delegate_.SetFileContents("new/p/Enum.aidl",
2077 "package p;"
2078 "enum Enum {"
2079 " BAR = 2,"
2080 " FOO = 1,"
2081 "}");
2082 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2083 }
2084
TEST_F(AidlTestCompatibleChanges,NewUnionField)2085 TEST_F(AidlTestCompatibleChanges, NewUnionField) {
2086 io_delegate_.SetFileContents("old/p/Union.aidl",
2087 "package p;"
2088 "union Union {"
2089 " String foo;"
2090 "}");
2091 io_delegate_.SetFileContents("new/p/Union.aidl",
2092 "package p;"
2093 "union Union {"
2094 " String foo;"
2095 " int num;"
2096 "}");
2097 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2098 }
2099
TEST_F(AidlTestCompatibleChanges,NewPackage)2100 TEST_F(AidlTestCompatibleChanges, NewPackage) {
2101 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2102 "package p;"
2103 "interface IFoo {"
2104 " void foo(int a);"
2105 "}");
2106 io_delegate_.SetFileContents("old/p/Data.aidl",
2107 "package p;"
2108 "parcelable Data {"
2109 " int foo;"
2110 "}");
2111 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2112 "package p;"
2113 "interface IFoo {"
2114 " void foo(int a);"
2115 "}");
2116 io_delegate_.SetFileContents("new/p/Data.aidl",
2117 "package p;"
2118 "parcelable Data {"
2119 " int foo;"
2120 "}");
2121 io_delegate_.SetFileContents("new/q/IFoo.aidl",
2122 "package q;"
2123 "interface IFoo {"
2124 " void foo(int a);"
2125 "}");
2126 io_delegate_.SetFileContents("new/q/Data.aidl",
2127 "package q;"
2128 "parcelable Data {"
2129 " int foo;"
2130 "}");
2131 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2132 }
2133
TEST_F(AidlTestCompatibleChanges,ArgNameChange)2134 TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
2135 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2136 "package p;"
2137 "interface IFoo {"
2138 " void foo(int a);"
2139 "}");
2140 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2141 "package p;"
2142 "interface IFoo {"
2143 " void foo(int b);"
2144 "}");
2145 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2146 }
2147
TEST_F(AidlTestCompatibleChanges,AddedConstValue)2148 TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
2149 io_delegate_.SetFileContents("old/p/I.aidl",
2150 "package p; interface I {"
2151 "const int A = 1; }");
2152 io_delegate_.SetFileContents("new/p/I.aidl",
2153 "package p ; interface I {"
2154 "const int A = 1; const int B = 2;}");
2155 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2156 }
2157
TEST_F(AidlTestCompatibleChanges,ChangedConstValueOrder)2158 TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
2159 io_delegate_.SetFileContents("old/p/I.aidl",
2160 "package p; interface I {"
2161 "const int A = 1; const int B = 2;}");
2162 io_delegate_.SetFileContents("new/p/I.aidl",
2163 "package p ; interface I {"
2164 "const int B = 2; const int A = 1;}");
2165 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2166 }
2167
TEST_F(AidlTestCompatibleChanges,ReorderedAnnatations)2168 TEST_F(AidlTestCompatibleChanges, ReorderedAnnatations) {
2169 io_delegate_.SetFileContents("old/p/Foo.aidl",
2170 "package p;"
2171 "@JavaPassthrough(annotation=\"Alice\")"
2172 "@JavaPassthrough(annotation=\"Bob\")"
2173 "parcelable Foo {}");
2174 io_delegate_.SetFileContents("new/p/Foo.aidl",
2175 "package p;"
2176 "@JavaPassthrough(annotation=\"Bob\")"
2177 "@JavaPassthrough(annotation=\"Alice\")"
2178 "parcelable Foo {}");
2179 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2180 }
2181
TEST_F(AidlTestCompatibleChanges,OkayToDeprecate)2182 TEST_F(AidlTestCompatibleChanges, OkayToDeprecate) {
2183 io_delegate_.SetFileContents("old/p/Foo.aidl",
2184 "package p;"
2185 "parcelable Foo {}");
2186 io_delegate_.SetFileContents("new/p/Foo.aidl",
2187 "package p;"
2188 "@JavaPassthrough(annotation=\"@Deprecated\")"
2189 "parcelable Foo {}");
2190 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2191 }
2192
TEST_F(AidlTestCompatibleChanges,NewFieldOfNewType)2193 TEST_F(AidlTestCompatibleChanges, NewFieldOfNewType) {
2194 io_delegate_.SetFileContents("old/p/Data.aidl",
2195 "package p;"
2196 "parcelable Data {"
2197 " int num;"
2198 "}");
2199 io_delegate_.SetFileContents(
2200 "new/p/Data.aidl",
2201 "package p;"
2202 "parcelable Data {"
2203 " int num;"
2204 " p.Enum e;" // this is considered as valid since 0(enum default) is valid for "Enum" type
2205 "}");
2206 io_delegate_.SetFileContents("new/p/Enum.aidl",
2207 "package p;"
2208 "enum Enum {"
2209 " FOO = 0,"
2210 " BAR = 1,"
2211 "}");
2212 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2213 }
2214
TEST_F(AidlTestCompatibleChanges,CompatibleExplicitDefaults)2215 TEST_F(AidlTestCompatibleChanges, CompatibleExplicitDefaults) {
2216 io_delegate_.SetFileContents("old/p/Data.aidl",
2217 "package p;\n"
2218 "parcelable Data {\n"
2219 " p.Enum e;\n"
2220 "}");
2221 io_delegate_.SetFileContents("old/p/Enum.aidl",
2222 "package p;\n"
2223 "enum Enum {\n"
2224 " FOO = 0,\n"
2225 " BAR = 1,\n"
2226 "}");
2227 io_delegate_.SetFileContents("new/p/Data.aidl",
2228 "package p;\n"
2229 "parcelable Data {\n"
2230 " p.Enum e = p.Enum.FOO;\n"
2231 "}");
2232 io_delegate_.SetFileContents("new/p/Enum.aidl",
2233 "package p;\n"
2234 "enum Enum {\n"
2235 " FOO = 0,\n"
2236 " BAR = 1,\n"
2237 "}");
2238 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2239 }
2240
2241 class AidlTestIncompatibleChanges : public AidlTest {
2242 protected:
2243 Options options_ = Options::From("aidl --checkapi old new");
2244 };
2245
TEST_F(AidlTestIncompatibleChanges,RemovedType)2246 TEST_F(AidlTestIncompatibleChanges, RemovedType) {
2247 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
2248 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2249 "package p;"
2250 "interface IFoo {"
2251 " void foo(in String[] str);"
2252 " void bar(@utf8InCpp String str);"
2253 "}");
2254 CaptureStderr();
2255 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2256 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2257 }
2258
TEST_F(AidlTestIncompatibleChanges,RemovedMethod)2259 TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
2260 const string expected_stderr =
2261 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
2262 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2263 "package p;"
2264 "interface IFoo {"
2265 " void foo(in String[] str);"
2266 " void bar(@utf8InCpp String str);"
2267 "}");
2268 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2269 "package p;"
2270 "interface IFoo {"
2271 " void foo(in String[] str);"
2272 "}");
2273 CaptureStderr();
2274 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2275 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2276 }
2277
TEST_F(AidlTestIncompatibleChanges,UntypedListInInterface)2278 TEST_F(AidlTestIncompatibleChanges, UntypedListInInterface) {
2279 const string expected_stderr =
2280 "ERROR: new/p/IFoo.aidl:1.61-65: "
2281 "Encountered an untyped List or Map. The use of untyped List/Map is "
2282 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2283 "the receiving side. Consider switching to an array or a generic List/Map.\n"
2284 "ERROR: new/p/IFoo.aidl: Failed to read.\n";
2285 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2286 "package p;"
2287 "interface IFoo {"
2288 " void foo(in String[] str);"
2289 "}");
2290 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2291 "package p;"
2292 "interface IFoo {"
2293 " void foo(in String[] str);"
2294 " void bar(in List arg);"
2295 "}");
2296 CaptureStderr();
2297 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2298 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2299 }
2300
TEST_F(AidlTestCompatibleChanges,UntypedListInParcelable)2301 TEST_F(AidlTestCompatibleChanges, UntypedListInParcelable) {
2302 const string expected_stderr =
2303 "ERROR: new/p/Data.aidl:1.54-59: "
2304 "Encountered an untyped List or Map. The use of untyped List/Map is "
2305 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2306 "the receiving side. Consider switching to an array or a generic List/Map.\n"
2307 "ERROR: new/p/Data.aidl: Failed to read.\n";
2308 io_delegate_.SetFileContents("old/p/Data.aidl",
2309 "package p;"
2310 "parcelable Data {"
2311 " int foo;"
2312 "}");
2313 io_delegate_.SetFileContents("new/p/Data.aidl",
2314 "package p;"
2315 "parcelable Data {"
2316 " int foo;"
2317 " @nullable List list;"
2318 "}");
2319 CaptureStderr();
2320 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2321 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2322 }
2323
TEST_F(AidlTestIncompatibleChanges,RemovedField)2324 TEST_F(AidlTestIncompatibleChanges, RemovedField) {
2325 const string expected_stderr =
2326 "ERROR: new/p/Data.aidl:1.21-26: Number of fields in p.Data is reduced from 2 to 1.\n";
2327 io_delegate_.SetFileContents("old/p/Data.aidl",
2328 "package p;"
2329 "parcelable Data {"
2330 " int foo;"
2331 " int bar;"
2332 "}");
2333 io_delegate_.SetFileContents("new/p/Data.aidl",
2334 "package p;"
2335 "parcelable Data {"
2336 " int foo;"
2337 "}");
2338 CaptureStderr();
2339 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2340 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2341 }
2342
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNoDefault)2343 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNoDefault) {
2344 const string expected_stderr =
2345 "ERROR: new/p/Data.aidl:1.46-50: Field 'str' does not have a useful default in some "
2346 "backends. Please either provide a default value for this field or mark the field as "
2347 "@nullable. This value or a null value will be used automatically when an old version of "
2348 "this parcelable is sent to a process which understands a new version of this parcelable. In "
2349 "order to make sure your code continues to be backwards compatible, make sure the default or "
2350 "null value does not cause a semantic change to this parcelable.\n";
2351 io_delegate_.SetFileContents("old/p/Data.aidl",
2352 "package p;"
2353 "parcelable Data {"
2354 " int num;"
2355 "}");
2356 io_delegate_.SetFileContents("new/p/Data.aidl",
2357 "package p;"
2358 "parcelable Data {"
2359 " int num;"
2360 " String str;"
2361 "}");
2362 CaptureStderr();
2363 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2364 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2365 }
2366
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNonZeroEnum)2367 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNonZeroEnum) {
2368 const string expected_stderr =
2369 "ERROR: new/p/Data.aidl:1.46-48: Field 'e' of enum 'Enum' can't be initialized as '0'. "
2370 "Please make sure 'Enum' has '0' as a valid value.\n";
2371 io_delegate_.SetFileContents("old/p/Data.aidl",
2372 "package p;"
2373 "parcelable Data {"
2374 " int num;"
2375 "}");
2376 io_delegate_.SetFileContents("new/p/Data.aidl",
2377 "package p;"
2378 "parcelable Data {"
2379 " int num;"
2380 " p.Enum e;"
2381 "}");
2382 io_delegate_.SetFileContents("new/p/Enum.aidl",
2383 "package p;"
2384 "enum Enum {"
2385 " FOO = 1,"
2386 " BAR = 2,"
2387 "}");
2388 CaptureStderr();
2389 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2390 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2391 }
2392
TEST_F(AidlTestIncompatibleChanges,RemovedEnumerator)2393 TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
2394 const string expected_stderr =
2395 "ERROR: new/p/Enum.aidl:1.15-20: Removed enumerator from p.Enum: FOO\n";
2396 io_delegate_.SetFileContents("old/p/Enum.aidl",
2397 "package p;"
2398 "enum Enum {"
2399 " FOO = 1,"
2400 " BAR = 2,"
2401 "}");
2402 io_delegate_.SetFileContents("new/p/Enum.aidl",
2403 "package p;"
2404 "enum Enum {"
2405 " BAR = 2,"
2406 "}");
2407 CaptureStderr();
2408 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2409 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2410 }
2411
TEST_F(AidlTestIncompatibleChanges,RemovedUnionField)2412 TEST_F(AidlTestIncompatibleChanges, RemovedUnionField) {
2413 const string expected_stderr =
2414 "ERROR: new/p/Union.aidl:1.16-22: Number of fields in p.Union is reduced from 2 to 1.\n";
2415 io_delegate_.SetFileContents("old/p/Union.aidl",
2416 "package p;"
2417 "union Union {"
2418 " String str;"
2419 " int num;"
2420 "}");
2421 io_delegate_.SetFileContents("new/p/Union.aidl",
2422 "package p;"
2423 "union Union {"
2424 " String str;"
2425 "}");
2426 CaptureStderr();
2427 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2428 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2429 }
2430
TEST_F(AidlTestIncompatibleChanges,RenamedMethod)2431 TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
2432 const string expected_stderr =
2433 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
2434 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2435 "package p;"
2436 "interface IFoo {"
2437 " void foo(in String[] str);"
2438 " void bar(@utf8InCpp String str);"
2439 "}");
2440 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2441 "package p;"
2442 "interface IFoo {"
2443 " void foo(in String[] str);"
2444 " void bar2(@utf8InCpp String str);"
2445 "}");
2446 CaptureStderr();
2447 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2448 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2449 }
2450
TEST_F(AidlTestIncompatibleChanges,RenamedType)2451 TEST_F(AidlTestIncompatibleChanges, RenamedType) {
2452 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
2453 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2454 "package p;"
2455 "interface IFoo {"
2456 " void foo(in String[] str);"
2457 " void bar(@utf8InCpp String str);"
2458 "}");
2459 io_delegate_.SetFileContents("new/p/IFoo2.aidl",
2460 "package p;"
2461 "interface IFoo2 {"
2462 " void foo(in String[] str);"
2463 " void bar(@utf8InCpp String str);"
2464 "}");
2465 CaptureStderr();
2466 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2467 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2468 }
2469
TEST_F(AidlTestIncompatibleChanges,ChangedEnumerator)2470 TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
2471 const string expected_stderr =
2472 "ERROR: new/p/Enum.aidl:1.15-20: Changed enumerator value: p.Enum::FOO from 1 to 3.\n";
2473 io_delegate_.SetFileContents("old/p/Enum.aidl",
2474 "package p;"
2475 "enum Enum {"
2476 " FOO = 1,"
2477 " BAR = 2,"
2478 "}");
2479 io_delegate_.SetFileContents("new/p/Enum.aidl",
2480 "package p;"
2481 "enum Enum {"
2482 " FOO = 3,"
2483 " BAR = 2,"
2484 "}");
2485 CaptureStderr();
2486 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2487 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2488 }
2489
TEST_F(AidlTestIncompatibleChanges,ReorderedMethod)2490 TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
2491 const string expected_stderr =
2492 "ERROR: new/p/IFoo.aidl:1.67-71: Transaction ID changed: p.IFoo.foo(String[]) is changed "
2493 "from 0 to 1.\n"
2494 "ERROR: new/p/IFoo.aidl:1.33-37: Transaction ID changed: p.IFoo.bar(String) is changed from "
2495 "1 to 0.\n";
2496 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2497 "package p;"
2498 "interface IFoo {"
2499 " void foo(in String[] str);"
2500 " void bar(@utf8InCpp String str);"
2501 "}");
2502 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2503 "package p;"
2504 "interface IFoo {"
2505 " void bar(@utf8InCpp String str);"
2506 " void foo(in String[] str);"
2507 "}");
2508 CaptureStderr();
2509 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2510 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2511 }
2512
TEST_F(AidlTestIncompatibleChanges,ReorderedField)2513 TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
2514 const string expected_stderr =
2515 "ERROR: new/p/Data.aidl:1.33-37: Reordered bar from 1 to 0.\n"
2516 "ERROR: new/p/Data.aidl:1.43-47: Reordered foo from 0 to 1.\n";
2517 io_delegate_.SetFileContents("old/p/Data.aidl",
2518 "package p;"
2519 "parcelable Data {"
2520 " int foo;"
2521 " int bar;"
2522 "}");
2523 io_delegate_.SetFileContents("new/p/Data.aidl",
2524 "package p;"
2525 "parcelable Data {"
2526 " int bar;"
2527 " int foo;"
2528 "}");
2529 CaptureStderr();
2530 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2531 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2532 }
2533
TEST_F(AidlTestIncompatibleChanges,ChangedDirectionSpecifier)2534 TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
2535 const string expected_stderr = "ERROR: new/p/IFoo.aidl:1.33-37: Direction changed: in to out.\n";
2536 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2537 "package p;"
2538 "interface IFoo {"
2539 " void foo(in String[] str);"
2540 " void bar(@utf8InCpp String str);"
2541 "}");
2542 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2543 "package p;"
2544 "interface IFoo {"
2545 " void foo(out String[] str);"
2546 " void bar(@utf8InCpp String str);"
2547 "}");
2548 CaptureStderr();
2549 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2550 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2551 }
2552
TEST_F(AidlTestIncompatibleChanges,AddedAnnotation)2553 TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
2554 const string expected_stderr =
2555 "ERROR: new/p/IFoo.aidl:1.51-58: Changed annotations: (empty) to @utf8InCpp\n";
2556 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2557 "package p;"
2558 "interface IFoo {"
2559 " void foo(in String[] str);"
2560 " void bar(@utf8InCpp String str);"
2561 "}");
2562 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2563 "package p;"
2564 "interface IFoo {"
2565 " void foo(in @utf8InCpp String[] str);"
2566 " void bar(@utf8InCpp String str);"
2567 "}");
2568 CaptureStderr();
2569 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2570 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2571 }
2572
TEST_F(AidlTestIncompatibleChanges,RemovedAnnotation)2573 TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
2574 const string expected_stderr =
2575 "ERROR: new/p/IFoo.aidl:1.66-72: Changed annotations: @utf8InCpp to (empty)\n";
2576 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2577 "package p;"
2578 "interface IFoo {"
2579 " void foo(in String[] str);"
2580 " void bar(@utf8InCpp String str);"
2581 "}");
2582 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2583 "package p;"
2584 "interface IFoo {"
2585 " void foo(in String[] str);"
2586 " void bar(String str);"
2587 "}");
2588 CaptureStderr();
2589 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2590 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2591 }
2592
TEST_F(AidlTestIncompatibleChanges,ChangedBackingTypeOfEnum)2593 TEST_F(AidlTestIncompatibleChanges, ChangedBackingTypeOfEnum) {
2594 const string expected_stderr =
2595 "ERROR: new/p/Foo.aidl:1.11-32: Type changed: byte to long.\n"
2596 "ERROR: new/p/Foo.aidl:1.36-40: Changed backing types.\n";
2597 io_delegate_.SetFileContents("old/p/Foo.aidl",
2598 "package p;"
2599 "@Backing(type=\"byte\")"
2600 "enum Foo {"
2601 " FOO, BAR,"
2602 "}");
2603 io_delegate_.SetFileContents("new/p/Foo.aidl",
2604 "package p;"
2605 "@Backing(type=\"long\")"
2606 "enum Foo {"
2607 " FOO, BAR,"
2608 "}");
2609 CaptureStderr();
2610 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2611 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2612 }
2613
TEST_F(AidlTestIncompatibleChanges,ChangedAnnatationParams)2614 TEST_F(AidlTestIncompatibleChanges, ChangedAnnatationParams) {
2615 const string expected_stderr =
2616 "ERROR: new/p/Foo.aidl:1.55-59: Changed annotations: @JavaPassthrough(annotation=\"Alice\") "
2617 "to @JavaPassthrough(annotation=\"Bob\")\n";
2618 io_delegate_.SetFileContents("old/p/Foo.aidl",
2619 "package p;"
2620 "@JavaPassthrough(annotation=\"Alice\")"
2621 "parcelable Foo {}");
2622 io_delegate_.SetFileContents("new/p/Foo.aidl",
2623 "package p;"
2624 "@JavaPassthrough(annotation=\"Bob\")"
2625 "parcelable Foo {}");
2626
2627 CaptureStderr();
2628 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2629 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2630 }
2631
TEST_F(AidlTestIncompatibleChanges,AddedParcelableAnnotation)2632 TEST_F(AidlTestIncompatibleChanges, AddedParcelableAnnotation) {
2633 const string expected_stderr =
2634 "ERROR: new/p/Foo.aidl:1.32-36: Changed annotations: (empty) to @FixedSize\n";
2635 io_delegate_.SetFileContents("old/p/Foo.aidl",
2636 "package p;"
2637 "parcelable Foo {"
2638 " int A;"
2639 "}");
2640 io_delegate_.SetFileContents("new/p/Foo.aidl",
2641 "package p;"
2642 "@FixedSize parcelable Foo {"
2643 " int A;"
2644 "}");
2645 CaptureStderr();
2646 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2647 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2648 }
2649
TEST_F(AidlTestIncompatibleChanges,RemovedParcelableAnnotation)2650 TEST_F(AidlTestIncompatibleChanges, RemovedParcelableAnnotation) {
2651 const string expected_stderr =
2652 "ERROR: new/p/Foo.aidl:1.21-25: Changed annotations: @FixedSize to (empty)\n";
2653 io_delegate_.SetFileContents("old/p/Foo.aidl",
2654 "package p;"
2655 "@FixedSize parcelable Foo {"
2656 " int A;"
2657 "}");
2658 io_delegate_.SetFileContents("new/p/Foo.aidl",
2659 "package p;"
2660 "parcelable Foo {"
2661 " int A;"
2662 "}");
2663 CaptureStderr();
2664 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2665 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2666 }
2667
TEST_F(AidlTestIncompatibleChanges,RemovedPackage)2668 TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
2669 const string expected_stderr = "ERROR: old/q/IFoo.aidl:1.11-21: Removed type: q.IFoo\n";
2670 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
2671 io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
2672 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
2673 CaptureStderr();
2674 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2675 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2676 }
2677
TEST_F(AidlTestIncompatibleChanges,ChangedDefaultValue)2678 TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
2679 const string expected_stderr = "ERROR: new/p/D.aidl:1.30-32: Changed default value: 1 to 2.\n";
2680 io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
2681 io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
2682 CaptureStderr();
2683 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2684 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2685 }
2686
TEST_F(AidlTestIncompatibleChanges,RemovedConstValue)2687 TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
2688 const string expected_stderr =
2689 "ERROR: old/p/I.aidl:1.51-53: Removed constant declaration: p.I.B\n";
2690 io_delegate_.SetFileContents("old/p/I.aidl",
2691 "package p; interface I {"
2692 "const int A = 1; const int B = 2;}");
2693 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
2694 CaptureStderr();
2695 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2696 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2697 }
2698
TEST_F(AidlTestIncompatibleChanges,ChangedConstValue)2699 TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
2700 const string expected_stderr =
2701 "ERROR: new/p/I.aidl:1.11-21: Changed constant value: p.I.A from 1 to 2.\n";
2702 io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
2703 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
2704 CaptureStderr();
2705 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2706 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2707 }
2708
TEST_F(AidlTestIncompatibleChanges,FixedSizeAddedField)2709 TEST_F(AidlTestIncompatibleChanges, FixedSizeAddedField) {
2710 const string expected_stderr =
2711 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is changed from 1 to 2. "
2712 "This is an incompatible change for FixedSize types.\n";
2713 io_delegate_.SetFileContents("old/p/Foo.aidl",
2714 "package p; @FixedSize parcelable Foo { int A = 1; }");
2715 io_delegate_.SetFileContents("new/p/Foo.aidl",
2716 "package p; @FixedSize parcelable Foo { int A = 1; int B = 2; }");
2717 CaptureStderr();
2718 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2719 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2720 }
2721
TEST_F(AidlTestIncompatibleChanges,UidRangeParcelAddedField)2722 TEST_F(AidlTestIncompatibleChanges, UidRangeParcelAddedField) {
2723 const string expected_stderr =
2724 "ERROR: new/android/net/UidRangeParcel.aidl:1.32-47: Number of fields in "
2725 "android.net.UidRangeParcel is changed from 1 to 2. "
2726 "But it is forbidden because of legacy support.\n";
2727 io_delegate_.SetFileContents("old/android/net/UidRangeParcel.aidl",
2728 "package android.net; parcelable UidRangeParcel { int A = 1; }");
2729 io_delegate_.SetFileContents(
2730 "new/android/net/UidRangeParcel.aidl",
2731 "package android.net; parcelable UidRangeParcel { int A = 1; int B = 2; }");
2732 CaptureStderr();
2733 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2734 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2735 }
2736
TEST_F(AidlTestIncompatibleChanges,FixedSizeRemovedField)2737 TEST_F(AidlTestIncompatibleChanges, FixedSizeRemovedField) {
2738 const string expected_stderr =
2739 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
2740 io_delegate_.SetFileContents("old/p/Foo.aidl",
2741 "package p; @FixedSize parcelable Foo { int A = 1; int B = 1; }");
2742 io_delegate_.SetFileContents("new/p/Foo.aidl",
2743 "package p; @FixedSize parcelable Foo { int A = 1; }");
2744 CaptureStderr();
2745 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2746 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2747 }
2748
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize)2749 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize) {
2750 const string expected_stderr =
2751 "ERROR: Foo.aidl:1.36-38: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2752 "a.\n"
2753 "ERROR: Foo.aidl:1.44-46: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2754 "b.\n"
2755 "ERROR: Foo.aidl:1.55-57: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2756 "c.\n"
2757 "ERROR: Foo.aidl:1.80-82: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2758 "d.\n"
2759 "ERROR: Foo.aidl:1.92-94: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2760 "e.\n"
2761 "ERROR: Foo.aidl:1.109-111: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2762 "f.\n";
2763
2764 io_delegate_.SetFileContents("Foo.aidl",
2765 "@FixedSize parcelable Foo { "
2766 " int[] a;"
2767 " Bar b;"
2768 " String c;"
2769 " ParcelFileDescriptor d;"
2770 " IBinder e;"
2771 " List<String> f;"
2772 " int isFixedSize;"
2773 "}");
2774 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
2775 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2776
2777 CaptureStderr();
2778 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2779 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2780 }
2781
TEST_P(AidlTest,AcceptFixedSizeFromFixedSize)2782 TEST_P(AidlTest, AcceptFixedSizeFromFixedSize) {
2783 const string expected_stderr = "";
2784
2785 io_delegate_.SetFileContents("Foo.aidl", "@FixedSize parcelable Foo { int a; Bar b; }");
2786 io_delegate_.SetFileContents("Bar.aidl", "@FixedSize parcelable Bar { Val c; }");
2787 io_delegate_.SetFileContents("Val.aidl", "enum Val { A, B, }");
2788 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2789
2790 CaptureStderr();
2791 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2792 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2793 }
2794
TEST_F(AidlTest,RejectAmbiguousImports)2795 TEST_F(AidlTest, RejectAmbiguousImports) {
2796 const string expected_stderr =
2797 "ERROR: p/IFoo.aidl: Duplicate files found for q.IBar from:\n"
2798 "dir1/q/IBar.aidl\n"
2799 "dir2/q/IBar.aidl\n"
2800 "ERROR: p/IFoo.aidl: Couldn't find import for class q.IBar\n";
2801 Options options = Options::From("aidl --lang=java -o out -I dir1 -I dir2 p/IFoo.aidl");
2802 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
2803 io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
2804 io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
2805
2806 CaptureStderr();
2807 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2808 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2809 }
2810
TEST_F(AidlTest,HandleManualIdAssignments)2811 TEST_F(AidlTest, HandleManualIdAssignments) {
2812 const string expected_stderr =
2813 "ERROR: new/p/IFoo.aidl:1.32-36: Transaction ID changed: p.IFoo.foo() is changed from 10 to "
2814 "11.\n";
2815 Options options = Options::From("aidl --checkapi old new");
2816 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
2817 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
2818
2819 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2820
2821 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
2822 CaptureStderr();
2823 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
2824 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2825 }
2826
TEST_P(AidlTest,ParcelFileDescriptorIsBuiltinType)2827 TEST_P(AidlTest, ParcelFileDescriptorIsBuiltinType) {
2828 Options options =
2829 Options::From("aidl --lang=" + to_string(GetLanguage()) + " -h out -o out p/IFoo.aidl");
2830
2831 // use without import
2832 io_delegate_.SetFileContents("p/IFoo.aidl",
2833 "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
2834 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2835
2836 // capture output files
2837 map<string, string> outputs = io_delegate_.OutputFiles();
2838
2839 // use without import but with full name
2840 io_delegate_.SetFileContents(
2841 "p/IFoo.aidl",
2842 "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
2843 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2844 // output files should be the same
2845 EXPECT_EQ(outputs, io_delegate_.OutputFiles());
2846
2847 // use with import (as before)
2848 io_delegate_.SetFileContents("p/IFoo.aidl",
2849 "package p;"
2850 "import android.os.ParcelFileDescriptor;"
2851 "interface IFoo{"
2852 " void foo(in ParcelFileDescriptor fd);"
2853 "}");
2854 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2855 // output files should be the same
2856 EXPECT_EQ(outputs, io_delegate_.OutputFiles());
2857 }
2858
TEST_P(AidlTest,RejectsOutputParcelFileDescriptor)2859 TEST_P(AidlTest, RejectsOutputParcelFileDescriptor) {
2860 Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
2861 CaptureStderr();
2862 io_delegate_.SetFileContents("p/IFoo.aidl",
2863 "package p;"
2864 "interface IFoo{"
2865 " void foo(out ParcelFileDescriptor fd);"
2866 "}");
2867 EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
2868 EXPECT_THAT(GetCapturedStderr(), HasSubstr("can't be an out parameter"));
2869 }
2870
TEST_P(AidlTest,RejectsArgumentDirectionNotSpecified)2871 TEST_P(AidlTest, RejectsArgumentDirectionNotSpecified) {
2872 Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
2873 CaptureStderr();
2874 io_delegate_.SetFileContents("p/IFoo.aidl",
2875 "package p;"
2876 "interface IFoo{"
2877 " void foo(ParcelFileDescriptor fd);"
2878 "}");
2879 EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
2880 EXPECT_THAT(GetCapturedStderr(),
2881 HasSubstr("ParcelFileDescriptor can be an in or inout parameter."));
2882 }
2883
TEST_F(AidlTest,ManualIds)2884 TEST_F(AidlTest, ManualIds) {
2885 Options options = Options::From("aidl --lang=java -o out IFoo.aidl");
2886 io_delegate_.SetFileContents("IFoo.aidl",
2887 "interface IFoo {\n"
2888 " void foo() = 0;\n"
2889 " void bar() = 1;\n"
2890 "}");
2891 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2892 }
2893
TEST_F(AidlTest,ManualIdsWithMetaTransactions)2894 TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
2895 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2896 io_delegate_.SetFileContents("IFoo.aidl",
2897 "interface IFoo {\n"
2898 " void foo() = 0;\n"
2899 " void bar() = 1;\n"
2900 "}");
2901 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2902 }
2903
TEST_F(AidlTest,FailOnDuplicatedIds)2904 TEST_F(AidlTest, FailOnDuplicatedIds) {
2905 const string expected_stderr =
2906 "ERROR: IFoo.aidl:3.7-11: Found duplicate method id (3) for method bar\n";
2907 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2908 io_delegate_.SetFileContents("IFoo.aidl",
2909 "interface IFoo {\n"
2910 " void foo() = 3;\n"
2911 " void bar() = 3;\n"
2912 "}");
2913 CaptureStderr();
2914 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2915 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2916 }
2917
TEST_F(AidlTest,FailOnOutOfRangeIds)2918 TEST_F(AidlTest, FailOnOutOfRangeIds) {
2919 // 16777115 is kLastMetaMethodId + 1
2920 const string expected_stderr =
2921 "ERROR: IFoo.aidl:3.7-11: Found out of bounds id (16777115) for method bar. "
2922 "Value for id must be between 0 and 16777114 inclusive.\n";
2923 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2924 io_delegate_.SetFileContents("IFoo.aidl",
2925 "interface IFoo {\n"
2926 " void foo() = 3;\n"
2927 " void bar() = 16777115;\n"
2928 "}");
2929 CaptureStderr();
2930 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2931 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2932 }
2933
TEST_F(AidlTest,FailOnPartiallyAssignedIds)2934 TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
2935 const string expected_stderr =
2936 "ERROR: IFoo.aidl:3.7-11: You must either assign id's to all methods or to none of them.\n";
2937 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2938 io_delegate_.SetFileContents("IFoo.aidl",
2939 "interface IFoo {\n"
2940 " void foo() = 3;\n"
2941 " void bar();\n"
2942 "}");
2943 CaptureStderr();
2944 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2945 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2946 }
2947
TEST_F(AidlTest,AllowDuplicatedImportPaths)2948 TEST_F(AidlTest, AllowDuplicatedImportPaths) {
2949 Options options = Options::From("aidl --lang=java -I dir -I dir IFoo.aidl");
2950 io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
2951 io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
2952 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2953 }
2954
TEST_F(AidlTest,FailOnAmbiguousImports)2955 TEST_F(AidlTest, FailOnAmbiguousImports) {
2956 const string expected_stderr =
2957 "ERROR: IFoo.aidl: Duplicate files found for IBar from:\n"
2958 "dir/IBar.aidl\n"
2959 "dir2/IBar.aidl\n"
2960 "ERROR: IFoo.aidl: Couldn't find import for class IBar\n";
2961
2962 Options options = Options::From("aidl --lang=java -I dir -I dir2 IFoo.aidl");
2963 io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
2964 io_delegate_.SetFileContents("dir2/IBar.aidl", "interface IBar{}");
2965 io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
2966 CaptureStderr();
2967 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2968 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2969 }
2970
TEST_F(AidlTest,UnusedImportDoesNotContributeInclude)2971 TEST_F(AidlTest, UnusedImportDoesNotContributeInclude) {
2972 io_delegate_.SetFileContents("a/b/IFoo.aidl",
2973 "package a.b;\n"
2974 "import a.b.IBar;\n"
2975 "import a.b.IQux;\n"
2976 "interface IFoo { IQux foo(); }\n");
2977 io_delegate_.SetFileContents("a/b/IBar.aidl", "package a.b; interface IBar { void foo(); }");
2978 io_delegate_.SetFileContents("a/b/IQux.aidl", "package a.b; interface IQux { void foo(); }");
2979
2980 Options options = Options::From("aidl --lang=ndk a/b/IFoo.aidl -I . -o out -h out/include");
2981 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2982
2983 string output;
2984 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/include/aidl/a/b/IFoo.h", &output));
2985 // IBar was imported but wasn't used. include is not expected.
2986 EXPECT_THAT(output, Not(testing::HasSubstr("#include <aidl/a/b/IBar.h>")));
2987 // IBar was imported and used. include is expected.
2988 EXPECT_THAT(output, (testing::HasSubstr("#include <aidl/a/b/IQux.h>")));
2989 }
2990
TEST_F(AidlTest,ParseJavaPassthroughAnnotation)2991 TEST_F(AidlTest, ParseJavaPassthroughAnnotation) {
2992 io_delegate_.SetFileContents("a/IFoo.aidl", R"--(package a;
2993 import a.MyEnum;
2994 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
2995 @JavaPassthrough(annotation="@com.android.AliceTwo")
2996 interface IFoo {
2997 @JavaPassthrough(annotation="@com.android.Bob")
2998 void foo(@JavaPassthrough(annotation="@com.android.Cat") int x, MyEnum y);
2999 const @JavaPassthrough(annotation="@com.android.David") int A = 3;
3000 })--");
3001 // JavaPassthrough should work with other types as well (e.g. enum)
3002 io_delegate_.SetFileContents("a/MyEnum.aidl", R"--(package a;
3003 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
3004 @JavaPassthrough(annotation="@com.android.AliceTwo")
3005 @Backing(type="byte")
3006 enum MyEnum {
3007 a, b, c
3008 })--");
3009
3010 Options java_options = Options::From("aidl -I . --lang=java -o out a/IFoo.aidl a/MyEnum.aidl");
3011 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
3012
3013 string java_out;
3014 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &java_out));
3015 // type-decl-level annotations with newline at the end
3016 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
3017 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3018 // member-decl-level annotations with newline at the end
3019 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Bob\n"));
3020 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.David\n"));
3021 // inline annotations with space at the end
3022 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Cat "));
3023
3024 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/MyEnum.java", &java_out));
3025 // type-decl-level annotations with newline at the end
3026 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
3027 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3028
3029 // Other backends shouldn't be bothered
3030 Options cpp_options =
3031 Options::From("aidl -I . --lang=cpp -o out -h out a/IFoo.aidl a/MyEnum.aidl");
3032 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
3033
3034 Options ndk_options =
3035 Options::From("aidl -I . --lang=ndk -o out -h out a/IFoo.aidl a/MyEnum.aidl");
3036 EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
3037
3038 Options rust_options = Options::From("aidl -I . --lang=rust -o out a/IFoo.aidl a/MyEnum.aidl");
3039 EXPECT_EQ(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
3040 }
3041
TEST_F(AidlTest,ParseRustDerive)3042 TEST_F(AidlTest, ParseRustDerive) {
3043 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
3044 @RustDerive(Clone=true, Copy=false)
3045 parcelable Foo {
3046 int a;
3047 })");
3048
3049 Options rust_options = Options::From("aidl --lang=rust -o out a/Foo.aidl");
3050 EXPECT_EQ(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
3051
3052 string rust_out;
3053 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.rs", &rust_out));
3054 EXPECT_THAT(rust_out, testing::HasSubstr("#[derive(Debug, Clone)]"));
3055
3056 // Other backends shouldn't be bothered
3057 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
3058 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
3059
3060 Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
3061 EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
3062
3063 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
3064 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
3065 }
3066
3067 class AidlOutputPathTest : public AidlTest {
3068 protected:
SetUp()3069 void SetUp() override {
3070 AidlTest::SetUp();
3071 io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
3072 }
3073
Test(const Options & options,const std::string expected_output_path)3074 void Test(const Options& options, const std::string expected_output_path) {
3075 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3076 // check the existence
3077 EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
3078 }
3079 };
3080
TEST_F(AidlOutputPathTest,OutDirWithNoOutputFile)3081 TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
3082 // <out_dir> / <package_name> / <type_name>.java
3083 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
3084 }
3085
TEST_F(AidlOutputPathTest,OutDirWithOutputFile)3086 TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
3087 // when output file is explicitly set, it is always respected. -o option is
3088 // ignored.
3089 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3090 }
3091
TEST_F(AidlOutputPathTest,NoOutDirWithOutputFile)3092 TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
3093 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3094 }
3095
TEST_F(AidlOutputPathTest,NoOutDirWithNoOutputFile)3096 TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
3097 // output is the same as the input file except for the suffix
3098 Test(Options::From("aidl sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
3099 }
3100
TEST_P(AidlTest,FailOnOutOfBoundsInt32MaxConstInt)3101 TEST_P(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
3102 AidlError error;
3103 const string expected_stderr =
3104 "ERROR: p/IFoo.aidl:3.58-69: Invalid type specifier for an int64 literal: int\n";
3105 CaptureStderr();
3106 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3107 R"(package p;
3108 interface IFoo {
3109 const int int32_max_oob = 2147483650;
3110 }
3111 )",
3112 typenames_, GetLanguage(), &error));
3113 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3114 EXPECT_EQ(AidlError::BAD_TYPE, error);
3115 }
3116
TEST_P(AidlTest,FailOnOutOfBoundsInt32MinConstInt)3117 TEST_P(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
3118 AidlError error;
3119 const string expected_stderr =
3120 "ERROR: p/IFoo.aidl:3.58-60: Invalid type specifier for an int64 literal: int\n";
3121 CaptureStderr();
3122 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3123 R"(package p;
3124 interface IFoo {
3125 const int int32_min_oob = -2147483650;
3126 }
3127 )",
3128 typenames_, GetLanguage(), &error));
3129 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3130 EXPECT_EQ(AidlError::BAD_TYPE, error);
3131 }
3132
TEST_P(AidlTest,FailOnOutOfBoundsInt64MaxConstInt)3133 TEST_P(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
3134 AidlError error;
3135 const string expected_stderr =
3136 "ERROR: p/IFoo.aidl:3.59-86: Could not parse integer: 21474836509999999999999999\n";
3137 CaptureStderr();
3138 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3139 R"(package p;
3140 interface IFoo {
3141 const long int64_max_oob = 21474836509999999999999999;
3142 }
3143 )",
3144 typenames_, GetLanguage(), &error));
3145 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3146 EXPECT_EQ(AidlError::PARSE_ERROR, error);
3147 }
3148
TEST_P(AidlTest,FailOnOutOfBoundsInt64MinConstInt)3149 TEST_P(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
3150 AidlError error;
3151 const string expected_stderr =
3152 "ERROR: p/IFoo.aidl:3.61-87: Could not parse integer: 21474836509999999999999999\n";
3153 CaptureStderr();
3154 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3155 R"(package p;
3156 interface IFoo {
3157 const long int64_min_oob = -21474836509999999999999999;
3158 }
3159 )",
3160 typenames_, GetLanguage(), &error));
3161 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3162 EXPECT_EQ(AidlError::PARSE_ERROR, error);
3163 }
3164
TEST_P(AidlTest,FailOnOutOfBoundsAutofilledEnum)3165 TEST_P(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
3166 AidlError error;
3167 const string expected_stderr =
3168 "ERROR: p/TestEnum.aidl:5.1-36: Invalid type specifier for an int32 literal: byte\n"
3169 "ERROR: p/TestEnum.aidl:5.1-36: Enumerator type differs from enum backing type.\n";
3170 CaptureStderr();
3171 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3172 R"(package p;
3173 @Backing(type="byte")
3174 enum TestEnum {
3175 FOO = 127,
3176 BAR,
3177 }
3178 )",
3179 typenames_, GetLanguage(), &error));
3180 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3181 EXPECT_EQ(AidlError::BAD_TYPE, error);
3182 }
3183
TEST_P(AidlTest,UnsupportedBackingAnnotationParam)3184 TEST_P(AidlTest, UnsupportedBackingAnnotationParam) {
3185 AidlError error;
3186 const string expected_stderr =
3187 "ERROR: p/TestEnum.aidl:2.1-51: Parameter foo not supported for annotation Backing. It must "
3188 "be one of: type\n";
3189 CaptureStderr();
3190 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3191 R"(package p;
3192 @Backing(foo="byte")
3193 enum TestEnum {
3194 FOO = 1,
3195 BAR,
3196 }
3197 )",
3198 typenames_, GetLanguage(), &error));
3199 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3200 EXPECT_EQ(AidlError::BAD_TYPE, error);
3201 }
3202
TEST_P(AidlTest,BackingAnnotationRequireTypeParameter)3203 TEST_P(AidlTest, BackingAnnotationRequireTypeParameter) {
3204 const string expected_stderr = "ERROR: Enum.aidl:1.1-9: Missing 'type' on @Backing.\n";
3205 CaptureStderr();
3206 EXPECT_EQ(nullptr, Parse("Enum.aidl", "@Backing enum Enum { FOO }", typenames_, GetLanguage()));
3207 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3208 }
3209
TEST_F(AidlTest,SupportJavaOnlyImmutableAnnotation)3210 TEST_F(AidlTest, SupportJavaOnlyImmutableAnnotation) {
3211 io_delegate_.SetFileContents("Foo.aidl",
3212 "@JavaOnlyImmutable parcelable Foo { int a; Bar b; List<Bar> c; "
3213 "Map<String, Baz> d; Bar[] e; }");
3214 io_delegate_.SetFileContents("Bar.aidl", "@JavaOnlyImmutable parcelable Bar { String a; }");
3215 io_delegate_.SetFileContents("Baz.aidl",
3216 "@JavaOnlyImmutable @JavaOnlyStableParcelable parcelable Baz;");
3217 Options options = Options::From("aidl --lang=java -I . Foo.aidl");
3218 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3219 }
3220
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableParcelable)3221 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableParcelable) {
3222 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
3223 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
3224 string expected_error =
3225 "ERROR: Foo.aidl:1.40-44: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
3226 "named 'bar'.\n";
3227 CaptureStderr();
3228 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3229 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3230 EXPECT_EQ(expected_error, GetCapturedStderr());
3231 }
3232
TEST_F(AidlTest,JavaOnlyImmutableParcelableWithEnumFields)3233 TEST_F(AidlTest, JavaOnlyImmutableParcelableWithEnumFields) {
3234 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
3235 io_delegate_.SetFileContents("Bar.aidl", "enum Bar { FOO }");
3236 CaptureStderr();
3237 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3238 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3239 EXPECT_EQ("", GetCapturedStderr());
3240 }
3241
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableUnion)3242 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableUnion) {
3243 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable union Foo { Bar bar; }");
3244 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
3245 string expected_error =
3246 "ERROR: Foo.aidl:1.35-39: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
3247 "named 'bar'.\n";
3248 CaptureStderr();
3249 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3250 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3251 EXPECT_EQ(expected_error, GetCapturedStderr());
3252 }
3253
TEST_F(AidlTest,ImmutableParcelableCannotBeInOut)3254 TEST_F(AidlTest, ImmutableParcelableCannotBeInOut) {
3255 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
3256 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(inout Foo foo); }");
3257 string expected_error =
3258 "ERROR: IBar.aidl:1.35-39: 'foo' can't be an inout parameter because @JavaOnlyImmutable can "
3259 "only be an in parameter.\n";
3260 CaptureStderr();
3261 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
3262 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3263 EXPECT_EQ(expected_error, GetCapturedStderr());
3264 }
3265
TEST_F(AidlTest,ImmutableParcelableCannotBeOut)3266 TEST_F(AidlTest, ImmutableParcelableCannotBeOut) {
3267 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
3268 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(out Foo foo); }");
3269 string expected_error =
3270 "ERROR: IBar.aidl:1.33-37: 'foo' can't be an out parameter because @JavaOnlyImmutable can "
3271 "only be an in parameter.\n";
3272 CaptureStderr();
3273 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
3274 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3275 EXPECT_EQ(expected_error, GetCapturedStderr());
3276 }
3277
TEST_F(AidlTest,ImmutableParcelableFieldNameRestriction)3278 TEST_F(AidlTest, ImmutableParcelableFieldNameRestriction) {
3279 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; int A; }");
3280 Options options = Options::From("aidl --lang=java Foo.aidl");
3281 const string expected_stderr =
3282 "ERROR: Foo.aidl:1.47-49: 'Foo' has duplicate field name 'A' after capitalizing the first "
3283 "letter\n";
3284 CaptureStderr();
3285 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3286 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3287 }
3288
TEST_P(AidlTest,UnionInUnion)3289 TEST_P(AidlTest, UnionInUnion) {
3290 import_paths_.insert(".");
3291 io_delegate_.SetFileContents("Bar.aidl", "union Bar { int n = 42; long l; }");
3292 CaptureStderr();
3293 EXPECT_NE(nullptr, Parse("Foo.aidl", "union Foo { Bar b; int n; }", typenames_, GetLanguage()));
3294 EXPECT_THAT("", GetCapturedStderr());
3295 }
3296
TEST_P(AidlTest,UnionRejectsEmptyDecl)3297 TEST_P(AidlTest, UnionRejectsEmptyDecl) {
3298 const string method = "package a; union Foo {}";
3299 const string expected_stderr = "ERROR: a/Foo.aidl:1.17-21: The union 'Foo' has no fields.\n";
3300 CaptureStderr();
3301 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3302 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3303 }
3304
TEST_P(AidlTest,UnionRejectsParcelableHolder)3305 TEST_P(AidlTest, UnionRejectsParcelableHolder) {
3306 const string method = "package a; union Foo { ParcelableHolder x; }";
3307 const string expected_stderr =
3308 "ERROR: a/Foo.aidl:1.40-42: A union can't have a member of ParcelableHolder 'x'\n";
3309 CaptureStderr();
3310 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3311 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3312 }
3313
TEST_P(AidlTest,UnionRejectsFirstEnumWithNoDefaults)3314 TEST_P(AidlTest, UnionRejectsFirstEnumWithNoDefaults) {
3315 import_paths_.insert(".");
3316 io_delegate_.SetFileContents("a/Enum.aidl", "package a; enum Enum { FOO, BAR }");
3317 const string expected_err = "The union's first member should have a useful default value.";
3318 CaptureStderr();
3319 EXPECT_EQ(nullptr,
3320 Parse("a/Foo.aidl", "package a; union Foo { a.Enum e; }", typenames_, GetLanguage()));
3321 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_err));
3322 }
3323
TEST_P(AidlTest,GenericStructuredParcelable)3324 TEST_P(AidlTest, GenericStructuredParcelable) {
3325 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T, U> { int a; int A; }");
3326 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3327 const string expected_stderr = "";
3328 CaptureStderr();
3329 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3330 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3331 }
3332
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Cpp)3333 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
3334 io_delegate_.SetFileContents("Foo.aidl",
3335 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
3336 Options options =
3337 Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::CPP) + " -o out -h out");
3338 const string expected_stderr = "";
3339 CaptureStderr();
3340 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3341 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3342
3343 string code;
3344 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
3345 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
3346 const ::android::String16& Foo<T,U>::s() {
3347 static const ::android::String16 value(::android::String16(""));
3348 return value;
3349 })--"));
3350 }
3351
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Ndk)3352 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
3353 io_delegate_.SetFileContents("Foo.aidl",
3354 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
3355 Options options =
3356 Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::NDK) + " -o out -h out");
3357 const string expected_stderr = "";
3358 CaptureStderr();
3359 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3360 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3361
3362 string code;
3363 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
3364 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
3365 const char* Foo<T, U>::s = "";
3366 )--"));
3367 }
3368
TEST_F(AidlTest,NestedTypeArgs)3369 TEST_F(AidlTest, NestedTypeArgs) {
3370 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
3371 io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");
3372
3373 io_delegate_.SetFileContents("a/Foo.aidl",
3374 "package a; import a.Bar; import a.Baz; parcelable Foo { "
3375 "Baz<Bar<Bar<String[]>>[], Bar<String>> barss; }");
3376 Options options = Options::From("aidl a/Foo.aidl -I . -o out --lang=java");
3377 const string expected_stderr = "";
3378 CaptureStderr();
3379 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3380 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3381
3382 string code;
3383 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
3384 EXPECT_THAT(code,
3385 testing::HasSubstr(
3386 "a.Baz<a.Bar<a.Bar<java.lang.String[]>>[],a.Bar<java.lang.String>> barss;"));
3387 }
3388
TEST_F(AidlTest,DoubleArrayError)3389 TEST_F(AidlTest, DoubleArrayError) {
3390 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][] a; }");
3391
3392 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3393 const string expected_stderr =
3394 "ERROR: a/Bar.aidl:1.28-37: Can only have one dimensional arrays.\n";
3395 CaptureStderr();
3396 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3397 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3398 }
3399
TEST_F(AidlTest,DoubleGenericError)3400 TEST_F(AidlTest, DoubleGenericError) {
3401 io_delegate_.SetFileContents("a/Bar.aidl",
3402 "package a; parcelable Bar { List<String><String> a; }");
3403
3404 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3405 const string expected_stderr =
3406 "ERROR: a/Bar.aidl:1.28-33: Can only specify one set of type parameters.\n";
3407 CaptureStderr();
3408 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3409 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3410 }
3411
TEST_F(AidlTest,ArrayBeforeGenericError)3412 TEST_F(AidlTest, ArrayBeforeGenericError) {
3413 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { List[]<String> a; }");
3414
3415 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3416 CaptureStderr();
3417 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3418 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("syntax error, unexpected '<'"));
3419 }
3420
TEST_F(AidlTest,NullableArraysAreNotSupported)3421 TEST_F(AidlTest, NullableArraysAreNotSupported) {
3422 io_delegate_.SetFileContents("a/Bar.aidl",
3423 "package a; parcelable Bar { String @nullable [] a; }");
3424
3425 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3426 CaptureStderr();
3427 EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
3428 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("Annotations for arrays are not supported."));
3429 }
3430
TEST_F(AidlTest,ListOfNullablesAreNotSupported)3431 TEST_F(AidlTest, ListOfNullablesAreNotSupported) {
3432 io_delegate_.SetFileContents("a/Bar.aidl",
3433 "package a; parcelable Bar { List<@nullable String> a; }");
3434
3435 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3436 CaptureStderr();
3437 EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
3438 EXPECT_THAT(GetCapturedStderr(),
3439 testing::HasSubstr("Annotations for type arguments are not supported."));
3440 }
3441
3442 struct GenericAidlTest : ::testing::Test {
3443 FakeIoDelegate io_delegate_;
Compileandroid::aidl::GenericAidlTest3444 void Compile(string cmd) {
3445 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { Bar<Baz<Qux>> x; }");
3446 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar<T> { }");
3447 io_delegate_.SetFileContents("Baz.aidl", "parcelable Baz<T> { }");
3448 io_delegate_.SetFileContents("Qux.aidl", "parcelable Qux { }");
3449
3450 Options options = Options::From(cmd);
3451 CaptureStderr();
3452 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3453 EXPECT_EQ("", GetCapturedStderr());
3454 }
3455 };
3456
TEST_F(GenericAidlTest,ImportGenericParameterTypesCPP)3457 TEST_F(GenericAidlTest, ImportGenericParameterTypesCPP) {
3458 Compile("aidl Foo.aidl --lang=cpp -I . -o out -h out");
3459 string code;
3460 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
3461 EXPECT_THAT(code, testing::HasSubstr("#include <Bar.h>"));
3462 EXPECT_THAT(code, testing::HasSubstr("#include <Baz.h>"));
3463 EXPECT_THAT(code, testing::HasSubstr("#include <Qux.h>"));
3464 }
3465
TEST_F(GenericAidlTest,ImportGenericParameterTypesNDK)3466 TEST_F(GenericAidlTest, ImportGenericParameterTypesNDK) {
3467 Compile("aidl Foo.aidl --lang=ndk -I . -o out -h out");
3468 string code;
3469 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
3470 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Bar.h>"));
3471 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Baz.h>"));
3472 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Qux.h>"));
3473 }
3474
TEST_P(AidlTest,RejectGenericStructuredParcelabelRepeatedParam)3475 TEST_P(AidlTest, RejectGenericStructuredParcelabelRepeatedParam) {
3476 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { int a; int A; }");
3477 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3478 const string expected_stderr =
3479 "ERROR: Foo.aidl:1.11-15: Every type parameter should be unique.\n";
3480 CaptureStderr();
3481 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3482 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3483 }
3484
TEST_P(AidlTest,RejectGenericStructuredParcelableField)3485 TEST_P(AidlTest, RejectGenericStructuredParcelableField) {
3486 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { T a; int A; }");
3487 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3488 const string expected_stderr = "ERROR: Foo.aidl:1.22-24: Failed to resolve 'T'\n";
3489 CaptureStderr();
3490 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3491 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3492 }
3493
TEST_P(AidlTest,LongCommentWithinConstExpression)3494 TEST_P(AidlTest, LongCommentWithinConstExpression) {
3495 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { FOO = (1 << 1) /* comment */ | 0x0 }");
3496 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3497 CaptureStderr();
3498 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3499 EXPECT_EQ("", GetCapturedStderr());
3500 }
3501
TEST_F(AidlTest,RejectUntypdeListAndMapInUnion)3502 TEST_F(AidlTest, RejectUntypdeListAndMapInUnion) {
3503 io_delegate_.SetFileContents("a/Foo.aidl", "package a; union Foo { List l; Map m; }");
3504 Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
3505 std::string expectedErr =
3506 "ERROR: a/Foo.aidl:1.28-30: "
3507 "Encountered an untyped List or Map. The use of untyped List/Map is "
3508 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3509 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3510 "ERROR: a/Foo.aidl:1.35-37: "
3511 "Encountered an untyped List or Map. The use of untyped List/Map is "
3512 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3513 "the receiving side. Consider switching to an array or a generic List/Map.\n";
3514 CaptureStderr();
3515 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3516 EXPECT_EQ(expectedErr, GetCapturedStderr());
3517 }
3518
TEST_F(AidlTest,RejectUntypdeListAndMapInUnstructuredParcelable)3519 TEST_F(AidlTest, RejectUntypdeListAndMapInUnstructuredParcelable) {
3520 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { List l; Map m; }");
3521 Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
3522 std::string expectedErr =
3523 "ERROR: a/Foo.aidl:1.33-35: "
3524 "Encountered an untyped List or Map. The use of untyped List/Map is "
3525 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3526 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3527 "ERROR: a/Foo.aidl:1.40-42: "
3528 "Encountered an untyped List or Map. The use of untyped List/Map is "
3529 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3530 "the receiving side. Consider switching to an array or a generic List/Map.\n";
3531 CaptureStderr();
3532 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3533 EXPECT_EQ(expectedErr, GetCapturedStderr());
3534 }
3535
TEST_F(AidlTest,RejectNestedUntypedListAndMap)3536 TEST_F(AidlTest, RejectNestedUntypedListAndMap) {
3537 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<T>;");
3538 io_delegate_.SetFileContents(
3539 "a/Foo.aidl", "package a; import a.Bar; parcelable Foo { Bar<List> a; Bar<Map> b; }");
3540 Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
3541 std::string expectedErr =
3542 "ERROR: a/Foo.aidl:1.52-54: "
3543 "Encountered an untyped List or Map. The use of untyped List/Map is "
3544 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3545 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3546 "ERROR: a/Foo.aidl:1.64-66: "
3547 "Encountered an untyped List or Map. The use of untyped List/Map is "
3548 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3549 "the receiving side. Consider switching to an array or a generic List/Map.\n";
3550 CaptureStderr();
3551 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3552 EXPECT_EQ(expectedErr, GetCapturedStderr());
3553 }
3554
TEST_F(AidlTest,EnumWithDefaults_Java)3555 TEST_F(AidlTest, EnumWithDefaults_Java) {
3556 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3557 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3558 package p;
3559 import p.Enum;
3560 parcelable Foo {
3561 Enum e = Enum.BAR;
3562 })");
3563 CaptureStderr();
3564 auto options = Options::From("aidl -I a --lang java -o out a/p/Foo.aidl");
3565 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3566 auto err = GetCapturedStderr();
3567 EXPECT_EQ("", err);
3568
3569 string code;
3570 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.java", &code));
3571 EXPECT_THAT(code, testing::HasSubstr("byte e = p.Enum.BAR"));
3572 }
3573
TEST_F(AidlTest,EnumWithDefaults_Cpp)3574 TEST_F(AidlTest, EnumWithDefaults_Cpp) {
3575 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3576 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3577 package p;
3578 import p.Enum;
3579 parcelable Foo {
3580 Enum e = Enum.BAR;
3581 })");
3582 CaptureStderr();
3583 auto options = Options::From("aidl -I a --lang cpp -o out -h out a/p/Foo.aidl");
3584 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3585 auto err = GetCapturedStderr();
3586 EXPECT_EQ("", err);
3587
3588 string code;
3589 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.h", &code));
3590 EXPECT_THAT(code, testing::HasSubstr("::p::Enum e = ::p::Enum(::p::Enum::BAR);"));
3591 }
3592
TEST_F(AidlTest,EnumWithDefaults_Ndk)3593 TEST_F(AidlTest, EnumWithDefaults_Ndk) {
3594 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3595 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3596 package p;
3597 import p.Enum;
3598 parcelable Foo {
3599 Enum e = Enum.BAR;
3600 })");
3601 CaptureStderr();
3602 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3603 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3604 auto err = GetCapturedStderr();
3605 EXPECT_EQ("", err);
3606
3607 string code;
3608 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
3609 EXPECT_THAT(code, testing::HasSubstr("::aidl::p::Enum e = ::aidl::p::Enum::BAR;"));
3610 }
3611
TEST_F(AidlTest,EnumWithDefaults_Rust)3612 TEST_F(AidlTest, EnumWithDefaults_Rust) {
3613 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3614 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3615 package p;
3616 import p.Enum;
3617 parcelable Foo {
3618 int n = 42;
3619 Enum e = Enum.BAR;
3620 })");
3621 CaptureStderr();
3622 auto options = Options::From("aidl -I a --lang rust -o out -h out a/p/Foo.aidl");
3623 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3624 auto err = GetCapturedStderr();
3625 EXPECT_EQ("", err);
3626
3627 string code;
3628 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.rs", &code));
3629 EXPECT_THAT(code, testing::HasSubstr(R"(
3630 fn default() -> Self {
3631 Self {
3632 n: 42,
3633 e: crate::mangled::_1_p_4_Enum::BAR,
3634 }
3635 })"));
3636 }
3637
TEST_P(AidlTest,EnumeratorIsConstantValue_DefaultValue)3638 TEST_P(AidlTest, EnumeratorIsConstantValue_DefaultValue) {
3639 import_paths_.insert("a");
3640 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
3641 CaptureStderr();
3642 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
3643 package p;
3644 import p.Enum;
3645 parcelable Foo {
3646 int e = Enum.FOO | Enum.BAR;
3647 })",
3648 typenames_, GetLanguage());
3649 auto err = GetCapturedStderr();
3650 EXPECT_EQ("", err);
3651 EXPECT_TRUE(type);
3652 const auto& fields = type->AsStructuredParcelable()->GetFields();
3653 EXPECT_EQ("int e = 3", fields[0]->ToString());
3654 }
3655
TEST_P(AidlTest,EnumeratorIsConstantValue_CanDefineOtherEnumerator)3656 TEST_P(AidlTest, EnumeratorIsConstantValue_CanDefineOtherEnumerator) {
3657 CaptureStderr();
3658 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
3659 @Backing(type="int")
3660 enum Foo {
3661 STANDARD_SHIFT = 16,
3662 STANDARD_BT709 = 1 << STANDARD_SHIFT,
3663 STANDARD_BT601_625 = 2 << STANDARD_SHIFT,
3664 }
3665 )",
3666 typenames_, GetLanguage());
3667 auto err = GetCapturedStderr();
3668 EXPECT_EQ("", err);
3669 EXPECT_TRUE(type);
3670 const auto& enum_type = type->AsEnumDeclaration();
3671 string code;
3672 auto writer = CodeWriter::ForString(&code);
3673 DumpVisitor visitor(*writer);
3674 visitor.Visit(*enum_type);
3675 writer->Close();
3676 EXPECT_EQ(R"--(@Backing(type="int")
3677 enum Foo {
3678 STANDARD_SHIFT = 16,
3679 STANDARD_BT709 = 65536,
3680 STANDARD_BT601_625 = 131072,
3681 }
3682 )--",
3683 code);
3684 }
3685
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators)3686 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators) {
3687 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
3688 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3689 package p;
3690 import p.Enum;
3691 parcelable Foo {
3692 Enum e = Enum.FOO | Enum.BAR;
3693 })");
3694 CaptureStderr();
3695 auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
3696 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3697 auto err = GetCapturedStderr();
3698 EXPECT_EQ("ERROR: a/p/Foo.aidl:5.11-20: Invalid value (Enum.FOO|Enum.BAR) for enum p.Enum\n",
3699 err);
3700 }
3701
TEST_P(AidlTest,DefaultWithEmptyArray)3702 TEST_P(AidlTest, DefaultWithEmptyArray) {
3703 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; parcelable Foo { p.Bar[] bars = {}; }");
3704 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; parcelable Bar { }");
3705 CaptureStderr();
3706 auto options =
3707 Options::From("aidl -I a --lang " + to_string(GetLanguage()) + " -o out -h out a/p/Foo.aidl");
3708 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3709 auto err = GetCapturedStderr();
3710 EXPECT_EQ("", err);
3711 }
3712
TEST_P(AidlTest,RejectRefsInAnnotation)3713 TEST_P(AidlTest, RejectRefsInAnnotation) {
3714 io_delegate_.SetFileContents("a/p/IFoo.aidl",
3715 "package p; interface IFoo {\n"
3716 " const String ANNOTATION = \"@Annotation\";\n"
3717 " @JavaPassthrough(annotation=ANNOTATION) void foo();\n"
3718 "}");
3719 CaptureStderr();
3720 auto options =
3721 Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out a/p/IFoo.aidl");
3722 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3723 auto err = GetCapturedStderr();
3724 EXPECT_EQ(
3725 "ERROR: a/p/IFoo.aidl:3.31-41: Value must be a constant expression but contains reference to "
3726 "ANNOTATION.\n",
3727 err);
3728 }
3729
TEST_F(AidlTest,DefaultWithEnumValues)3730 TEST_F(AidlTest, DefaultWithEnumValues) {
3731 io_delegate_.SetFileContents(
3732 "a/p/Foo.aidl",
3733 "package p; import p.Bar; parcelable Foo { Bar[] bars = { Bar.FOO, Bar.FOO }; }");
3734 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; enum Bar { FOO, BAR }");
3735 CaptureStderr();
3736 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3737 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3738 auto err = GetCapturedStderr();
3739 EXPECT_EQ("", err);
3740 string code;
3741 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
3742 EXPECT_THAT(
3743 code, testing::HasSubstr(
3744 "std::vector<::aidl::p::Bar> bars = {::aidl::p::Bar::FOO, ::aidl::p::Bar::FOO};"));
3745 }
3746
TEST_F(AidlTest,RejectsCircularReferencingEnumerators)3747 TEST_F(AidlTest, RejectsCircularReferencingEnumerators) {
3748 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; enum Foo { A = B, B }");
3749 CaptureStderr();
3750 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3751 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3752 auto err = GetCapturedStderr();
3753 EXPECT_EQ(
3754 "ERROR: a/p/Foo.aidl:1.26-28: Found a circular reference: B -> A -> B\n"
3755 "ERROR: a/p/Foo.aidl:1.29-31: Found a circular reference: A -> B -> A\n",
3756 err);
3757 }
3758
TEST_F(AidlTest,RejectsCircularReferencingConsts)3759 TEST_F(AidlTest, RejectsCircularReferencingConsts) {
3760 io_delegate_.SetFileContents("a/p/Foo.aidl",
3761 "package p; parcelable Foo { const int A = A + 1; }");
3762 CaptureStderr();
3763 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3764 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3765 auto err = GetCapturedStderr();
3766 EXPECT_EQ("ERROR: a/p/Foo.aidl:1.42-44: Found a circular reference: A -> A\n", err);
3767 }
3768
TEST_F(AidlTest,RecursiveReferences)3769 TEST_F(AidlTest, RecursiveReferences) {
3770 io_delegate_.SetFileContents("a/p/Foo.aidl",
3771 "package p; parcelable Foo { const int A = p.Bar.A + 1; }");
3772 io_delegate_.SetFileContents("a/p/Bar.aidl",
3773 "package p; parcelable Bar { const int A = p.Baz.A + 1; }");
3774 io_delegate_.SetFileContents("a/p/Baz.aidl", "package p; parcelable Baz { const int A = 1; }");
3775 CaptureStderr();
3776 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3777 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3778 EXPECT_EQ("", GetCapturedStderr());
3779 }
3780
TEST_P(AidlTest,UnknownConstReference)3781 TEST_P(AidlTest, UnknownConstReference) {
3782 io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { UnknownType field = UNKNOWN_REF; }");
3783 auto options =
3784 Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
3785 const string err =
3786 "ERROR: Foo.aidl:1.18-30: Failed to resolve 'UnknownType'\n"
3787 "ERROR: Foo.aidl:1.38-50: Can't find UNKNOWN_REF in Foo\n"
3788 "ERROR: Foo.aidl:1.38-50: Unknown reference 'UNKNOWN_REF'\n";
3789 CaptureStderr();
3790 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3791 EXPECT_EQ(err, GetCapturedStderr());
3792 }
3793
TEST_P(AidlTest,JavaCompatibleBuiltinTypes)3794 TEST_P(AidlTest, JavaCompatibleBuiltinTypes) {
3795 string contents = R"(
3796 import android.os.IBinder;
3797 import android.os.IInterface;
3798 interface IFoo {}
3799 )";
3800 EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
3801 }
3802
TEST_P(AidlTest,WarningInterfaceName)3803 TEST_P(AidlTest, WarningInterfaceName) {
3804 io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
3805 auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
3806 " -Weverything -o out -h out p/Foo.aidl");
3807 CaptureStderr();
3808 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3809 EXPECT_EQ("WARNING: p/Foo.aidl:1.1-10: Interface names should start with I. [-Winterface-name]\n",
3810 GetCapturedStderr());
3811 }
3812
TEST_P(AidlTest,ErrorInterfaceName)3813 TEST_P(AidlTest, ErrorInterfaceName) {
3814 io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
3815 auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
3816 " -Weverything -Werror -o out -h out p/Foo.aidl");
3817 CaptureStderr();
3818 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3819 EXPECT_EQ("ERROR: p/Foo.aidl:1.1-10: Interface names should start with I. [-Winterface-name]\n",
3820 GetCapturedStderr());
3821 }
3822
TEST_F(AidlTest,RejectsIncorrectOutputFilePathOnLegacyCppInput)3823 TEST_F(AidlTest, RejectsIncorrectOutputFilePathOnLegacyCppInput) {
3824 const std::string input_file = "base/p/q/IFoo.aidl";
3825 const std::string header_dir = "out/";
3826 const std::string output_file = "out/base/p/q/IFoo.cpp";
3827 const std::string package = "p.q"; // not base.p.q
3828 io_delegate_.SetFileContents(input_file, "package " + package + "; interface IFoo {}");
3829
3830 auto options = Options::From({"aidl-cpp", input_file, header_dir, output_file});
3831 CaptureStderr();
3832 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3833 EXPECT_THAT(
3834 GetCapturedStderr(),
3835 testing::StartsWith(
3836 "ERROR: base/p/q/IFoo.aidl:1.13-23: Output file is expected to be at out/p/q/IFoo.cpp, "
3837 "but is out/base/p/q/IFoo.cpp."));
3838 }
3839
TEST_F(AidlTest,FormatCommentsForJava)3840 TEST_F(AidlTest, FormatCommentsForJava) {
3841 using android::aidl::FormatCommentsForJava;
3842
3843 struct TestCase {
3844 vector<Comment> comments;
3845 string formatted;
3846 };
3847 vector<TestCase> testcases = {
3848 {{}, ""},
3849 {{{"// line comments\n"}}, "// line comments\n"},
3850 {{{"// @hide \n"}}, "// @hide \n"},
3851 // Transform the last block comment as Javadoc.
3852 {{{"/*\n"
3853 " * Hello, world!\n"
3854 " */"}},
3855 "/**\n"
3856 " * Hello, world!\n"
3857 " */"},
3858 {{{"/* @hide */"}}, "/** @hide */"},
3859 {{{"/**\n"
3860 " @param foo ...\n"
3861 "*/"}},
3862 "/**\n"
3863 " @param foo ...\n"
3864 "*/"},
3865 {{{"/* @hide */"}, {"/* @hide */"}}, "/* @hide *//** @hide */"},
3866 {{{"/* @deprecated first */"}, {"/* @deprecated second */"}},
3867 "/* @deprecated first *//** @deprecated second */"},
3868 {{{"/* @deprecated */"}, {"/** @param foo */"}}, "/* @deprecated *//** @param foo */"},
3869 // Line comments are printed as they are
3870 {{{"/* @deprecated */"}, {"// line comments\n"}}, "/* @deprecated */// line comments\n"},
3871 };
3872 for (const auto& [input, formatted] : testcases) {
3873 EXPECT_EQ(formatted, FormatCommentsForJava(input));
3874 }
3875 }
3876
TEST_F(AidlTest,HideIsNotForArgs)3877 TEST_F(AidlTest, HideIsNotForArgs) {
3878 io_delegate_.SetFileContents("IFoo.aidl",
3879 "interface IFoo {\n"
3880 " void foo(in @Hide int x);\n"
3881 "}");
3882 auto options = Options::From("aidl --lang=java IFoo.aidl");
3883 CaptureStderr();
3884 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3885 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@Hide is not available"));
3886 }
3887
TEST_F(AidlTest,SuppressWarningsIsNotForArgs)3888 TEST_F(AidlTest, SuppressWarningsIsNotForArgs) {
3889 io_delegate_.SetFileContents(
3890 "IFoo.aidl",
3891 "interface IFoo {\n"
3892 " void foo(in @SuppressWarnings(value=\"inout-parameter\") int x);\n"
3893 "}");
3894 auto options = Options::From("aidl --lang=java IFoo.aidl");
3895 CaptureStderr();
3896 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3897 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@SuppressWarnings is not available"));
3898 }
3899
3900 struct TypeParam {
3901 string kind;
3902 string literal;
3903 };
3904
3905 const TypeParam kTypeParams[] = {
3906 {"primitive", "int"}, {"primitiveArray", "int[]"},
3907 {"String", "String"}, {"StringArray", "String[]"},
3908 {"IBinder", "IBinder"}, {"ParcelFileDescriptor", "ParcelFileDescriptor"},
3909 {"parcelable", "Foo"}, {"enum", "a.Enum"},
3910 {"union", "a.Union"}, {"interface", "a.IBar"},
3911 };
3912
3913 const std::map<std::string, std::string> kListSupportExpectations = {
3914 {"cpp_primitive", "A generic type cannot have any primitive type parameters."},
3915 {"java_primitive", "A generic type cannot have any primitive type parameters."},
3916 {"ndk_primitive", "A generic type cannot have any primitive type parameters."},
3917 {"rust_primitive", "A generic type cannot have any primitive type parameters."},
3918 {"cpp_primitiveArray", "List of arrays is not supported."},
3919 {"java_primitiveArray", "List of arrays is not supported."},
3920 {"ndk_primitiveArray", "List of arrays is not supported."},
3921 {"rust_primitiveArray", "List of arrays is not supported."},
3922 {"cpp_String", ""},
3923 {"java_String", ""},
3924 {"ndk_String", ""},
3925 {"rust_String", ""},
3926 {"cpp_StringArray", "List of arrays is not supported."},
3927 {"java_StringArray", "List of arrays is not supported."},
3928 {"ndk_StringArray", "List of arrays is not supported."},
3929 {"rust_StringArray", "List of arrays is not supported."},
3930 {"cpp_IBinder", ""},
3931 {"java_IBinder", ""},
3932 {"ndk_IBinder", "List<IBinder> is not supported. List in NDK doesn't support IBinder."},
3933 {"rust_IBinder", ""},
3934 {"cpp_ParcelFileDescriptor", ""},
3935 {"java_ParcelFileDescriptor", ""},
3936 {"ndk_ParcelFileDescriptor", ""},
3937 {"rust_ParcelFileDescriptor", ""},
3938 {"cpp_interface", "List<a.IBar> is not supported."},
3939 {"java_interface", "List<a.IBar> is not supported."},
3940 {"ndk_interface", "List<a.IBar> is not supported."},
3941 {"rust_interface", "List<a.IBar> is not supported."},
3942 {"cpp_parcelable", ""},
3943 {"java_parcelable", ""},
3944 {"ndk_parcelable", ""},
3945 {"rust_parcelable", ""},
3946 {"cpp_enum", "A generic type cannot have any primitive type parameters."},
3947 {"java_enum", "A generic type cannot have any primitive type parameters."},
3948 {"ndk_enum", "A generic type cannot have any primitive type parameters."},
3949 {"rust_enum", "A generic type cannot have any primitive type parameters."},
3950 {"cpp_union", ""},
3951 {"java_union", ""},
3952 {"ndk_union", ""},
3953 {"rust_union", ""},
3954 };
3955
3956 const std::map<std::string, std::string> kArraySupportExpectations = {
3957 {"cpp_primitive", ""},
3958 {"java_primitive", ""},
3959 {"ndk_primitive", ""},
3960 {"rust_primitive", ""},
3961 {"cpp_primitiveArray", "Can only have one dimensional arrays."},
3962 {"java_primitiveArray", "Can only have one dimensional arrays."},
3963 {"ndk_primitiveArray", "Can only have one dimensional arrays."},
3964 {"rust_primitiveArray", "Can only have one dimensional arrays."},
3965 {"cpp_String", ""},
3966 {"java_String", ""},
3967 {"ndk_String", ""},
3968 {"rust_String", ""},
3969 {"cpp_StringArray", "Can only have one dimensional arrays."},
3970 {"java_StringArray", "Can only have one dimensional arrays."},
3971 {"ndk_StringArray", "Can only have one dimensional arrays."},
3972 {"rust_StringArray", "Can only have one dimensional arrays."},
3973 {"cpp_IBinder", ""},
3974 {"java_IBinder", ""},
3975 {"ndk_IBinder", "The ndk backend does not support array of IBinder"},
3976 {"rust_IBinder", "The rust backend does not support array of IBinder"},
3977 {"cpp_ParcelFileDescriptor", ""},
3978 {"java_ParcelFileDescriptor", ""},
3979 {"ndk_ParcelFileDescriptor", ""},
3980 {"rust_ParcelFileDescriptor", ""},
3981 {"cpp_interface", "Binder type cannot be an array"},
3982 {"java_interface", "Binder type cannot be an array"},
3983 {"ndk_interface", "Binder type cannot be an array"},
3984 {"rust_interface", "Binder type cannot be an array"},
3985 {"cpp_parcelable", ""},
3986 {"java_parcelable", ""},
3987 {"ndk_parcelable", ""},
3988 {"rust_parcelable", ""},
3989 {"cpp_enum", ""},
3990 {"java_enum", ""},
3991 {"ndk_enum", ""},
3992 {"rust_enum", ""},
3993 {"cpp_union", ""},
3994 {"java_union", ""},
3995 {"ndk_union", ""},
3996 {"rust_union", ""},
3997 };
3998
3999 class AidlTypeParamTest : public testing::TestWithParam<std::tuple<Options::Language, TypeParam>> {
4000 public:
Run(const std::string & generic_type_decl,const std::map<std::string,std::string> & expectations)4001 void Run(const std::string& generic_type_decl,
4002 const std::map<std::string, std::string>& expectations) {
4003 const auto& param = GetParam();
4004 const auto& lang = to_string(std::get<0>(param));
4005 const auto& kind = std::get<1>(param).kind;
4006
4007 FakeIoDelegate io;
4008 io.SetFileContents("a/IBar.aidl", "package a; interface IBar { }");
4009 io.SetFileContents("a/Enum.aidl", "package a; enum Enum { A }");
4010 io.SetFileContents("a/Union.aidl", "package a; union Union { int a; }");
4011 std::string decl = fmt::format(generic_type_decl, std::get<1>(param).literal);
4012 io.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { " + decl + " f; }");
4013
4014 const auto options =
4015 Options::From(fmt::format("aidl -I . --lang={} a/Foo.aidl -o out -h out", lang));
4016 CaptureStderr();
4017 compile_aidl(options, io);
4018 auto it = expectations.find(lang + "_" + kind);
4019 EXPECT_TRUE(it != expectations.end());
4020 const string err = GetCapturedStderr();
4021 if (it->second.empty()) {
4022 EXPECT_EQ("", err);
4023 } else {
4024 EXPECT_THAT(err, testing::HasSubstr(it->second));
4025 }
4026 }
4027 };
4028
4029 INSTANTIATE_TEST_SUITE_P(
4030 AidlTestSuite, AidlTypeParamTest,
4031 testing::Combine(testing::Values(Options::Language::CPP, Options::Language::JAVA,
4032 Options::Language::NDK, Options::Language::RUST),
4033 testing::ValuesIn(kTypeParams)),
__anon758595f20402(const testing::TestParamInfo<std::tuple<Options::Language, TypeParam>>& info) 4034 [](const testing::TestParamInfo<std::tuple<Options::Language, TypeParam>>& info) {
4035 return to_string(std::get<0>(info.param)) + "_" + std::get<1>(info.param).kind;
4036 });
4037
TEST_P(AidlTypeParamTest,ListSupportedTypes)4038 TEST_P(AidlTypeParamTest, ListSupportedTypes) {
4039 Run("List<{}>", kListSupportExpectations);
4040 }
4041
TEST_P(AidlTypeParamTest,ArraySupportedTypes)4042 TEST_P(AidlTypeParamTest, ArraySupportedTypes) {
4043 Run("{}[]", kArraySupportExpectations);
4044 }
4045
4046 } // namespace aidl
4047 } // namespace android
4048