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 <variant>
29 #include <vector>
30
31 #include "aidl_checkapi.h"
32 #include "aidl_dumpapi.h"
33 #include "aidl_language.h"
34 #include "aidl_to_cpp.h"
35 #include "aidl_to_cpp_common.h"
36 #include "aidl_to_java.h"
37 #include "aidl_to_ndk.h"
38 #include "aidl_to_rust.h"
39 #include "comments.h"
40 #include "logging.h"
41 #include "options.h"
42 #include "parser.h"
43 #include "preprocess.h"
44 #include "tests/fake_io_delegate.h"
45
46 using android::aidl::test::FakeIoDelegate;
47 using android::base::StringPrintf;
48 using std::map;
49 using std::set;
50 using std::string;
51 using std::unique_ptr;
52 using std::variant;
53 using std::vector;
54 using testing::HasSubstr;
55 using testing::TestParamInfo;
56 using testing::internal::CaptureStderr;
57 using testing::internal::GetCapturedStderr;
58
59 namespace android {
60 namespace aidl {
61 namespace {
62
63 const char kExpectedDepFileContents[] =
64 R"(place/for/output/p/IFoo.java : \
65 p/IFoo.aidl
66
67 p/IFoo.aidl :
68 )";
69
70 const char kExpectedNinjaDepFileContents[] =
71 R"(place/for/output/p/IFoo.java : \
72 p/IFoo.aidl
73 )";
74
75 const char kExpectedParcelableDeclarationDepFileContents[] =
76 R"( : \
77 p/Foo.aidl
78
79 p/Foo.aidl :
80 )";
81
82 const char kExpectedStructuredParcelableDepFileContents[] =
83 R"(place/for/output/p/Foo.java : \
84 p/Foo.aidl
85
86 p/Foo.aidl :
87 )";
88
89 } // namespace
90
91 const string INVALID_INT8_VALUE = "Invalid type specifier for an int8 literal";
92 const string INVALID_FLOAT_VALUE = "Invalid type specifier for a literal float";
93 const string INVALID_OPERATION = "Cannot perform operation";
94
95 class AidlTest : public ::testing::TestWithParam<Options::Language> {
96 protected:
Parse(const string & path,const string & contents,AidlTypenames & typenames_,Options::Language lang,AidlError * error=nullptr,const vector<string> additional_arguments={})97 AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
98 Options::Language lang, AidlError* error = nullptr,
99 const vector<string> additional_arguments = {}) {
100 io_delegate_.SetFileContents(path, contents);
101 vector<string> args;
102 args.emplace_back("aidl");
103 args.emplace_back("--min_sdk_version=current");
104 args.emplace_back("--lang=" + to_string(lang));
105 for (const string& s : additional_arguments) {
106 args.emplace_back(s);
107 }
108 for (const string& f : preprocessed_files_) {
109 args.emplace_back("--preprocessed=" + f);
110 }
111 args.emplace_back("--include=.");
112 for (const string& i : import_paths_) {
113 args.emplace_back("--include=" + i);
114 }
115 args.emplace_back(path);
116 Options options = Options::From(args);
117 vector<string> imported_files;
118 ImportResolver import_resolver{io_delegate_, path, import_paths_};
119 AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
120 path, options, io_delegate_, &typenames_, &imported_files);
121
122 if (error != nullptr) {
123 *error = actual_error;
124 }
125
126 if (actual_error != AidlError::OK) {
127 return nullptr;
128 }
129
130 const auto& defined_types = typenames_.MainDocument().DefinedTypes();
131 EXPECT_EQ(1ul, defined_types.size());
132
133 return defined_types.front().get();
134 }
135
EvaluateInvalidAssignment(string content,string expected_stderr,AidlTypenames & typenames_,Options::Language lang)136 void EvaluateInvalidAssignment(string content, string expected_stderr, AidlTypenames& typenames_,
137 Options::Language lang) {
138 AidlError error;
139 CaptureStderr();
140 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", content, typenames_, lang, &error));
141 EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
142 };
143
EvaluateValidAssignment(string content,string expected_stderr,AidlTypenames & typenames_,Options::Language lang)144 void EvaluateValidAssignment(string content, string expected_stderr, AidlTypenames& typenames_,
145 Options::Language lang) {
146 AidlError error;
147 CaptureStderr();
148 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", content, typenames_, lang, &error));
149 EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
150 };
151
GetLanguage()152 Options::Language GetLanguage() { return GetParam(); }
153
154 FakeIoDelegate io_delegate_;
155 vector<string> preprocessed_files_;
156 set<string> import_paths_;
157 AidlTypenames typenames_;
158 };
159
160 // Instantiate the AidlTest parameterized suite, calling all of the TEST_P
161 // tests with each of the supported languages as a parameter.
162 INSTANTIATE_TEST_SUITE_P(AidlTestSuite, AidlTest,
163 testing::Values(Options::Language::CPP, Options::Language::JAVA,
164 Options::Language::NDK, Options::Language::RUST),
__anon0e32cfeb0202(const testing::TestParamInfo<Options::Language>& info) 165 [](const testing::TestParamInfo<Options::Language>& info) {
166 return to_string(info.param);
167 });
168
TEST_P(AidlTest,AcceptMissingPackage)169 TEST_P(AidlTest, AcceptMissingPackage) {
170 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, GetLanguage()));
171 }
172
TEST_P(AidlTest,EndsInSingleLineComment)173 TEST_P(AidlTest, EndsInSingleLineComment) {
174 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, GetLanguage()));
175 }
176
TEST_P(AidlTest,InterfaceRequiresCorrectPath)177 TEST_P(AidlTest, InterfaceRequiresCorrectPath) {
178 const string expected_stderr =
179 "ERROR: a/Foo.aidl:1.11-21: IBar should be declared in a file called a/IBar.aidl\n";
180 const std::string file_contents = "package a; interface IBar {}";
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,ParcelableRequiresCorrectPath)186 TEST_P(AidlTest, ParcelableRequiresCorrectPath) {
187 const string expected_stderr =
188 "ERROR: a/Foo.aidl:1.11-21: Bar should be declared in a file called a/Bar.aidl\n";
189 const std::string file_contents = "package a; interface Bar {}";
190 CaptureStderr();
191 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
192 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
193 }
194
TEST_P(AidlTest,UnstructuredParcelableRequiresCorrectPath)195 TEST_P(AidlTest, UnstructuredParcelableRequiresCorrectPath) {
196 const string expected_stderr =
197 "ERROR: a/Foo.aidl:1.22-26: Bar should be declared in a file called a/Bar.aidl\n";
198 const std::string file_contents = "package a; parcelable Bar cpp_header \"anything.h\";";
199 CaptureStderr();
200 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
201 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
202 }
203
TEST_P(AidlTest,EnumRequiresCorrectPath)204 TEST_P(AidlTest, EnumRequiresCorrectPath) {
205 const string expected_stderr =
206 "ERROR: a/Foo.aidl:1.16-20: Bar should be declared in a file called a/Bar.aidl\n";
207 const std::string file_contents = "package a; enum Bar { A, }";
208 CaptureStderr();
209 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
210 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
211 }
212
TEST_P(AidlTest,SupportOnlyOutParameters)213 TEST_P(AidlTest, SupportOnlyOutParameters) {
214 const string interface_list = "package a; interface IBar { void f(out List<String> bar); }";
215 EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, GetLanguage()));
216 }
217
TEST_P(AidlTest,RejectOutParametersForIBinder)218 TEST_P(AidlTest, RejectOutParametersForIBinder) {
219 const string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
220 const string expected_ibinder_stderr =
221 "ERROR: a/IBaz.aidl:1.47-51: 'bar' can't be an out parameter because IBinder can only be an "
222 "in parameter.\n";
223 CaptureStderr();
224 EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, GetLanguage()));
225 EXPECT_EQ(expected_ibinder_stderr, GetCapturedStderr());
226 }
227
TEST_P(AidlTest,RejectsOutParametersInOnewayInterface)228 TEST_P(AidlTest, RejectsOutParametersInOnewayInterface) {
229 const string oneway_interface = "package a; oneway interface IBar { void f(out int[] bar); }";
230 const string expected_stderr =
231 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
232 CaptureStderr();
233 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
234 EXPECT_EQ(expected_stderr, GetCapturedStderr());
235 }
236
TEST_P(AidlTest,RejectsOutParametersInOnewayMethod)237 TEST_P(AidlTest, RejectsOutParametersInOnewayMethod) {
238 const string oneway_method = "package a; interface IBar { oneway void f(out int[] bar); }";
239 const string expected_stderr =
240 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
241 CaptureStderr();
242 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, GetLanguage()));
243 EXPECT_EQ(expected_stderr, GetCapturedStderr());
244 }
245
TEST_P(AidlTest,RejectsOnewayNonVoidReturn)246 TEST_P(AidlTest, RejectsOnewayNonVoidReturn) {
247 const string oneway_method = "package a; interface IFoo { oneway int f(); }";
248 const string expected_stderr =
249 "ERROR: a/IFoo.aidl:1.39-41: oneway method 'f' cannot return a value\n";
250 CaptureStderr();
251 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
252 EXPECT_EQ(expected_stderr, GetCapturedStderr());
253 }
254
TEST_P(AidlTest,RejectsNullablePrimitive)255 TEST_P(AidlTest, RejectsNullablePrimitive) {
256 const string oneway_method = "package a; interface IFoo { @nullable int f(); }";
257 const string expected_stderr =
258 "ERROR: a/IFoo.aidl:1.38-42: Primitive type cannot get nullable annotation\n";
259 CaptureStderr();
260 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
261 EXPECT_EQ(expected_stderr, GetCapturedStderr());
262 }
263
TEST_P(AidlTest,AcceptNullableList)264 TEST_P(AidlTest, AcceptNullableList) {
265 const string oneway_method = "package a; interface IFoo { @nullable List<String> f(); }";
266 const string expected_stderr = "";
267 CaptureStderr();
268 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
269 EXPECT_EQ(expected_stderr, GetCapturedStderr());
270 }
271
TEST_P(AidlTest,RejectRecursiveParcelable)272 TEST_P(AidlTest, RejectRecursiveParcelable) {
273 CaptureStderr();
274 EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo { Foo foo; }", typenames_, GetLanguage()));
275 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Foo is a recursive parcelable"));
276 }
277
TEST_P(AidlTest,RejectIndirectRecursiveParcelable)278 TEST_P(AidlTest, RejectIndirectRecursiveParcelable) {
279 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { Foo foo; }");
280 import_paths_.emplace("");
281 CaptureStderr();
282 EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo { Bar bar; }", typenames_, GetLanguage()));
283 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Foo is a recursive parcelable"));
284 }
285
TEST_P(AidlTest,RejectRecursiveTypeEvenIfNullable)286 TEST_P(AidlTest, RejectRecursiveTypeEvenIfNullable) {
287 // Note: in native backends @nullable is mapped to non-heap wrapper like std::optional/Option<T>
288 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { @nullable Foo foo; }");
289 import_paths_.emplace("");
290 CaptureStderr();
291 EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo { Bar bar; }", typenames_, GetLanguage()));
292 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Foo is a recursive parcelable"));
293 }
294
TEST_P(AidlTest,OkayIfRecursionInvolvesHeapType)295 TEST_P(AidlTest, OkayIfRecursionInvolvesHeapType) {
296 CaptureStderr();
297 std::string java_only_map_field;
298 if (GetLanguage() == Options::Language::JAVA) {
299 java_only_map_field = " Map<String, Foo> map;\n";
300 }
301 EXPECT_NE(nullptr, Parse("Foo.aidl",
302 "parcelable Foo {\n"
303 " List<Foo> list;\n" +
304 java_only_map_field +
305 " Foo[] arr;\n"
306 " @nullable(heap=true) Foo heap_nullable;\n"
307 "}\n",
308 typenames_, GetLanguage()));
309 EXPECT_THAT(GetCapturedStderr(), "");
310 }
311
TEST_P(AidlTest,InterfaceCanReferenceItself)312 TEST_P(AidlTest, InterfaceCanReferenceItself) {
313 CaptureStderr();
314 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { void foo(in IFoo self); }", typenames_,
315 GetLanguage()));
316 EXPECT_THAT(GetCapturedStderr(), "");
317 }
318
TEST_P(AidlTest,HeapNullableCantApplyToOtherThanParcelables)319 TEST_P(AidlTest, HeapNullableCantApplyToOtherThanParcelables) {
320 CaptureStderr();
321 EXPECT_EQ(nullptr, Parse("Foo.aidl",
322 "parcelable Foo {\n"
323 " @nullable(heap=true) String s;\n"
324 "}",
325 typenames_, GetLanguage()));
326 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable(heap=true) is available to parcelables"));
327 }
328
TEST_P(AidlTest,RejectsDuplicatedArgumentNames)329 TEST_P(AidlTest, RejectsDuplicatedArgumentNames) {
330 const string method = "package a; interface IFoo { void f(int a, int a); }";
331 const string expected_stderr =
332 "ERROR: a/IFoo.aidl:1.33-35: method 'f' has duplicate argument name 'a'\n";
333 CaptureStderr();
334 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
335 EXPECT_EQ(expected_stderr, GetCapturedStderr());
336 }
337
TEST_P(AidlTest,RejectsDuplicatedFieldNames)338 TEST_P(AidlTest, RejectsDuplicatedFieldNames) {
339 const string method = "package a; parcelable Foo { int a; String a; }";
340 const string expected_stderr = "ERROR: a/Foo.aidl:1.42-44: 'Foo' has duplicate field name 'a'\n";
341 CaptureStderr();
342 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
343 EXPECT_EQ(expected_stderr, GetCapturedStderr());
344 }
345
TEST_P(AidlTest,AcceptsEmptyParcelable)346 TEST_P(AidlTest, AcceptsEmptyParcelable) {
347 CaptureStderr();
348 EXPECT_NE(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage()));
349 EXPECT_EQ("", GetCapturedStderr());
350 }
351
TEST_P(AidlTest,RejectsDuplicatedAnnotationParams)352 TEST_P(AidlTest, RejectsDuplicatedAnnotationParams) {
353 const string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
354 const string expected_stderr = "ERROR: a/IFoo.aidl:1.56-62: Trying to redefine parameter foo.\n";
355 CaptureStderr();
356 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
357 EXPECT_EQ(expected_stderr, GetCapturedStderr());
358 }
359
TEST_P(AidlTest,RejectUnsupportedInterfaceAnnotations)360 TEST_P(AidlTest, RejectUnsupportedInterfaceAnnotations) {
361 AidlError error;
362 const string method = "package a; @nullable interface IFoo { int f(); }";
363 CaptureStderr();
364 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
365 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
366 EXPECT_EQ(AidlError::BAD_TYPE, error);
367 }
368
TEST_P(AidlTest,RejectUnsupportedTypeAnnotations)369 TEST_P(AidlTest, RejectUnsupportedTypeAnnotations) {
370 AidlError error;
371 const string method = "package a; interface IFoo { @JavaOnlyStableParcelable int f(); }";
372 CaptureStderr();
373 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
374 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaOnlyStableParcelable is not available."));
375 EXPECT_EQ(AidlError::BAD_TYPE, error);
376 }
377
TEST_P(AidlTest,RejectUnsupportedParcelableDefineAnnotations)378 TEST_P(AidlTest, RejectUnsupportedParcelableDefineAnnotations) {
379 AidlError error;
380 const string method = "package a; @nullable parcelable Foo { String a; String b; }";
381 CaptureStderr();
382 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage(), &error));
383 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
384 EXPECT_EQ(AidlError::BAD_TYPE, error);
385 }
386
TEST_P(AidlTest,ParsesNonNullableAnnotation)387 TEST_P(AidlTest, ParsesNonNullableAnnotation) {
388 auto parse_result =
389 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
390 ASSERT_NE(nullptr, parse_result);
391 const AidlInterface* interface = parse_result->AsInterface();
392 ASSERT_NE(nullptr, interface);
393 ASSERT_FALSE(interface->GetMethods().empty());
394 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsNullable());
395 }
396
TEST_P(AidlTest,ParsesNullableAnnotation)397 TEST_P(AidlTest, ParsesNullableAnnotation) {
398 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @nullable String f(); }",
399 typenames_, GetLanguage());
400 ASSERT_NE(nullptr, parse_result);
401 const AidlInterface* interface = parse_result->AsInterface();
402 ASSERT_NE(nullptr, interface);
403 ASSERT_FALSE(interface->GetMethods().empty());
404 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsNullable());
405 }
406
TEST_P(AidlTest,ParsesNonUtf8Annotations)407 TEST_P(AidlTest, ParsesNonUtf8Annotations) {
408 auto parse_result =
409 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
410 ASSERT_NE(nullptr, parse_result);
411 const AidlInterface* interface = parse_result->AsInterface();
412 ASSERT_NE(nullptr, interface);
413 ASSERT_FALSE(interface->GetMethods().empty());
414 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
415 }
416
TEST_P(AidlTest,ParsesUtf8Annotations)417 TEST_P(AidlTest, ParsesUtf8Annotations) {
418 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @utf8InCpp String f(); }",
419 typenames_, GetLanguage());
420 ASSERT_NE(nullptr, parse_result);
421 const AidlInterface* interface = parse_result->AsInterface();
422 ASSERT_NE(nullptr, interface);
423 ASSERT_FALSE(interface->GetMethods().empty());
424 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
425 }
426
TEST_P(AidlTest,VintfRequiresStructuredAndStability)427 TEST_P(AidlTest, VintfRequiresStructuredAndStability) {
428 AidlError error;
429 const string expected_stderr =
430 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
431 "\"vintf\"'\n"
432 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
433 "--structured\n";
434 CaptureStderr();
435 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
436 GetLanguage(), &error));
437 EXPECT_EQ(expected_stderr, GetCapturedStderr());
438 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
439 }
440
TEST_P(AidlTest,VintfRequiresStructured)441 TEST_P(AidlTest, VintfRequiresStructured) {
442 AidlError error;
443 const string expected_stderr =
444 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
445 "--structured\n";
446 CaptureStderr();
447 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
448 GetLanguage(), &error, {"--stability", "vintf"}));
449 EXPECT_EQ(expected_stderr, GetCapturedStderr());
450 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
451 }
452
TEST_P(AidlTest,VintfRequiresSpecifiedStability)453 TEST_P(AidlTest, VintfRequiresSpecifiedStability) {
454 AidlError error;
455 const string expected_stderr =
456 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
457 "\"vintf\"'\n";
458 CaptureStderr();
459 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
460 GetLanguage(), &error, {"--structured"}));
461 EXPECT_EQ(expected_stderr, GetCapturedStderr());
462 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
463 }
464
TEST_P(AidlTest,ParsesStabilityAnnotations)465 TEST_P(AidlTest, ParsesStabilityAnnotations) {
466 AidlError error;
467 auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
468 GetLanguage(), &error, {"--structured", "--stability", "vintf"});
469 ASSERT_EQ(AidlError::OK, error);
470 ASSERT_NE(nullptr, parse_result);
471 const AidlInterface* interface = parse_result->AsInterface();
472 ASSERT_NE(nullptr, interface);
473 ASSERT_TRUE(interface->IsVintfStability());
474 }
475
TEST_P(AidlTest,TypesShouldHaveVintfStabilityWhenCompilingWithTheVintfFlag)476 TEST_P(AidlTest, TypesShouldHaveVintfStabilityWhenCompilingWithTheVintfFlag) {
477 CaptureStderr();
478 string code =
479 "@VintfStability\n"
480 "parcelable Foo {\n"
481 " interface INested { interface INastyNester {} }"
482 "}";
483 EXPECT_NE(nullptr, Parse("Foo.aidl", code, typenames_, GetLanguage(), nullptr,
484 {"--structured", "--stability", "vintf"}));
485 EXPECT_EQ(GetCapturedStderr(), "");
486 auto nested = typenames_.TryGetDefinedType("Foo.INested");
487 ASSERT_NE(nullptr, nested);
488 ASSERT_TRUE(nested->IsVintfStability());
489
490 auto nastyNester = typenames_.TryGetDefinedType("Foo.INested.INastyNester");
491 ASSERT_NE(nullptr, nastyNester);
492 ASSERT_TRUE(nastyNester->IsVintfStability());
493 }
494
TEST_P(AidlTest,VintfStabilityAppliesToNestedTypesAsWell)495 TEST_P(AidlTest, VintfStabilityAppliesToNestedTypesAsWell) {
496 CaptureStderr();
497 EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage(), nullptr,
498 {"--structured", "--stability", "vintf"}));
499 EXPECT_THAT(GetCapturedStderr(),
500 HasSubstr("Foo does not have VINTF level stability (marked @VintfStability)"));
501 }
502
TEST_F(AidlTest,ParsesJavaOnlyStableParcelable)503 TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
504 Options java_options = Options::From("aidl -I . -o out --structured a/Foo.aidl");
505 Options cpp_options = Options::From("aidl -I . --lang=cpp -o out -h out/include a/Foo.aidl");
506 Options cpp_structured_options =
507 Options::From("aidl --lang=cpp -I . --structured -o out -h out/include a/Foo.aidl");
508 Options rust_options = Options::From("aidl -I . --lang=rust -o out --structured a/Foo.aidl");
509 io_delegate_.SetFileContents(
510 "a/Foo.aidl",
511 StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
512
513 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
514 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
515
516 CaptureStderr();
517 EXPECT_FALSE(compile_aidl(cpp_structured_options, io_delegate_));
518 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
519
520 CaptureStderr();
521 EXPECT_FALSE(compile_aidl(rust_options, io_delegate_));
522 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
523 }
524
TEST_F(AidlTest,ParsesNdkOnlyStableParcelable)525 TEST_F(AidlTest, ParsesNdkOnlyStableParcelable) {
526 Options java_options = Options::From("aidl -I . -o out --structured a/Foo.aidl");
527 Options ndk_structured_options =
528 Options::From("aidl --lang=ndk --structured -I . -o out -h out/include a/Foo.aidl");
529 Options rust_options = Options::From("aidl --lang=rust -I . -o out --structured a/Foo.aidl");
530 Options cpp_options = Options::From("aidl --lang=cpp -I . -o out -h out/include a/Foo.aidl");
531 io_delegate_.SetFileContents(
532 "a/Foo.aidl",
533 StringPrintf("package a; @NdkOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
534
535 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
536
537 // not considered unstructured, but it still can't be compiled directly with
538 // --structured AIDL - it can only be used as an import
539 CaptureStderr();
540 EXPECT_FALSE(compile_aidl(ndk_structured_options, io_delegate_));
541 EXPECT_THAT(GetCapturedStderr(),
542 HasSubstr("Refusing to generate code with unstructured parcelables"));
543
544 CaptureStderr();
545 EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
546 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
547
548 CaptureStderr();
549 EXPECT_FALSE(compile_aidl(rust_options, io_delegate_));
550 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
551 }
552
TEST_P(AidlTest,NdkAndJavaStabilityIsVintfStable)553 TEST_P(AidlTest, NdkAndJavaStabilityIsVintfStable) {
554 CaptureStderr();
555
556 io_delegate_.SetFileContents("NonPortableThing.aidl",
557 "@NdkOnlyStableParcelable @JavaOnlyStableParcelable parcelable "
558 "NonPortableThing ndk_header \"lol.h\" cpp_header \"lolol.h\";");
559 import_paths_.emplace("");
560
561 auto result =
562 Parse("IFoo.aidl",
563 "import NonPortableThing; @VintfStability interface IFoo { NonPortableThing get(); }",
564 typenames_, GetLanguage(), nullptr, {"--structured", "--stability", "vintf"});
565
566 if (GetLanguage() == Options::Language::NDK || GetLanguage() == Options::Language::JAVA) {
567 EXPECT_NE(result, nullptr);
568 EXPECT_EQ(GetCapturedStderr(), "");
569 } else {
570 EXPECT_EQ(result, nullptr);
571 EXPECT_THAT(
572 GetCapturedStderr(),
573 HasSubstr("NonPortableThing does not have VINTF level stability (marked @VintfStability)"));
574 }
575 }
576
TEST_F(AidlTest,ParcelableSupportJavaDeriveToString)577 TEST_F(AidlTest, ParcelableSupportJavaDeriveToString) {
578 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
579 @JavaDerive(toString=true) parcelable Foo { int a; float b; })");
580 Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
581 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
582
583 string java_out;
584 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
585 EXPECT_THAT(java_out, testing::HasSubstr("public String toString() {"));
586
587 // Other backends shouldn't be bothered
588 Options cpp_options = Options::From("aidl --lang=cpp -I . -o out -h out a/Foo.aidl");
589 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
590
591 Options ndk_options = Options::From("aidl --lang=ndk -I . -o out -h out a/Foo.aidl");
592 EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
593 }
594
TEST_F(AidlTest,UnionSupportJavaDeriveToString)595 TEST_F(AidlTest, UnionSupportJavaDeriveToString) {
596 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
597 @JavaDerive(toString=true) union Foo { int a; int[] b; })");
598 CaptureStderr();
599 Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
600 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
601 EXPECT_EQ("", GetCapturedStderr());
602
603 const string expected_to_string_method = R"--(
604 @Override
605 public String toString() {
606 switch (_tag) {
607 case a: return "a.Foo.a(" + (getA()) + ")";
608 case b: return "a.Foo.b(" + (java.util.Arrays.toString(getB())) + ")";
609 }
610 throw new IllegalStateException("unknown field: " + _tag);
611 }
612 )--";
613
614 string java_out;
615 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
616 EXPECT_THAT(java_out, testing::HasSubstr(expected_to_string_method));
617 }
618
TEST_F(AidlTest,ParcelableSupportJavaDeriveEquals)619 TEST_F(AidlTest, ParcelableSupportJavaDeriveEquals) {
620 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
621 @JavaDerive(equals=true) parcelable Foo { int a; float b; })");
622 CaptureStderr();
623 Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
624 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
625 EXPECT_EQ("", GetCapturedStderr());
626
627 const std::string expected = R"--(
628 @Override
629 public boolean equals(Object other) {
630 if (this == other) return true;
631 if (other == null) return false;
632 if (!(other instanceof Foo)) return false;
633 Foo that = (Foo)other;
634 if (!java.util.Objects.deepEquals(a, that.a)) return false;
635 if (!java.util.Objects.deepEquals(b, that.b)) return false;
636 return true;
637 }
638
639 @Override
640 public int hashCode() {
641 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(a, b).toArray());
642 }
643 )--";
644
645 string java_out;
646 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
647 EXPECT_THAT(java_out, testing::HasSubstr(expected));
648 }
649
TEST_F(AidlTest,UnionSupportJavaDeriveEquals)650 TEST_F(AidlTest, UnionSupportJavaDeriveEquals) {
651 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
652 @JavaDerive(equals=true) union Foo { int a; int[] b; })");
653 CaptureStderr();
654 Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
655 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
656 EXPECT_EQ("", GetCapturedStderr());
657
658 const std::string expected = R"--(
659 @Override
660 public boolean equals(Object other) {
661 if (this == other) return true;
662 if (other == null) return false;
663 if (!(other instanceof Foo)) return false;
664 Foo that = (Foo)other;
665 if (_tag != that._tag) return false;
666 if (!java.util.Objects.deepEquals(_value, that._value)) return false;
667 return true;
668 }
669
670 @Override
671 public int hashCode() {
672 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(_tag, _value).toArray());
673 }
674 )--";
675
676 string java_out;
677 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
678 EXPECT_THAT(java_out, testing::HasSubstr(expected));
679 }
680
TEST_F(AidlTest,RejectsJavaDeriveAnnotation)681 TEST_F(AidlTest, RejectsJavaDeriveAnnotation) {
682 {
683 io_delegate_.SetFileContents("a/Foo.aidl",
684 "package a; @JavaDerive(blah=true) parcelable Foo{}");
685 Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
686 CaptureStderr();
687 EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
688 const std::string expected_stderr =
689 "ERROR: a/Foo.aidl:1.11-34: Parameter blah not supported for annotation JavaDerive.";
690 EXPECT_THAT(GetCapturedStderr(),
691 HasSubstr("Parameter blah not supported for annotation JavaDerive."));
692 }
693
694 {
695 io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive interface IFoo{}");
696 Options java_options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
697 CaptureStderr();
698 EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
699 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
700 }
701 }
702
TEST_P(AidlTest,ParseDescriptorAnnotation)703 TEST_P(AidlTest, ParseDescriptorAnnotation) {
704 AidlError error;
705 auto parse_result = Parse("IFoo.aidl", R"(@Descriptor(value="IBar") interface IFoo{})",
706 typenames_, GetLanguage(), &error, {"--structured"});
707 ASSERT_EQ(AidlError::OK, error);
708 ASSERT_NE(nullptr, parse_result);
709 const AidlInterface* interface = parse_result->AsInterface();
710 ASSERT_NE(nullptr, interface);
711 ASSERT_EQ("IBar", interface->GetDescriptor());
712 }
713
TEST_P(AidlTest,UnknownAnnotation)714 TEST_P(AidlTest, UnknownAnnotation) {
715 CaptureStderr();
716 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", "package a; @Unknown interface IFoo { }", typenames_,
717 GetLanguage()));
718 EXPECT_THAT(GetCapturedStderr(), HasSubstr("not a recognized annotation"));
719
720 CaptureStderr();
721 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", "package a; @Unknown(param=true) interface IFoo { }",
722 typenames_, GetLanguage()));
723 EXPECT_THAT(GetCapturedStderr(), HasSubstr("not a recognized annotation"));
724 }
725
TEST_P(AidlTest,AcceptsOnewayMethod)726 TEST_P(AidlTest, AcceptsOnewayMethod) {
727 const string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
728 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
729 }
730
TEST_P(AidlTest,AcceptsOnewayInterface)731 TEST_P(AidlTest, AcceptsOnewayInterface) {
732 const string oneway_interface = "package a; oneway interface IBar { void f(int a); }";
733 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
734 }
735
TEST_P(AidlTest,AcceptsAnnotatedOnewayMethod)736 TEST_P(AidlTest, AcceptsAnnotatedOnewayMethod) {
737 const string oneway_method =
738 "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
739 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
740 }
741
TEST_P(AidlTest,AnnotationsInMultiplePlaces)742 TEST_P(AidlTest, AnnotationsInMultiplePlaces) {
743 const string oneway_method =
744 "package a; interface IFoo { @UnsupportedAppUsage oneway @PropagateAllowBlocking void f(int "
745 "a); }";
746 const AidlDefinedType* defined = Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage());
747 ASSERT_NE(nullptr, defined);
748 const AidlInterface* iface = defined->AsInterface();
749 ASSERT_NE(nullptr, iface);
750
751 const auto& methods = iface->GetMethods();
752 ASSERT_EQ(1u, methods.size());
753 const auto& method = methods[0];
754 const AidlTypeSpecifier& ret_type = method->GetType();
755
756 // TODO(b/151102494): these annotations should be on the method
757 ASSERT_NE(nullptr, ret_type.UnsupportedAppUsage());
758 ASSERT_TRUE(ret_type.IsPropagateAllowBlocking());
759 }
760
TEST_P(AidlTest,AnnotationValueAttribute)761 TEST_P(AidlTest, AnnotationValueAttribute) {
762 const string content =
763 "package a; @Descriptor(\"descriptor_value\") interface IFoo { void f(int a); }";
764 const AidlDefinedType* defined = Parse("a/IFoo.aidl", content, typenames_, GetLanguage());
765 ASSERT_NE(nullptr, defined);
766 const AidlInterface* iface = defined->AsInterface();
767 ASSERT_NE(nullptr, iface);
768
769 ASSERT_EQ("descriptor_value", iface->GetDescriptor());
770 }
771
TEST_F(AidlTest,CheckApiForAnnotationValueAttribute)772 TEST_F(AidlTest, CheckApiForAnnotationValueAttribute) {
773 Options options = Options::From("aidl --checkapi=equal old new");
774
775 io_delegate_.SetFileContents("old/p/IFoo.aidl",
776 "package p; @Descriptor(value=\"v1\") interface IFoo{ void foo();}");
777 io_delegate_.SetFileContents("new/p/IFoo.aidl",
778 "package p; @Descriptor(\"v1\") interface IFoo{ void foo();}");
779
780 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
781 }
782
TEST_P(AidlTest,WritesComments)783 TEST_P(AidlTest, WritesComments) {
784 string foo_interface =
785 R"(package a;
786 /* foo */
787 interface IFoo {
788 /* i */
789 int i();
790 // j
791 @nullable String j();
792 // k1
793 /* k2 */
794 @UnsupportedAppUsage oneway void k(int a);
795 })";
796
797 CaptureStderr();
798 auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, GetLanguage());
799 EXPECT_NE(nullptr, parse_result);
800 EXPECT_EQ("", GetCapturedStderr());
801
802 EXPECT_EQ((Comments{{"/* foo */"}}), parse_result->GetComments());
803
804 const AidlInterface* interface = parse_result->AsInterface();
805 EXPECT_EQ((Comments{{"/* i */"}}), interface->GetMethods()[0]->GetComments());
806 EXPECT_EQ((Comments{{"// j\n"}}), interface->GetMethods()[1]->GetComments());
807 EXPECT_EQ((Comments{{"// k1\n"}, {"/* k2 */"}}), interface->GetMethods()[2]->GetComments());
808 }
809
TEST_P(AidlTest,CppHeaderCanBeIdentifierAsWell)810 TEST_P(AidlTest, CppHeaderCanBeIdentifierAsWell) {
811 io_delegate_.SetFileContents("p/cpp_header.aidl",
812 R"(package p;
813 parcelable cpp_header cpp_header "bar/header" ndk_header "ndk/bar/header";)");
814 import_paths_.emplace("");
815 const string input_path = "p/IFoo.aidl";
816 const string input = R"(package p;
817 import p.cpp_header;
818 interface IFoo {
819 // get bar
820 cpp_header get();
821 })";
822
823 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
824 EXPECT_NE(nullptr, parse_result);
825 const AidlInterface* interface = parse_result->AsInterface();
826 EXPECT_EQ((Comments{{"// get bar\n"}}), interface->GetMethods()[0]->GetComments());
827 }
828
TEST_F(AidlTest,RejectsIfCppHeaderIsMissing)829 TEST_F(AidlTest, RejectsIfCppHeaderIsMissing) {
830 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo;");
831 Options options = Options::From("aidl -I . --lang cpp -h h -o o Foo.aidl");
832 CaptureStderr();
833 EXPECT_FALSE(compile_aidl(options, io_delegate_));
834 EXPECT_THAT(GetCapturedStderr(), HasSubstr("must have cpp_header defined"));
835 }
836
TEST_F(AidlTest,RejectsIfTypeRefsCppHeaderIsMissing)837 TEST_F(AidlTest, RejectsIfTypeRefsCppHeaderIsMissing) {
838 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo;");
839 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void bar(in Foo foo); }");
840 Options options = Options::From("aidl -I . --lang cpp -h h -o o IBar.aidl");
841 CaptureStderr();
842 EXPECT_FALSE(compile_aidl(options, io_delegate_));
843 EXPECT_THAT(GetCapturedStderr(), HasSubstr("must have cpp_header defined"));
844 }
845
TEST_F(AidlTest,ParsesPreprocessedFile)846 TEST_F(AidlTest, ParsesPreprocessedFile) {
847 string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
848 io_delegate_.SetFileContents("path", simple_content);
849 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
850 EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
851 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
852 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
853 }
854
TEST_F(AidlTest,ParsesPreprocessedFileWithWhitespace)855 TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
856 string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
857 io_delegate_.SetFileContents("path", simple_content);
858
859 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
860 EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
861 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
862 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
863 }
864
TEST_P(AidlTest,PreferImportToPreprocessed)865 TEST_P(AidlTest, PreferImportToPreprocessed) {
866 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
867 io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
868 "interface IBar {}");
869 preprocessed_files_.push_back("preprocessed");
870 import_paths_.emplace("");
871 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
872 typenames_, GetLanguage());
873 EXPECT_NE(nullptr, parse_result);
874
875 // We expect to know about both kinds of IBar
876 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
877 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
878 // But if we request just "IBar" we should get our imported one.
879 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", /*array=*/std::nullopt, nullptr, {});
880 ambiguous_type.Resolve(typenames_, parse_result);
881 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
882 }
883
884 // Special case of PreferImportToPreprocessed. Imported type should be preferred
885 // even when the preprocessed file already has the same type.
TEST_P(AidlTest,B147918827)886 TEST_P(AidlTest, B147918827) {
887 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;\ninterface one.IBar;");
888 io_delegate_.SetFileContents("one/IBar.aidl",
889 "package one; "
890 "interface IBar {}");
891 preprocessed_files_.push_back("preprocessed");
892 import_paths_.emplace("");
893 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
894 typenames_, GetLanguage());
895 EXPECT_NE(nullptr, parse_result);
896
897 // We expect to know about both kinds of IBar
898 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
899 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
900 // But if we request just "IBar" we should get our imported one.
901 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", /*array=*/std::nullopt, nullptr, {});
902 ambiguous_type.Resolve(typenames_, parse_result);
903 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
904 }
905
TEST_F(AidlTest,WritePreprocessedFile)906 TEST_F(AidlTest, WritePreprocessedFile) {
907 io_delegate_.SetFileContents("p/Outer.aidl",
908 "package p; parcelable Outer.Inner;");
909 io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
910 "interface IBar {}");
911
912 vector<string> args{"aidl", "--preprocess", "preprocessed",
913 "-I.", "p/Outer.aidl", "one/IBar.aidl"};
914 Options options = Options::From(args);
915 EXPECT_TRUE(::android::aidl::Preprocess(options, io_delegate_));
916
917 std::map<std::string, std::string> expected = {{"preprocessed",
918 "parcelable p.Outer.Inner;\n"
919 "interface one.IBar {\n"
920 "}\n"}};
921 EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
922 }
923
TEST_F(AidlTest,PreprocessVariousThings)924 TEST_F(AidlTest, PreprocessVariousThings) {
925 io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
926 "package foo.bar;\n"
927 "interface IFoo {\n"
928 " int foo();\n"
929 " const int FOO = foo.bar.Bar.BAR + 1; // should be 44\n"
930 "}\n");
931 io_delegate_.SetFileContents("foo/bar/Bar.aidl",
932 "package foo.bar;\n"
933 "parcelable Bar {\n"
934 " const int BAR = imported.Foo.FOO + 1; // should be 43\n"
935 " imported.Foo foo;\n"
936 "}\n");
937 io_delegate_.SetFileContents("foo/bar/Gen.aidl",
938 "package foo.bar;\n"
939 "parcelable Gen<T> {\n"
940 "}\n");
941 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
942 "package foo.bar;\n"
943 "enum Enum {\n"
944 " FOO = 3, BAR = FOO + 3, // should be 3, 6\n"
945 "}\n");
946 io_delegate_.SetFileContents("sub/imported/Foo.aidl",
947 "package imported;\n"
948 "parcelable Foo {\n"
949 " const int FOO = 42;\n"
950 "}\n");
951
952 vector<string> args = {
953 "aidl",
954 "--preprocess",
955 "preprocessed",
956 "-Isub",
957 "-I.",
958 "foo/bar/IFoo.aidl",
959 "foo/bar/Bar.aidl",
960 "foo/bar/Gen.aidl",
961 "foo/bar/Enum.aidl",
962 };
963 ASSERT_TRUE(Preprocess(Options::From(args), io_delegate_));
964 std::string preprocessed =
965 "interface foo.bar.IFoo {\n"
966 " const int FOO = 44;\n"
967 "}\n"
968 "parcelable foo.bar.Bar {\n"
969 " const int BAR = 43;\n"
970 "}\n"
971 "parcelable foo.bar.Gen<T> {\n"
972 "}\n"
973 "enum foo.bar.Enum {\n"
974 " FOO = 3,\n"
975 " BAR = 6,\n"
976 "}\n";
977 std::map<std::string, std::string> expected = {{"preprocessed", preprocessed}};
978 EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
979
980 // use preprocessed
981 io_delegate_.SetFileContents("a/Foo.aidl",
982 "package a; parcelable Foo { const int y = foo.bar.Bar.BAR; }");
983 io_delegate_.SetFileContents("preprocessed", preprocessed);
984 CaptureStderr();
985 auto options = Options::From("aidl --lang java -I . -o out a/Foo.aidl -ppreprocessed");
986 EXPECT_TRUE(compile_aidl(options, io_delegate_));
987 EXPECT_EQ("", GetCapturedStderr());
988 string code;
989 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
990 EXPECT_THAT(code, testing::HasSubstr("public static final int y = 43;"));
991 }
992
TEST_F(AidlTest,AllowMultipleUnstructuredNestedParcelablesInASingleDocument)993 TEST_F(AidlTest, AllowMultipleUnstructuredNestedParcelablesInASingleDocument) {
994 io_delegate_.SetFileContents("p/IFoo.aidl",
995 "package p;\n"
996 "import x.Outer;\n"
997 "interface IFoo {\n"
998 " void foo(in Outer.Inner1 in1, in Outer.Inner2 in2);\n"
999 "}");
1000 io_delegate_.SetFileContents("imported/x/Outer.aidl",
1001 "package x;\n"
1002 "parcelable Outer.Inner1;\n"
1003 "parcelable Outer.Inner2;\n");
1004 auto opt = Options::From("aidl -I . -Iimported --lang=java p/IFoo.aidl");
1005 CaptureStderr();
1006 EXPECT_TRUE(compile_aidl(opt, io_delegate_));
1007 EXPECT_EQ("", GetCapturedStderr());
1008 }
1009
TEST_F(AidlTest,StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlLater)1010 TEST_F(AidlTest,
1011 StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlLater) {
1012 // Main doc(Foo.aidl) is loaded
1013 // And then framework.aidl is loaded as preprocessed. (conflict)
1014 io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
1015 io_delegate_.SetFileContents("x/Foo.aidl",
1016 "package x;\n"
1017 "parcelable Foo.Inner;\n");
1018 auto opt = Options::From("aidl -psdk/framework.aidl -I. x/Foo.aidl");
1019 CaptureStderr();
1020 EXPECT_TRUE(compile_aidl(opt, io_delegate_));
1021 EXPECT_EQ("", GetCapturedStderr());
1022 }
1023
TEST_F(AidlTest,StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlFirst)1024 TEST_F(AidlTest,
1025 StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlFirst) {
1026 // Main doc(IBar.aidl) is loaded first.
1027 // Framework.aidl is loaded as preprocessed.
1028 // And then import(Foo.aidl) is loaded. (conflict)
1029 io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
1030 io_delegate_.SetFileContents("x/IBar.aidl",
1031 "package x;\n"
1032 "import x.Foo;\n"
1033 "interface IBar {\n"
1034 " void bar(in Foo.Inner inner);\n"
1035 "}");
1036 io_delegate_.SetFileContents("x/Foo.aidl",
1037 "package x;\n"
1038 "parcelable Foo.Inner;\n");
1039 auto opt = Options::From("aidl -psdk/framework.aidl -I. x/IBar.aidl");
1040 CaptureStderr();
1041 EXPECT_TRUE(compile_aidl(opt, io_delegate_));
1042 EXPECT_EQ("", GetCapturedStderr());
1043 }
1044
TEST_F(AidlTest,PreprocessedFileCantDeclarePackage)1045 TEST_F(AidlTest, PreprocessedFileCantDeclarePackage) {
1046 string simple_content = "package xxx; parcelable a.Foo;";
1047 io_delegate_.SetFileContents("path", simple_content);
1048 CaptureStderr();
1049 EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
1050 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Preprocessed file can't declare package."));
1051 }
1052
TEST_F(AidlTest,RejectQualifiedTypeNameUnlessPreprocessed)1053 TEST_F(AidlTest, RejectQualifiedTypeNameUnlessPreprocessed) {
1054 string simple_content = "parcelable a.Foo {}";
1055 io_delegate_.SetFileContents("path", simple_content);
1056 CaptureStderr();
1057 EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/false));
1058 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Type name can't be qualified"));
1059 }
1060
TEST_P(AidlTest,PreprocessedCanDeclareJavaStyleBuiltinTypes)1061 TEST_P(AidlTest, PreprocessedCanDeclareJavaStyleBuiltinTypes) {
1062 string contents = R"(
1063 interface android.os.IBinder;
1064 interface android.os.IInterface;
1065 parcelable android.os.ParcelFileDescriptor;
1066 )";
1067 io_delegate_.SetFileContents("path", contents);
1068 CaptureStderr();
1069 EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
1070 EXPECT_THAT(GetCapturedStderr(), "");
1071 }
1072
TEST_P(AidlTest,SupportDeprecated)1073 TEST_P(AidlTest, SupportDeprecated) {
1074 struct TestCase {
1075 std::string output_file;
1076 std::string annotation;
1077 };
1078
1079 auto CheckDeprecated = [&](const std::string& filename, const std::string& contents,
1080 std::vector<std::pair<Options::Language, TestCase>> expectations) {
1081 io_delegate_.SetFileContents(filename, contents);
1082
1083 auto options = Options::From("aidl -I . --lang=" + to_string(GetLanguage()) + " " + filename +
1084 " --out=out --header_out=out");
1085 EXPECT_TRUE(compile_aidl(options, io_delegate_));
1086 for (const auto& [lang, test_case] : expectations) {
1087 if (lang != GetLanguage()) continue;
1088 string output;
1089 EXPECT_TRUE(io_delegate_.GetWrittenContents(test_case.output_file, &output));
1090 EXPECT_THAT(output, HasSubstr(test_case.annotation));
1091 }
1092 };
1093
1094 // Emit escaped string for notes
1095 CheckDeprecated(
1096 "IFoo.aidl",
1097 R"(interface IFoo {
1098 /**
1099 * @note asdf
1100 * @deprecated a really long deprecation message
1101 *
1102 * which is really long
1103 * @param foo bar
1104 */
1105 List<String> foo();
1106 })",
1107 {
1108 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1109 {Options::Language::CPP,
1110 {"out/IFoo.h",
1111 R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
1112 {Options::Language::NDK,
1113 {"out/aidl/IFoo.h",
1114 R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
1115 {Options::Language::RUST,
1116 {"out/IFoo.rs",
1117 R"(#[deprecated = "a really long deprecation message which is really long"])"}},
1118 });
1119
1120 // In AIDL @deprecated can be in block comments as well as javadoc style
1121 CheckDeprecated(
1122 "IFoo.aidl",
1123 "interface IFoo {\n"
1124 " /* @deprecated use bar() */\n"
1125 " List<String> foo();\n"
1126 "}",
1127 {
1128 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1129 {Options::Language::JAVA, {"out/IFoo.java", "/** @deprecated use bar() */"}},
1130 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
1131 {Options::Language::NDK,
1132 {"out/aidl/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
1133 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated = \"use bar()\"]"}},
1134 });
1135
1136 // but not in line comments
1137 auto parsed = Parse("IFoo.aidl", "// @deprecated\ninterface IFoo {}", typenames_, GetLanguage());
1138 EXPECT_FALSE(parsed->IsDeprecated());
1139
1140 // parcelable
1141 CheckDeprecated("Foo.aidl",
1142 "parcelable Foo {\n"
1143 " /** @deprecated use bar*/\n"
1144 " int foo = 0;\n"
1145 "}",
1146 {
1147 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1148 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1149 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1150 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1151 });
1152
1153 // interface constants
1154 CheckDeprecated("IFoo.aidl",
1155 "interface IFoo {\n"
1156 " /** @deprecated use bar*/\n"
1157 " const int FOO = 0;\n"
1158 "}",
1159 {
1160 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1161 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1162 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1163 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1164 });
1165
1166 // union fields
1167 CheckDeprecated("Foo.aidl",
1168 "union Foo {\n"
1169 " int bar = 0;\n"
1170 " /** @deprecated use bar*/\n"
1171 " int foo;\n"
1172 "}",
1173 {
1174 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1175 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1176 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1177 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1178 });
1179
1180 CheckDeprecated("Foo.aidl",
1181 "/** @deprecated use Bar */\n"
1182 "parcelable Foo {}",
1183 {
1184 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1185 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1186 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1187 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1188 });
1189
1190 CheckDeprecated("Foo.aidl",
1191 "/** @deprecated use Bar */\n"
1192 "union Foo { int foo = 0; }",
1193 {
1194 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1195 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1196 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1197 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1198 });
1199
1200 CheckDeprecated("IFoo.aidl",
1201 "/** @deprecated use IBar */\n"
1202 "interface IFoo {}",
1203 {
1204 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1205 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1206 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1207 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1208 });
1209
1210 CheckDeprecated("Foo.aidl",
1211 "/** @deprecated use IBar */\n"
1212 "enum Foo { FOO }",
1213 {
1214 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1215 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1216 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1217 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1218 });
1219
1220 CheckDeprecated("Foo.aidl",
1221 "enum Foo {\n"
1222 " /** @deprecated */\n"
1223 " FOO,\n"
1224 " BAR,\n"
1225 "}",
1226 {
1227 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1228 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1229 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1230 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1231 });
1232 }
1233
TEST_P(AidlTest,RequireOuterClass)1234 TEST_P(AidlTest, RequireOuterClass) {
1235 const string expected_stderr =
1236 "ERROR: p/IFoo.aidl: Couldn't find import for class Inner. Searched here:\n - ./\nERROR: "
1237 "p/IFoo.aidl:1.54-60: Failed to resolve 'Inner'\n";
1238 io_delegate_.SetFileContents("p/Outer.aidl",
1239 "package p; parcelable Outer.Inner;");
1240 import_paths_.emplace("");
1241 CaptureStderr();
1242 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1243 "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
1244 typenames_, GetLanguage()));
1245 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1246 }
1247
TEST_P(AidlTest,ParseCompoundParcelableFromPreprocess)1248 TEST_P(AidlTest, ParseCompoundParcelableFromPreprocess) {
1249 io_delegate_.SetFileContents(
1250 "preprocessed",
1251 "parcelable p.Outer.Inner cpp_header \"inner.h\" ndk_header \"ndk/inner.h\";");
1252 preprocessed_files_.push_back("preprocessed");
1253 auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
1254 typenames_, GetLanguage());
1255 // Require legacy behavior - inner class name can be used without outer class name.
1256 EXPECT_NE(nullptr, parse_result);
1257 }
1258
TEST_F(AidlTest,ApiMappingAcceptsUnstructuredParcelables)1259 TEST_F(AidlTest, ApiMappingAcceptsUnstructuredParcelables) {
1260 io_delegate_.SetFileContents("p/Foo.aidl", "package p; parcelable Foo;");
1261
1262 Options options1 = Options::From("aidl -I . --apimapping mapping.txt p/Foo.aidl");
1263 CaptureStderr();
1264 EXPECT_EQ(0, aidl_entry(options1, io_delegate_));
1265 EXPECT_EQ("", GetCapturedStderr());
1266 }
1267
TEST_F(AidlTest,FailOnParcelable)1268 TEST_F(AidlTest, FailOnParcelable) {
1269 const string expected_foo_stderr =
1270 "ERROR: p/IFoo.aidl:1.22-27: Refusing to generate code with unstructured parcelables. "
1271 "Declared parcelables should be in their own file and/or cannot be used with --structured "
1272 "interfaces.\n";
1273 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; parcelable IFoo;");
1274
1275 // By default, we shouldn't fail on parcelable.
1276 Options options1 = Options::From("aidl -I . p/IFoo.aidl");
1277 CaptureStderr();
1278 EXPECT_TRUE(compile_aidl(options1, io_delegate_));
1279 EXPECT_EQ("", GetCapturedStderr());
1280
1281 // -b considers this an error
1282 Options options2 = Options::From("aidl -I . -b p/IFoo.aidl");
1283 CaptureStderr();
1284 EXPECT_FALSE(compile_aidl(options2, io_delegate_));
1285 EXPECT_EQ(expected_foo_stderr, GetCapturedStderr());
1286
1287 const string expected_bar_stderr =
1288 "ERROR: p/IBar.aidl:1.22-26: Refusing to generate code with unstructured parcelables. "
1289 "Declared parcelables should be in their own file and/or cannot be used with --structured "
1290 "interfaces.\n";
1291 io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
1292
1293 // With '-b' option, a parcelable and an interface should fail.
1294 Options options3 = Options::From("aidl -I . p/IBar.aidl");
1295 CaptureStderr();
1296 EXPECT_TRUE(compile_aidl(options3, io_delegate_));
1297 EXPECT_EQ("", GetCapturedStderr());
1298 Options options4 = Options::From("aidl -I . -b p/IBar.aidl");
1299 CaptureStderr();
1300 EXPECT_FALSE(compile_aidl(options4, io_delegate_));
1301 EXPECT_EQ(expected_bar_stderr, GetCapturedStderr());
1302 }
1303
TEST_P(AidlTest,ImportingJavaStyleBuiltinTypesIsAllowed)1304 TEST_P(AidlTest, ImportingJavaStyleBuiltinTypesIsAllowed) {
1305 string contents = R"(
1306 import android.os.IBinder;
1307 import android.os.IInterface;
1308 interface IFoo {
1309 void foo(in IBinder b);
1310 }
1311 )";
1312 EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
1313 }
1314
TEST_P(AidlTest,StructuredFailOnUnstructuredParcelable)1315 TEST_P(AidlTest, StructuredFailOnUnstructuredParcelable) {
1316 const string expected_stderr =
1317 "o.WhoKnowsWhat is not structured, but this is a structured interface";
1318 io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl",
1319 "package o; parcelable WhoKnowsWhat cpp_header \"who_knows.h\" "
1320 "ndk_header \"ndk/who_knows.h\";");
1321 import_paths_.emplace("");
1322 AidlError error;
1323 CaptureStderr();
1324 EXPECT_EQ(
1325 nullptr,
1326 Parse("p/IFoo.aidl",
1327 "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
1328 typenames_, GetLanguage(), &error, {"--structured"}));
1329 EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
1330 EXPECT_EQ(AidlError::NOT_STRUCTURED, error);
1331 }
1332
TEST_P(AidlTest,FailOnDuplicateConstantNames)1333 TEST_P(AidlTest, FailOnDuplicateConstantNames) {
1334 AidlError error;
1335 const string expected_stderr =
1336 "ERROR: p/IFoo.aidl:4.34-45: Found duplicate constant name 'DUPLICATED'\n";
1337 CaptureStderr();
1338 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1339 R"(package p;
1340 interface IFoo {
1341 const String DUPLICATED = "d";
1342 const int DUPLICATED = 1;
1343 }
1344 )",
1345 typenames_, GetLanguage(), &error));
1346 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1347 EXPECT_EQ(AidlError::BAD_TYPE, error);
1348 }
1349
TEST_P(AidlTest,InvalidConstString)1350 TEST_P(AidlTest, InvalidConstString) {
1351 AidlError error;
1352 const string expected_stderr =
1353 "ERROR: p/IFoo.aidl:3.47-60: Found invalid character '\\' at index 4 in string constant "
1354 "'\"test\\\"test\"'\n";
1355 CaptureStderr();
1356 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1357 R"(package p;
1358 interface IFoo {
1359 const String someVar = "test\"test";
1360 }
1361 )",
1362 typenames_, GetLanguage(), &error));
1363 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1364 EXPECT_EQ(AidlError::BAD_TYPE, error);
1365 }
1366
TEST_F(AidlTest,InvalidCharLiteral)1367 TEST_F(AidlTest, InvalidCharLiteral) {
1368 auto filename = "Foo.aidl";
1369 char code[] = "parcelable Foo { char a = '\0'; char b = '\t'; }";
1370 io_delegate_.SetFileContents(filename,
1371 string{code, sizeof(code) - 1}); // -1 to drop nil at the end
1372 CaptureStderr();
1373 EXPECT_TRUE(Parser::Parse(filename, io_delegate_, typenames_, /*is_preprocessed=*/false));
1374 auto err = GetCapturedStderr();
1375 EXPECT_THAT(err, HasSubstr("Invalid character literal \\0"));
1376 EXPECT_THAT(err, HasSubstr("Invalid character literal \\t"));
1377 }
1378
TEST_P(AidlTest,RejectUnstructuredParcelablesInNDKandRust)1379 TEST_P(AidlTest, RejectUnstructuredParcelablesInNDKandRust) {
1380 io_delegate_.SetFileContents("o/Foo.aidl", "package o; parcelable Foo cpp_header \"cpp/Foo.h\";");
1381 const auto options =
1382 Options::From("aidl --lang=" + to_string(GetLanguage()) + " -o out -h out -I. o/Foo.aidl");
1383 const bool reject_unstructured_parcelables =
1384 GetLanguage() == Options::Language::NDK || GetLanguage() == Options::Language::RUST;
1385 const string expected_err = reject_unstructured_parcelables
1386 ? "Refusing to generate code with unstructured parcelables"
1387 : "";
1388 CaptureStderr();
1389 EXPECT_EQ(compile_aidl(options, io_delegate_), !reject_unstructured_parcelables);
1390 EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_err));
1391 }
1392
TEST_F(AidlTest,CosntantValueType)1393 TEST_F(AidlTest, CosntantValueType) {
1394 unique_ptr<AidlConstantValue> num{AidlConstantValue::Integral(AIDL_LOCATION_HERE, "1")};
1395 EXPECT_EQ(num->GetType(), AidlConstantValue::Type::INT8);
1396 }
1397
TEST_P(AidlTest,FailOnTooBigConstant)1398 TEST_P(AidlTest, FailOnTooBigConstant) {
1399 AidlError error;
1400 const string expected_stderr =
1401 "ERROR: p/IFoo.aidl:3.48-52: Invalid type specifier for an int32 literal: byte (256)\n";
1402 CaptureStderr();
1403 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1404 R"(package p;
1405 interface IFoo {
1406 const byte type2small = 256;
1407 }
1408 )",
1409 typenames_, GetLanguage(), &error));
1410 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1411 EXPECT_EQ(AidlError::BAD_TYPE, error);
1412 }
1413
TEST_F(AidlTest,BoolConstantsEvaluatesToIntegers)1414 TEST_F(AidlTest, BoolConstantsEvaluatesToIntegers) {
1415 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { const int y = true; }");
1416 CaptureStderr();
1417 auto options = Options::From("aidl -I . --lang java -o out a/Foo.aidl");
1418 EXPECT_TRUE(compile_aidl(options, io_delegate_));
1419 EXPECT_EQ("", GetCapturedStderr());
1420 string code;
1421 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
1422 EXPECT_THAT(code, testing::HasSubstr("public static final int y = 1;"));
1423 }
1424
TEST_F(AidlTest,AidlConstantValue_EvaluatedValue)1425 TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) {
1426 using Ptr = unique_ptr<AidlConstantValue>;
1427 const AidlLocation& loc = AIDL_LOCATION_HERE;
1428
1429 EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, "'c'"))->EvaluatedValue<char16_t>());
1430 EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>());
1431 EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>());
1432 EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>());
1433
1434 AidlBinaryConstExpression one_plus_one(loc, Ptr(AidlConstantValue::Integral(loc, "1")), "+",
1435 Ptr(AidlConstantValue::Integral(loc, "1")));
1436 EXPECT_EQ(2, one_plus_one.EvaluatedValue<int32_t>());
1437
1438 auto values = unique_ptr<vector<Ptr>>{new vector<Ptr>};
1439 values->emplace_back(AidlConstantValue::String(loc, "\"hello\""));
1440 values->emplace_back(AidlConstantValue::String(loc, "\"world\""));
1441 vector<string> expected{"hello", "world"};
1442 EXPECT_EQ(
1443 expected,
1444 Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>());
1445 }
1446
TEST_F(AidlTest,AidlConstantCharacterDefault)1447 TEST_F(AidlTest, AidlConstantCharacterDefault) {
1448 auto char_type = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "char", false);
1449 auto default_value = unique_ptr<AidlConstantValue>(AidlConstantValue::Default(*char_type));
1450 EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, cpp::ConstantValueDecorator));
1451 EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, ndk::ConstantValueDecorator));
1452 EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, java::ConstantValueDecorator));
1453 }
1454
TEST_P(AidlTest,FailOnManyDefinedTypes)1455 TEST_P(AidlTest, FailOnManyDefinedTypes) {
1456 AidlError error;
1457 const string expected_stderr =
1458 "ERROR: p/IFoo.aidl:3.33-38: You must declare only one type per file.\n";
1459 CaptureStderr();
1460 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1461 R"(package p;
1462 interface IFoo {}
1463 parcelable IBar {}
1464 parcelable StructuredParcelable {}
1465 interface IBaz {}
1466 )",
1467 typenames_, GetLanguage(), &error));
1468 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1469 // Parse success is important for clear error handling even if the cases aren't
1470 // actually supported in code generation.
1471 EXPECT_EQ(AidlError::BAD_TYPE, error);
1472 }
1473
TEST_P(AidlTest,FailOnNoDefinedTypes)1474 TEST_P(AidlTest, FailOnNoDefinedTypes) {
1475 AidlError error;
1476 const string expected_stderr = "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected $end\n";
1477 const string expected_stderr_newbison =
1478 "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected end of file\n";
1479 CaptureStderr();
1480 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, GetLanguage(), &error));
1481 EXPECT_THAT(GetCapturedStderr(),
1482 testing::AnyOf(testing::Eq(expected_stderr), testing::Eq(expected_stderr_newbison)));
1483 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1484 }
1485
TEST_P(AidlTest,FailOnEmptyListWithComma)1486 TEST_P(AidlTest, FailOnEmptyListWithComma) {
1487 AidlError error;
1488 const string expected_stderr =
1489 "ERROR: p/Foo.aidl:1.45-47: syntax error, unexpected ',', expecting '}'\n";
1490 CaptureStderr();
1491 EXPECT_EQ(nullptr, Parse("p/Foo.aidl", R"(package p; parcelable Foo { uint64_t[] a = { , }; })",
1492 typenames_, GetLanguage(), &error));
1493 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1494 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1495 }
1496
TEST_P(AidlTest,FailOnMalformedConstHexValue)1497 TEST_P(AidlTest, FailOnMalformedConstHexValue) {
1498 AidlError error;
1499 const string expected_stderr =
1500 "ERROR: p/IFoo.aidl:3.50-71: Could not parse hexvalue: 0xffffffffffffffffff\n";
1501 CaptureStderr();
1502 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1503 R"(package p;
1504 interface IFoo {
1505 const int BAD_HEX_VALUE = 0xffffffffffffffffff;
1506 }
1507 )",
1508 typenames_, GetLanguage(), &error));
1509 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1510 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1511 }
1512
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsIdentifier)1513 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsIdentifier) {
1514 AidlError error;
1515 const string expected_stderr =
1516 "ERROR: p/IFoo.aidl:1.25-26: syntax error, unexpected ';', expecting identifier";
1517 CaptureStderr();
1518 // Notice the trailing dot(.) in the name, which isn't a correct name
1519 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p; parcelable A.; )", typenames_,
1520 GetLanguage(), &error));
1521 EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
1522 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1523 }
1524
TEST_P(AidlTest,FailOnAssigningDoubleInFloatConst)1525 TEST_P(AidlTest, FailOnAssigningDoubleInFloatConst) {
1526 EvaluateInvalidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1.1; })",
1527 INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1528 }
1529
TEST_P(AidlTest,FailOnAssigningFloatInDoubleConst)1530 TEST_P(AidlTest, FailOnAssigningFloatInDoubleConst) {
1531 EvaluateValidAssignment(R"(package a; interface IFoo { const double FLOAT_VALUE = 1.1f; })", "",
1532 typenames_, GetLanguage());
1533 }
1534
TEST_P(AidlTest,FailOnAssigningIntInFloatConst)1535 TEST_P(AidlTest, FailOnAssigningIntInFloatConst) {
1536 EvaluateInvalidAssignment(R"(package a; interface IFoo { const float INT_VALUE = 1; })",
1537 INVALID_INT8_VALUE, typenames_, GetLanguage());
1538 }
1539
TEST_P(AidlTest,FailOnAssigningFloatInIntConst)1540 TEST_P(AidlTest, FailOnAssigningFloatInIntConst) {
1541 EvaluateInvalidAssignment(R"(package a; interface IFoo { const int FLOAT_VALUE = 1.1f; })",
1542 INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1543 }
1544
TEST_P(AidlTest,FailOnAssigningIntInDoubleConst)1545 TEST_P(AidlTest, FailOnAssigningIntInDoubleConst) {
1546 EvaluateInvalidAssignment(R"(package a; interface IFoo { const double INT_VALUE = 1; })",
1547 INVALID_INT8_VALUE, typenames_, GetLanguage());
1548 }
1549
TEST_P(AidlTest,FailOnAssigningDoubleInIntConst)1550 TEST_P(AidlTest, FailOnAssigningDoubleInIntConst) {
1551 EvaluateInvalidAssignment(R"(package a; interface IFoo { const int DOUBLE_VALUE = 1.1; })",
1552 INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1553 }
1554
TEST_P(AidlTest,FailOnAssigningFloatPlusIntConst)1555 TEST_P(AidlTest, FailOnAssigningFloatPlusIntConst) {
1556 EvaluateInvalidAssignment(R"(package a; interface IFoo { const float FLOAT_VALUE = 1.1f + 1; })",
1557 INVALID_OPERATION, typenames_, GetLanguage());
1558 }
1559
TEST_P(AidlTest,FailOnAssigningIntPlusFloatConst)1560 TEST_P(AidlTest, FailOnAssigningIntPlusFloatConst) {
1561 EvaluateInvalidAssignment(R"(package a; interface IFoo { const float FLOAT_VALUE = 1 + 1.1f; })",
1562 INVALID_OPERATION, typenames_, GetLanguage());
1563 }
1564
TEST_P(AidlTest,FailOnAssigningDoublePlusIntConst)1565 TEST_P(AidlTest, FailOnAssigningDoublePlusIntConst) {
1566 EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1.1 + 1; })",
1567 INVALID_OPERATION, typenames_, GetLanguage());
1568 }
1569
TEST_P(AidlTest,FailOnAssigningIntPlusDoubleConst)1570 TEST_P(AidlTest, FailOnAssigningIntPlusDoubleConst) {
1571 EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1 + 1.1; })",
1572 INVALID_OPERATION, typenames_, GetLanguage());
1573 }
1574
TEST_P(AidlTest,FailOnAssigningTooLargeFloatConst)1575 TEST_P(AidlTest, FailOnAssigningTooLargeFloatConst) {
1576 EvaluateInvalidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1e50f; })",
1577 INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1578 }
1579
TEST_P(AidlTest,FailOnAssigningTooLargeDoubleConst)1580 TEST_P(AidlTest, FailOnAssigningTooLargeDoubleConst) {
1581 EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1e310; })",
1582 INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1583 }
1584
TEST_P(AidlTest,PassOnAssigningLargeFloatConst)1585 TEST_P(AidlTest, PassOnAssigningLargeFloatConst) {
1586 EvaluateValidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1e20f; })", "",
1587 typenames_, GetLanguage());
1588 }
1589
TEST_P(AidlTest,PassOnAssigningLargeDoubleConst)1590 TEST_P(AidlTest, PassOnAssigningLargeDoubleConst) {
1591 EvaluateValidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1e150; })", "",
1592 typenames_, GetLanguage());
1593 }
1594
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsPackage)1595 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsPackage) {
1596 AidlError error;
1597 const string expected_stderr =
1598 "ERROR: p/IFoo.aidl:1.11-12: syntax error, unexpected ';', expecting identifier";
1599 CaptureStderr();
1600 // Notice the trailing dot(.) in the package name
1601 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p.; parcelable A; )", typenames_,
1602 GetLanguage(), &error));
1603 EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
1604 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1605 }
1606
TEST_P(AidlTest,ParsePositiveConstHexValue)1607 TEST_P(AidlTest, ParsePositiveConstHexValue) {
1608 AidlError error;
1609 auto parse_result = Parse("p/IFoo.aidl",
1610 R"(package p;
1611 interface IFoo {
1612 const int POSITIVE_HEX_VALUE = 0xf5;
1613 }
1614 )",
1615 typenames_, GetLanguage(), &error);
1616 EXPECT_NE(nullptr, parse_result);
1617 const AidlInterface* interface = parse_result->AsInterface();
1618 ASSERT_NE(nullptr, interface);
1619 const auto& cpp_constants = interface->GetConstantDeclarations();
1620 EXPECT_EQ((size_t)1, cpp_constants.size());
1621 EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
1622 EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
1623 EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1624 }
1625
TEST_P(AidlTest,ParseNegativeConstHexValue)1626 TEST_P(AidlTest, ParseNegativeConstHexValue) {
1627 AidlError error;
1628 auto parse_result = Parse("p/IFoo.aidl",
1629 R"(package p;
1630 interface IFoo {
1631 const int NEGATIVE_HEX_VALUE = 0xffffffff;
1632 }
1633 )",
1634 typenames_, GetLanguage(), &error);
1635 ASSERT_NE(nullptr, parse_result);
1636 const AidlInterface* interface = parse_result->AsInterface();
1637 ASSERT_NE(nullptr, interface);
1638 const auto& cpp_constants = interface->GetConstantDeclarations();
1639 EXPECT_EQ((size_t)1, cpp_constants.size());
1640 EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
1641 EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
1642 EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1643 }
1644
TEST_F(AidlTest,ByteAndByteArrayDifferInCpp)1645 TEST_F(AidlTest, ByteAndByteArrayDifferInCpp) {
1646 auto type = Parse("p/Foo.aidl",
1647 R"(
1648 package p;
1649 parcelable Foo {
1650 byte a = -1;
1651 byte[] b = {-1, 1};
1652 @nullable byte[] c = {-1, 1};
1653 }
1654 )",
1655 typenames_, Options::Language::CPP);
1656 ASSERT_NE(nullptr, type);
1657 auto& fields = type->GetFields();
1658 ASSERT_EQ(3ul, fields.size());
1659 EXPECT_EQ("-1", fields[0]->ValueString(cpp::ConstantValueDecorator));
1660 EXPECT_EQ("{uint8_t(-1), 1}", fields[1]->ValueString(cpp::ConstantValueDecorator));
1661 EXPECT_EQ("{{uint8_t(-1), 1}}", fields[2]->ValueString(cpp::ConstantValueDecorator));
1662 }
1663
TEST_F(AidlTest,ByteAndByteArrayDifferInNdk)1664 TEST_F(AidlTest, ByteAndByteArrayDifferInNdk) {
1665 auto type = Parse("p/Foo.aidl",
1666 R"(
1667 package p;
1668 parcelable Foo {
1669 byte a = -1;
1670 byte[] b = {-1, 1};
1671 @nullable byte[] c = {-1, 1};
1672 }
1673 )",
1674 typenames_, Options::Language::NDK);
1675 ASSERT_NE(nullptr, type);
1676 auto& fields = type->GetFields();
1677 ASSERT_EQ(3ul, fields.size());
1678 EXPECT_EQ("-1", fields[0]->ValueString(ndk::ConstantValueDecorator));
1679 EXPECT_EQ("{uint8_t(-1), 1}", fields[1]->ValueString(ndk::ConstantValueDecorator));
1680 EXPECT_EQ("{{uint8_t(-1), 1}}", fields[2]->ValueString(ndk::ConstantValueDecorator));
1681 }
1682
TEST_P(AidlTest,UnderstandsNestedUnstructuredParcelables)1683 TEST_P(AidlTest, UnderstandsNestedUnstructuredParcelables) {
1684 io_delegate_.SetFileContents(
1685 "p/Outer.aidl",
1686 "package p; parcelable Outer.Inner cpp_header \"baz/header\" ndk_header \"ndk/baz/header\";");
1687 import_paths_.emplace("");
1688 const string input_path = "p/IFoo.aidl";
1689 const string input = "package p; import p.Outer; interface IFoo"
1690 " { Outer.Inner get(); }";
1691
1692 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1693 EXPECT_NE(nullptr, parse_result);
1694
1695 EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1696 // C++ uses "::" instead of "." to refer to a inner class.
1697 AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", /*array=*/std::nullopt,
1698 nullptr, {});
1699 EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1700 }
1701
TEST_P(AidlTest,UnderstandsNestedUnstructuredParcelablesWithoutImports)1702 TEST_P(AidlTest, UnderstandsNestedUnstructuredParcelablesWithoutImports) {
1703 io_delegate_.SetFileContents(
1704 "p/Outer.aidl",
1705 "package p; parcelable Outer.Inner cpp_header \"baz/header\" ndk_header \"ndk/baz/header\";");
1706 import_paths_.emplace("");
1707 const string input_path = "p/IFoo.aidl";
1708 const string input = "package p; interface IFoo { p.Outer.Inner get(); }";
1709
1710 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1711 EXPECT_NE(nullptr, parse_result);
1712
1713 EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1714 // C++ uses "::" instead of "." to refer to a inner class.
1715 AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", /*array=*/std::nullopt,
1716 nullptr, {});
1717 EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1718 }
1719
TEST_F(AidlTest,UnderstandsNestedTypes)1720 TEST_F(AidlTest, UnderstandsNestedTypes) {
1721 io_delegate_.SetFileContents("p/IOuter.aidl",
1722 "package p;\n"
1723 "interface IOuter {\n"
1724 " parcelable Inner {}\n"
1725 "}");
1726 import_paths_.emplace("");
1727 const string input_path = "p/IFoo.aidl";
1728 const string input =
1729 "package p;\n"
1730 "import p.IOuter;\n"
1731 "interface IFoo {\n"
1732 " IOuter.Inner get();\n"
1733 "}";
1734 CaptureStderr();
1735 EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1736 EXPECT_EQ(GetCapturedStderr(), "");
1737
1738 EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1739 // C++ uses "::" instead of "." to refer to a inner class.
1740 AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.IOuter.Inner", /*array=*/std::nullopt,
1741 nullptr, {});
1742 EXPECT_EQ("::p::IOuter::Inner", cpp::CppNameOf(nested_type, typenames_));
1743 }
1744
TEST_F(AidlTest,DefinedTypeKnowsItsParentScope)1745 TEST_F(AidlTest, DefinedTypeKnowsItsParentScope) {
1746 const string input_path = "p/IFoo.aidl";
1747 const string input =
1748 "package p;\n"
1749 "interface IFoo {\n"
1750 " parcelable Inner {\n"
1751 " enum Enum { A }\n"
1752 " }\n"
1753 "}";
1754 CaptureStderr();
1755 EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1756 EXPECT_EQ(GetCapturedStderr(), "");
1757
1758 auto enum_type = typenames_.ResolveTypename("p.IFoo.Inner.Enum");
1759 auto inner_type = typenames_.ResolveTypename("p.IFoo.Inner");
1760 auto ifoo_type = typenames_.ResolveTypename("p.IFoo");
1761 EXPECT_TRUE(enum_type.is_resolved);
1762 EXPECT_TRUE(inner_type.is_resolved);
1763 EXPECT_TRUE(ifoo_type.is_resolved);
1764 // GetParentType()
1765 EXPECT_EQ(inner_type.defined_type, enum_type.defined_type->GetParentType());
1766 EXPECT_EQ(ifoo_type.defined_type, inner_type.defined_type->GetParentType());
1767 EXPECT_EQ(nullptr, ifoo_type.defined_type->GetParentType());
1768 // GetRootType()
1769 EXPECT_EQ(ifoo_type.defined_type, enum_type.defined_type->GetRootType());
1770 EXPECT_EQ(ifoo_type.defined_type, inner_type.defined_type->GetRootType());
1771 EXPECT_EQ(ifoo_type.defined_type, ifoo_type.defined_type->GetRootType());
1772 // GetDocument()
1773 auto main_document = &typenames_.MainDocument();
1774 EXPECT_EQ(main_document, &enum_type.defined_type->GetDocument());
1775 EXPECT_EQ(main_document, &inner_type.defined_type->GetDocument());
1776 EXPECT_EQ(main_document, &ifoo_type.defined_type->GetDocument());
1777 }
1778
TEST_F(AidlTest,UnderstandsNestedTypesViaFullyQualifiedName)1779 TEST_F(AidlTest, UnderstandsNestedTypesViaFullyQualifiedName) {
1780 io_delegate_.SetFileContents("p/IOuter.aidl",
1781 "package p;\n"
1782 "interface IOuter {\n"
1783 " parcelable Inner {}\n"
1784 "}");
1785 import_paths_.emplace("");
1786 const string input_path = "p/IFoo.aidl";
1787 const string input =
1788 "package p;\n"
1789 "interface IFoo {\n"
1790 " p.IOuter.Inner get();\n"
1791 "}";
1792 CaptureStderr();
1793 EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1794 EXPECT_EQ(GetCapturedStderr(), "");
1795
1796 EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1797 }
1798
TEST_F(AidlTest,IncludeParentsRawHeaderForNestedInterface)1799 TEST_F(AidlTest, IncludeParentsRawHeaderForNestedInterface) {
1800 CaptureStderr();
1801 EXPECT_NE(nullptr, Parse("p/Outer.aidl",
1802 "package p;\n"
1803 "parcelable Outer {\n"
1804 " interface IInner {}\n"
1805 "}",
1806 typenames_, Options::Language::CPP));
1807
1808 EXPECT_EQ(GetCapturedStderr(), "");
1809 auto resolved = typenames_.ResolveTypename("p.Outer.IInner");
1810 ASSERT_TRUE(resolved.defined_type);
1811 EXPECT_EQ(cpp::HeaderFile(*resolved.defined_type, cpp::ClassNames::CLIENT), "p/Outer.h");
1812 }
1813
TEST_F(AidlTest,UnderstandsNestedTypesViaFullyQualifiedImport)1814 TEST_F(AidlTest, UnderstandsNestedTypesViaFullyQualifiedImport) {
1815 io_delegate_.SetFileContents("p/IOuter.aidl",
1816 "package p;\n"
1817 "interface IOuter {\n"
1818 " parcelable Inner {}\n"
1819 "}");
1820 import_paths_.emplace("");
1821 const string input_path = "p/IFoo.aidl";
1822 const string input =
1823 "package p;\n"
1824 "import p.IOuter.Inner;"
1825 "interface IFoo {\n"
1826 " Inner get();\n"
1827 "}";
1828 CaptureStderr();
1829 EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1830 EXPECT_EQ(GetCapturedStderr(), "");
1831
1832 EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1833 }
1834
TEST_F(AidlTest,UnderstandsNestedTypesInTheSameScope)1835 TEST_F(AidlTest, UnderstandsNestedTypesInTheSameScope) {
1836 const string input_path = "p/IFoo.aidl";
1837 const string input =
1838 "package p;\n"
1839 "interface IFoo {\n"
1840 " parcelable Result {}\n"
1841 " Result get();\n"
1842 "}";
1843 CaptureStderr();
1844 EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1845 EXPECT_EQ(GetCapturedStderr(), "");
1846
1847 EXPECT_TRUE(typenames_.ResolveTypename("p.IFoo.Result").is_resolved);
1848 }
1849
1850 // Finding the type of nested named member.
1851 struct TypeFinder : AidlVisitor {
1852 string name;
1853 const AidlTypeSpecifier* type = nullptr;
TypeFinderandroid::aidl::TypeFinder1854 TypeFinder(std::string name) : name(name) {}
Visitandroid::aidl::TypeFinder1855 void Visit(const AidlVariableDeclaration& v) override {
1856 if (v.GetName() == name) {
1857 type = &v.GetType();
1858 }
1859 }
Visitandroid::aidl::TypeFinder1860 void Visit(const AidlMethod& m) override {
1861 if (m.GetName() == name) {
1862 type = &m.GetType();
1863 }
1864 }
Getandroid::aidl::TypeFinder1865 static string Get(const AidlDefinedType& type, const string& name) {
1866 TypeFinder v(name);
1867 VisitTopDown(v, type);
1868 return v.type ? v.type->Signature() : "(null)";
1869 };
1870 };
1871
TEST_F(AidlTest,UnderstandsNestedTypesViaQualifiedInTheSameScope)1872 TEST_F(AidlTest, UnderstandsNestedTypesViaQualifiedInTheSameScope) {
1873 io_delegate_.SetFileContents("q/IBar.aidl",
1874 "package q;\n"
1875 "interface IBar {\n"
1876 " parcelable Baz {}\n"
1877 "}");
1878 import_paths_.emplace("");
1879 const string input_path = "p/IFoo.aidl";
1880 const string input =
1881 "package p;\n"
1882 "import q.IBar;\n"
1883 "interface IFoo {\n"
1884 " parcelable Nested {\n"
1885 " Baz t1;\n"
1886 " }\n"
1887 " parcelable Baz { }\n"
1888 " IBar.Baz t2();\n"
1889 " Baz t3();\n"
1890 "}";
1891 CaptureStderr();
1892 auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
1893 EXPECT_EQ(GetCapturedStderr(), "");
1894 ASSERT_NE(nullptr, foo);
1895
1896 EXPECT_EQ(TypeFinder::Get(*foo, "t1"), "p.IFoo.Baz");
1897 EXPECT_EQ(TypeFinder::Get(*foo, "t2"), "q.IBar.Baz");
1898 EXPECT_EQ(TypeFinder::Get(*foo, "t3"), "p.IFoo.Baz");
1899 }
1900
TEST_F(AidlTest,NestedTypeResolutionWithNoPackage)1901 TEST_F(AidlTest, NestedTypeResolutionWithNoPackage) {
1902 const string input_path = "Foo.aidl";
1903 const string input =
1904 "parcelable Foo {\n"
1905 " parcelable Bar {\n"
1906 " enum Baz { BAZ }\n"
1907 " Baz baz = Baz.BAZ;\n"
1908 " }\n"
1909 " Bar bar;\n"
1910 "}";
1911 CaptureStderr();
1912 auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
1913 EXPECT_EQ(GetCapturedStderr(), "");
1914 ASSERT_NE(nullptr, foo);
1915
1916 EXPECT_EQ(TypeFinder::Get(*foo, "bar"), "Foo.Bar");
1917 EXPECT_EQ(TypeFinder::Get(*foo, "baz"), "Foo.Bar.Baz");
1918 }
1919
TEST_F(AidlTest,RejectsNestedTypesWithParentsName)1920 TEST_F(AidlTest, RejectsNestedTypesWithParentsName) {
1921 const string input_path = "p/Foo.aidl";
1922 const string input =
1923 "package p;\n"
1924 "parcelable Foo {\n"
1925 " parcelable Foo {}\n"
1926 "}";
1927 CaptureStderr();
1928 EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1929 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Nested type 'Foo' has the same name as its parent."));
1930 }
1931
TEST_F(AidlTest,RejectUnstructuredParcelableAsNestedTypes)1932 TEST_F(AidlTest, RejectUnstructuredParcelableAsNestedTypes) {
1933 const string input_path = "p/IFoo.aidl";
1934 const string input =
1935 "package p;\n"
1936 "interface IFoo {\n"
1937 " parcelable Bar cpp_header \"Bar.h\";\n"
1938 "}";
1939 CaptureStderr();
1940 EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1941 EXPECT_THAT(GetCapturedStderr(),
1942 HasSubstr("Unstructured parcelables should be at the root scope"));
1943 }
1944
TEST_F(AidlTest,RejectGenericTypeWithNestedTypes)1945 TEST_F(AidlTest, RejectGenericTypeWithNestedTypes) {
1946 const string input_path = "p/Foo.aidl";
1947 const string input =
1948 "package p;\n"
1949 "parcelable Foo<T> {\n"
1950 " parcelable Bar {}\n"
1951 "}";
1952 CaptureStderr();
1953 EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1954 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Generic types can't have nested types."));
1955 }
1956
TEST_F(AidlTest,HandleSyntaxErrorsInNestedDecl)1957 TEST_F(AidlTest, HandleSyntaxErrorsInNestedDecl) {
1958 const string input_path = "p/IFoo.aidl";
1959 const string input =
1960 "package p;\n"
1961 "interface IFoo {\n"
1962 " parcelable;\n" // missing identifier
1963 "}";
1964 CaptureStderr();
1965 EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1966 EXPECT_THAT(GetCapturedStderr(), HasSubstr("expecting identifier"));
1967 }
1968
TEST_F(AidlTest,RejectsNestedTypesWithDuplicateNames)1969 TEST_F(AidlTest, RejectsNestedTypesWithDuplicateNames) {
1970 const string input_path = "p/Foo.aidl";
1971 const string input =
1972 "package p;\n"
1973 "interface Foo {\n"
1974 " parcelable Bar {}\n"
1975 " parcelable Bar {}\n"
1976 "}";
1977 CaptureStderr();
1978 EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1979 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Redefinition of 'Bar'"));
1980 }
1981
TEST_F(AidlTest,TypeResolutionWithMultipleLevelsOfNesting)1982 TEST_F(AidlTest, TypeResolutionWithMultipleLevelsOfNesting) {
1983 struct Failure {
1984 string err;
1985 };
1986 struct TestCase {
1987 string type;
1988 variant<string, Failure> expected; // success<0> or failure<1>
1989 };
1990 vector<TestCase> cases = {
1991 {"foo.A", "foo.A"},
1992 {"foo.A.B", "foo.A.B"},
1993 {"@nullable(heap=true) A", "foo.A.B.A"},
1994 // In the scope of foo.A.B.A, B is resolved to A.B.A.B first.
1995 {"B.A", Failure{"Failed to resolve 'B.A'"}},
1996 {"B", "foo.A.B.A.B"},
1997 {"A.B", "foo.A.B.A.B"},
1998 };
1999 const string input_path = "foo/A.aidl";
2000 for (auto& [type, expected] : cases) {
2001 AidlTypenames typenames;
2002 // clang-format off
2003 const string input =
2004 "package foo;\n"
2005 "parcelable A {\n"
2006 " parcelable B {\n"
2007 " parcelable A {\n"
2008 " parcelable B {\n"
2009 " }\n"
2010 " " + type + " m;\n"
2011 " }\n"
2012 " }\n"
2013 "}";
2014 // clang-format on
2015 CaptureStderr();
2016 auto foo = Parse(input_path, input, typenames, Options::Language::CPP);
2017 if (auto failure = std::get_if<Failure>(&expected); failure) {
2018 ASSERT_EQ(nullptr, foo);
2019 EXPECT_THAT(GetCapturedStderr(), HasSubstr(failure->err));
2020 } else {
2021 EXPECT_EQ(GetCapturedStderr(), "");
2022 ASSERT_NE(nullptr, foo);
2023 EXPECT_EQ(TypeFinder::Get(*foo, "m"), std::get<string>(expected));
2024 }
2025 }
2026 }
2027
TEST_F(AidlTest,HeaderForNestedTypeShouldPointToTopMostParent)2028 TEST_F(AidlTest, HeaderForNestedTypeShouldPointToTopMostParent) {
2029 const string input_path = "p/IFoo.aidl";
2030 const string input =
2031 "package p;\n"
2032 "interface IFoo {\n"
2033 " parcelable Result {}\n"
2034 "}";
2035 CaptureStderr();
2036 auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
2037 ASSERT_NE(nullptr, foo);
2038 EXPECT_EQ(GetCapturedStderr(), "");
2039
2040 auto result = typenames_.ResolveTypename("p.IFoo.Result").defined_type;
2041 ASSERT_NE(nullptr, result);
2042 EXPECT_EQ("p/IFoo.h", cpp::CppHeaderForType(*result));
2043 }
2044
TEST_F(AidlTest,ReorderNestedTypesForCppOutput)2045 TEST_F(AidlTest, ReorderNestedTypesForCppOutput) {
2046 const string input_path = "p/IFoo.aidl";
2047 const string input = R"(
2048 package p;
2049 interface IFoo {
2050 // partial orderings for [A, D, G]:
2051 // D - A
2052 // A - G
2053 parcelable A {
2054 // partial orderings for [B, C]:
2055 // C - B
2056 parcelable B {
2057 C c;
2058 D.E d;
2059 }
2060 parcelable C {}
2061 }
2062 parcelable D {
2063 // partial orderings for [E, F]:
2064 // F - E
2065 parcelable E {
2066 F f;
2067 }
2068 parcelable F {}
2069 }
2070 parcelable G {
2071 A.B b;
2072 }
2073 }
2074 )";
2075 Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
2076 io_delegate_.SetFileContents(input_path, input);
2077 CaptureStderr();
2078 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2079 EXPECT_EQ(GetCapturedStderr(), "");
2080
2081 string code;
2082 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/IFoo.h", &code));
2083 // check partial orderings: a should comes before b
2084 EXPECT_LE(code.find("class D"), code.find("class A"));
2085 EXPECT_LE(code.find("class A"), code.find("class G"));
2086 EXPECT_LE(code.find("class C"), code.find("class B"));
2087 EXPECT_LE(code.find("class F"), code.find("class E"));
2088 }
2089
TEST_F(AidlTest,RejectsNestedTypesWithCyclicDeps)2090 TEST_F(AidlTest, RejectsNestedTypesWithCyclicDeps) {
2091 const string input_path = "p/IFoo.aidl";
2092 const string input = R"(
2093 package p;
2094 interface IFoo {
2095 // Cycles:
2096 // D - A
2097 // A - G
2098 // G - D
2099 parcelable A {
2100 parcelable B {
2101 C c;
2102 }
2103 }
2104 parcelable C {
2105 parcelable D {
2106 E e;
2107 }
2108 }
2109 parcelable E {
2110 parcelable F {
2111 A a;
2112 }
2113 }
2114 }
2115 )";
2116 Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
2117 io_delegate_.SetFileContents(input_path, input);
2118 CaptureStderr();
2119 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2120 EXPECT_THAT(GetCapturedStderr(), HasSubstr("IFoo has nested types with cyclic references."));
2121 }
2122
TEST_F(AidlTest,RejectsCyclicNestedInterfaces)2123 TEST_F(AidlTest, RejectsCyclicNestedInterfaces) {
2124 Options options = Options::From(
2125 "aidl --lang cpp -I. -oout -hout "
2126 "p/IFoo.aidl p/IBar.aidl p/IQux.aidl");
2127 io_delegate_.SetFileContents("p/IFoo.aidl",
2128 "package p; import p.IBar; "
2129 "interface IFoo { IBar getBar(); }");
2130 io_delegate_.SetFileContents("p/IBar.aidl",
2131 "package p; import p.IQux; "
2132 "interface IBar { IQux.Inner getQux(); }");
2133 io_delegate_.SetFileContents("p/IQux.aidl",
2134 "package p; import p.IFoo; "
2135 "interface IQux { interface Inner { IFoo getFoo(); } }");
2136 CaptureStderr();
2137 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2138 EXPECT_THAT(GetCapturedStderr(),
2139 HasSubstr("ERROR: p/IQux.aidl:1.43-53: has cyclic references to nested types."));
2140 }
2141
TEST_F(AidlTest,RejectsCyclicNestedInterfacesAndParcelables)2142 TEST_F(AidlTest, RejectsCyclicNestedInterfacesAndParcelables) {
2143 Options options = Options::From(
2144 "aidl --lang cpp -I. -oout -hout "
2145 "p/IFoo.aidl p/Bar.aidl");
2146 io_delegate_.SetFileContents("p/IFoo.aidl",
2147 "package p; import p.Bar; "
2148 "interface IFoo { interface Inner { Bar getBar(); } }");
2149 io_delegate_.SetFileContents("p/Bar.aidl",
2150 "package p; import p.IFoo; "
2151 "parcelable Bar { IFoo.Inner foo; }");
2152 CaptureStderr();
2153 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2154 EXPECT_THAT(GetCapturedStderr(),
2155 HasSubstr("ERROR: p/IFoo.aidl:1.42-52: has cyclic references to nested types."));
2156 }
2157
TEST_F(AidlTest,CppNameOf_GenericType)2158 TEST_F(AidlTest, CppNameOf_GenericType) {
2159 const string input_path = "p/Wrapper.aidl";
2160 const string input = "package p; parcelable Wrapper<T> {}";
2161
2162 auto parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
2163 EXPECT_NE(nullptr, parse_result);
2164
2165 auto type = [](std::string name, auto&&... type_params) -> std::unique_ptr<AidlTypeSpecifier> {
2166 auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>;
2167 (..., params->emplace_back(std::move(type_params)));
2168 return std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, name, std::nullopt, params,
2169 Comments{});
2170 };
2171
2172 auto set_nullable = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
2173 std::vector<std::unique_ptr<AidlAnnotation>> annotations;
2174 annotations.emplace_back(std::unique_ptr<AidlAnnotation>(
2175 AidlAnnotation::Parse(AIDL_LOCATION_HERE, "nullable", {}, {})));
2176 type->Annotate(std::move(annotations));
2177 return std::move(type);
2178 };
2179
2180 auto set_array = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
2181 (void)type->MakeArray(DynamicArray{});
2182 return std::move(type);
2183 };
2184
2185 auto w = type("p.Wrapper", type("String"));
2186 EXPECT_EQ("::p::Wrapper<::android::String16>", cpp::CppNameOf(*w, typenames_));
2187
2188 auto nullable_w = set_nullable(type("p.Wrapper", type("String")));
2189 EXPECT_EQ("::std::optional<::p::Wrapper<::android::String16>>",
2190 cpp::CppNameOf(*nullable_w, typenames_));
2191
2192 auto array_w = set_array(type("p.Wrapper", type("String")));
2193 EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
2194 cpp::CppNameOf(*array_w, typenames_));
2195
2196 auto nullable_array_w = set_nullable(set_array(type("p.Wrapper", type("String"))));
2197 EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
2198 cpp::CppNameOf(*nullable_array_w, typenames_));
2199
2200 auto list_w = type("List", type("p.Wrapper", type("String")));
2201 EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
2202 cpp::CppNameOf(*list_w, typenames_));
2203
2204 auto nullable_list_w = set_nullable(type("List", type("p.Wrapper", type("String"))));
2205 EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
2206 cpp::CppNameOf(*nullable_list_w, typenames_));
2207 }
2208
TEST_P(AidlTest,UnderstandsNativeParcelables)2209 TEST_P(AidlTest, UnderstandsNativeParcelables) {
2210 io_delegate_.SetFileContents(
2211 "p/Bar.aidl",
2212 "package p; parcelable Bar cpp_header \"baz/header\";");
2213 import_paths_.emplace("");
2214 const string input_path = "p/IFoo.aidl";
2215 const string input = "package p; import p.Bar; interface IFoo { }";
2216 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
2217 EXPECT_NE(nullptr, parse_result);
2218 EXPECT_TRUE(typenames_.ResolveTypename("p.Bar").is_resolved);
2219 AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", /*array=*/std::nullopt, nullptr, {});
2220 native_type.Resolve(typenames_, parse_result);
2221
2222 EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type));
2223 // C++ understands C++ specific stuff
2224 EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
2225 set<string> headers;
2226 cpp::AddHeaders(native_type, typenames_, &headers);
2227 EXPECT_EQ(1u, headers.size());
2228 EXPECT_EQ(1u, headers.count("baz/header"));
2229 }
2230
TEST_F(AidlTest,WritesCorrectDependencyFile)2231 TEST_F(AidlTest, WritesCorrectDependencyFile) {
2232 // While the in tree build system always gives us an output file name,
2233 // other android tools take advantage of our ability to infer the intended
2234 // file name. This test makes sure we handle this correctly.
2235 vector<string> args = {"aidl", "-I .", "-d dep/file/path", "-o place/for/output", "p/IFoo.aidl"};
2236 Options options = Options::From(args);
2237 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
2238 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2239 string actual_dep_file_contents;
2240 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2241 EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
2242 }
2243
TEST_F(AidlTest,WritesCorrectDependencyFileNinja)2244 TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
2245 // While the in tree build system always gives us an output file name,
2246 // other android tools take advantage of our ability to infer the intended
2247 // file name. This test makes sure we handle this correctly.
2248 vector<string> args = {"aidl", "-I .", "-d dep/file/path", "--ninja", "-o place/for/output",
2249 "p/IFoo.aidl"};
2250 Options options = Options::From(args);
2251 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
2252 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2253 string actual_dep_file_contents;
2254 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2255 EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
2256 }
2257
TEST_F(AidlTest,WritesTrivialDependencyFileForParcelableDeclaration)2258 TEST_F(AidlTest, WritesTrivialDependencyFileForParcelableDeclaration) {
2259 // The SDK uses aidl to decide whether a .aidl file is a parcelable. It does
2260 // this by calling aidl with every .aidl file it finds, then parsing the
2261 // generated dependency files. Those that reference .java output files are
2262 // for interfaces and those that do not are parcelables. However, for both
2263 // parcelables and interfaces, we *must* generate a non-empty dependency file.
2264 vector<string> args = {"aidl", "-I .", "-o place/for/output", "-d dep/file/path", "p/Foo.aidl"};
2265 Options options = Options::From(args);
2266 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
2267 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2268 string actual_dep_file_contents;
2269 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2270 EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDeclarationDepFileContents);
2271 }
2272
TEST_F(AidlTest,WritesDependencyFileForStructuredParcelable)2273 TEST_F(AidlTest, WritesDependencyFileForStructuredParcelable) {
2274 vector<string> args = {
2275 "aidl", "-I .", "--structured", "-o place/for/output", "-d dep/file/path", "p/Foo.aidl"};
2276 Options options = Options::From(args);
2277 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo {int a;}");
2278 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2279 string actual_dep_file_contents;
2280 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2281 EXPECT_EQ(actual_dep_file_contents, kExpectedStructuredParcelableDepFileContents);
2282 }
2283
TEST_F(AidlTest,NoJavaOutputForParcelableDeclaration)2284 TEST_F(AidlTest, NoJavaOutputForParcelableDeclaration) {
2285 vector<string> args = {"aidl", "-I .", "--lang=java", "-o place/for/output", "p/Foo.aidl"};
2286 Options options = Options::From(args);
2287 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
2288 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2289 string output_file_contents;
2290 EXPECT_FALSE(io_delegate_.GetWrittenContents(options.OutputFile(), &output_file_contents));
2291 }
2292
TEST_P(AidlTest,RejectsListArray)2293 TEST_P(AidlTest, RejectsListArray) {
2294 const string input = "package a; parcelable Foo { List<String>[] lists; }";
2295 CaptureStderr();
2296 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", input, typenames_, GetLanguage()));
2297 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Arrays of List are not supported"));
2298 }
2299
TEST_P(AidlTest,RejectsPrimitiveListInStableAidl)2300 TEST_P(AidlTest, RejectsPrimitiveListInStableAidl) {
2301 AidlError error;
2302 string expected_stderr =
2303 "ERROR: a/IFoo.aidl:2.7-11: "
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 if (GetLanguage() != Options::Language::JAVA) {
2308 expected_stderr =
2309 "ERROR: a/IFoo.aidl:2.1-7: "
2310 "Currently, only the Java backend supports non-generic List.\n";
2311 }
2312
2313 const string primitive_interface =
2314 "package a; interface IFoo {\n"
2315 " List foo(); }";
2316 CaptureStderr();
2317 AidlTypenames tn1;
2318 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_interface, tn1, GetLanguage(), &error,
2319 {"--structured"}));
2320 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2321
2322 string primitive_parcelable =
2323 "package a; parcelable IFoo {\n"
2324 " List foo;}";
2325 CaptureStderr();
2326 AidlTypenames tn2;
2327 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_parcelable, tn2, GetLanguage(), &error,
2328 {"--structured"}));
2329 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2330 }
2331
TEST_P(AidlTest,ExtensionTest)2332 TEST_P(AidlTest, ExtensionTest) {
2333 CaptureStderr();
2334 string extendable_parcelable =
2335 "package a; parcelable Data {\n"
2336 " ParcelableHolder extension;\n"
2337 " ParcelableHolder extension2;\n"
2338 "}";
2339 EXPECT_NE(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
2340 EXPECT_EQ("", GetCapturedStderr());
2341 }
2342
TEST_P(AidlTest,ParcelableHolderAsReturnType)2343 TEST_P(AidlTest, ParcelableHolderAsReturnType) {
2344 CaptureStderr();
2345 string parcelableholder_return_interface =
2346 "package a; interface IFoo {\n"
2347 " ParcelableHolder foo();\n"
2348 "}";
2349 EXPECT_EQ(nullptr,
2350 Parse("a/IFoo.aidl", parcelableholder_return_interface, typenames_, GetLanguage()));
2351
2352 EXPECT_EQ("ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n",
2353 GetCapturedStderr());
2354 }
2355
TEST_P(AidlTest,ParcelableHolderAsArgumentType)2356 TEST_P(AidlTest, ParcelableHolderAsArgumentType) {
2357 CaptureStderr();
2358 string extendable_parcelable_arg_interface =
2359 "package a; interface IFoo {\n"
2360 " void foo(in ParcelableHolder ph);\n"
2361 "}";
2362 EXPECT_EQ(nullptr,
2363 Parse("a/IFoo.aidl", extendable_parcelable_arg_interface, typenames_, GetLanguage()));
2364
2365 EXPECT_EQ("ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n",
2366 GetCapturedStderr());
2367 }
2368
TEST_P(AidlTest,RejectNullableParcelableHolderField)2369 TEST_P(AidlTest, RejectNullableParcelableHolderField) {
2370 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { @nullable ParcelableHolder ext; }");
2371 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2372 const string expected_stderr = "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n";
2373 CaptureStderr();
2374 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2375 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2376 }
2377
TEST_P(AidlTest,ParcelablesWithConstants)2378 TEST_P(AidlTest, ParcelablesWithConstants) {
2379 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { const int BIT = 0x1 << 3; }");
2380 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2381 CaptureStderr();
2382 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2383 EXPECT_EQ("", GetCapturedStderr());
2384 }
2385
TEST_P(AidlTest,UnionWithConstants)2386 TEST_P(AidlTest, UnionWithConstants) {
2387 io_delegate_.SetFileContents("Foo.aidl", "union Foo { const int BIT = 0x1 << 3; int n; }");
2388 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2389 CaptureStderr();
2390 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2391 EXPECT_EQ("", GetCapturedStderr());
2392 }
2393
TEST_F(AidlTest,ConstantsWithAnnotations)2394 TEST_F(AidlTest, ConstantsWithAnnotations) {
2395 io_delegate_.SetFileContents("IFoo.aidl",
2396 "interface IFoo {\n"
2397 " @JavaPassthrough(annotation=\"@Foo\")\n"
2398 " const @JavaPassthrough(annotation=\"@Bar\") int FOO = 0;\n"
2399 "}");
2400 Options options = Options::From("aidl IFoo.aidl -I . --lang=java -o out");
2401 CaptureStderr();
2402 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2403 EXPECT_EQ("", GetCapturedStderr());
2404 string code;
2405 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/IFoo.java", &code));
2406 EXPECT_THAT(code, HasSubstr("@Foo\n"));
2407 EXPECT_THAT(code, HasSubstr("@Bar\n"));
2408 }
2409
TEST_F(AidlTest,ApiDump)2410 TEST_F(AidlTest, ApiDump) {
2411 io_delegate_.SetFileContents(
2412 "foo/bar/IFoo.aidl",
2413 "// comment\n"
2414 "package foo.bar;\n"
2415 "import foo.bar.Data;\n"
2416 "// commented /* @hide */\n"
2417 "interface IFoo {\n"
2418 " /* @hide applied \n"
2419 " @deprecated use foo2 */\n"
2420 " int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
2421 " int foo2(@utf8InCpp String x, inout List<String> y);\n"
2422 " IFoo foo3(IFoo foo);\n"
2423 " void foo4(in int[2][3] fixedArray);\n"
2424 " Data getData();\n"
2425 " // @hide not applied\n"
2426 " /** blahblah\n"
2427 " @deprecated\n"
2428 " reason why... */\n"
2429 " const int A = 1;\n"
2430 " // @deprecated tags in line comments are ignored\n"
2431 " const String STR = \"Hello\";\n"
2432 "}\n");
2433 io_delegate_.SetFileContents("foo/bar/Data.aidl",
2434 "// comment\n"
2435 "package foo.bar;\n"
2436 "import foo.bar.IFoo;\n"
2437 "/* @hide*/\n"
2438 "parcelable Data {\n"
2439 " // @hide\n"
2440 " int x = 10;\n"
2441 " // @hide\n"
2442 " int y;\n"
2443 " /*@hide2*/\n"
2444 " IFoo foo;\n"
2445 " // Ignore @hide property in line comment\n"
2446 " @nullable String[] c;\n"
2447 "}\n");
2448 io_delegate_.SetFileContents("api.aidl", "");
2449 vector<string> args = {"aidl", "--dumpapi", "--out=dump", "--include=.",
2450 "foo/bar/IFoo.aidl", "foo/bar/Data.aidl"};
2451 Options options = Options::From(args);
2452 bool result = dump_api(options, io_delegate_);
2453 ASSERT_TRUE(result);
2454 string actual;
2455 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2456 EXPECT_EQ(string("// comment\n").append(string(kPreamble)).append(R"(package foo.bar;
2457 interface IFoo {
2458 /**
2459 * @hide
2460 * @deprecated use foo2
2461 */
2462 int foo(out int[] a, String b, boolean c, inout List<String> d);
2463 int foo2(@utf8InCpp String x, inout List<String> y);
2464 foo.bar.IFoo foo3(foo.bar.IFoo foo);
2465 void foo4(in int[2][3] fixedArray);
2466 foo.bar.Data getData();
2467 /**
2468 * @deprecated reason why...
2469 */
2470 const int A = 1;
2471 const String STR = "Hello";
2472 }
2473 )"),
2474 actual);
2475
2476 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
2477 EXPECT_EQ(string("// comment\n").append(string(kPreamble)).append(R"(package foo.bar;
2478 /* @hide */
2479 parcelable Data {
2480 int x = 10;
2481 int y;
2482 foo.bar.IFoo foo;
2483 @nullable String[] c;
2484 }
2485 )"),
2486 actual);
2487 }
2488
TEST_F(AidlTest,ApiDumpWithManualIds)2489 TEST_F(AidlTest, ApiDumpWithManualIds) {
2490 io_delegate_.SetFileContents(
2491 "foo/bar/IFoo.aidl",
2492 "package foo.bar;\n"
2493 "interface IFoo {\n"
2494 " int foo() = 1;\n"
2495 " int bar() = 2;\n"
2496 " int baz() = 10;\n"
2497 "}\n");
2498
2499 vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2500 Options options = Options::From(args);
2501 bool result = dump_api(options, io_delegate_);
2502 ASSERT_TRUE(result);
2503 string actual;
2504 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2505 EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
2506 interface IFoo {
2507 int foo() = 1;
2508 int bar() = 2;
2509 int baz() = 10;
2510 }
2511 )"));
2512 }
2513
TEST_F(AidlTest,ApiDumpWithManualIdsOnlyOnSomeMethods)2514 TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
2515 const string expected_stderr =
2516 "ERROR: foo/bar/IFoo.aidl:4.8-12: You must either assign id's to all methods or to none of "
2517 "them.\n";
2518 io_delegate_.SetFileContents(
2519 "foo/bar/IFoo.aidl",
2520 "package foo.bar;\n"
2521 "interface IFoo {\n"
2522 " int foo() = 1;\n"
2523 " int bar();\n"
2524 " int baz() = 10;\n"
2525 "}\n");
2526
2527 vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2528 Options options = Options::From(args);
2529 CaptureStderr();
2530 EXPECT_FALSE(dump_api(options, io_delegate_));
2531 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2532 }
2533
TEST_F(AidlTest,ApiDumpConstWithAnnotation)2534 TEST_F(AidlTest, ApiDumpConstWithAnnotation) {
2535 io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
2536 "package foo.bar;\n"
2537 "interface IFoo {\n"
2538 " @utf8InCpp String foo();\n"
2539 " const @utf8InCpp String bar = \"bar\";\n"
2540 "}\n");
2541
2542 vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2543 Options options = Options::From(args);
2544 CaptureStderr();
2545 EXPECT_TRUE(dump_api(options, io_delegate_));
2546 EXPECT_EQ("", GetCapturedStderr());
2547 string actual;
2548 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2549 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
2550 interface IFoo {
2551 @utf8InCpp String foo();
2552 const @utf8InCpp String bar = "bar";
2553 }
2554 )"),
2555 actual);
2556 }
2557
TEST_F(AidlTest,ApiDumpWithEnums)2558 TEST_F(AidlTest, ApiDumpWithEnums) {
2559 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
2560 "package foo.bar;\n"
2561 "enum Enum {\n"
2562 " FOO,\n"
2563 " BAR = FOO + 1,\n"
2564 "}\n");
2565
2566 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Enum.aidl"};
2567 Options options = Options::From(args);
2568 CaptureStderr();
2569 EXPECT_TRUE(dump_api(options, io_delegate_));
2570 EXPECT_EQ("", GetCapturedStderr());
2571 string actual;
2572 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
2573 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2574 "enum Enum {\n"
2575 " FOO,\n"
2576 " BAR = (FOO + 1) /* 1 */,\n"
2577 "}\n"),
2578 actual);
2579 }
2580
TEST_F(AidlTest,ApiDumpWithEnumDefaultValues)2581 TEST_F(AidlTest, ApiDumpWithEnumDefaultValues) {
2582 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
2583 "package foo.bar;\n"
2584 "enum Enum {\n"
2585 " FOO,\n"
2586 "}\n");
2587 io_delegate_.SetFileContents("foo/bar/Foo.aidl",
2588 "package foo.bar;\n"
2589 "import foo.bar.Enum;\n"
2590 "parcelable Foo {\n"
2591 " Enum e = Enum.FOO;\n"
2592 " int n = Enum.FOO;\n"
2593 "}\n");
2594
2595 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
2596 Options options = Options::From(args);
2597 CaptureStderr();
2598 EXPECT_TRUE(dump_api(options, io_delegate_));
2599 EXPECT_EQ("", GetCapturedStderr());
2600 string actual;
2601 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
2602 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2603 "parcelable Foo {\n"
2604 " foo.bar.Enum e = foo.bar.Enum.FOO;\n"
2605 " int n = foo.bar.Enum.FOO /* 0 */;\n"
2606 "}\n"),
2607 actual);
2608 }
2609
TEST_F(AidlTest,ApiDumpWithGenerics)2610 TEST_F(AidlTest, ApiDumpWithGenerics) {
2611 io_delegate_.SetFileContents("foo/bar/Foo.aidl",
2612 "package foo.bar;\n"
2613 "parcelable Foo<T, U> {\n"
2614 "}\n");
2615
2616 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
2617 Options options = Options::From(args);
2618 CaptureStderr();
2619 EXPECT_TRUE(dump_api(options, io_delegate_));
2620 EXPECT_EQ("", GetCapturedStderr());
2621 string actual;
2622 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
2623 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2624 "parcelable Foo<T, U> {\n"
2625 "}\n"),
2626 actual);
2627 }
2628
TEST_F(AidlTest,ImportedDocumentHasDuplicateDefinitions)2629 TEST_F(AidlTest, ImportedDocumentHasDuplicateDefinitions) {
2630 io_delegate_.SetFileContents("IFoo.aidl", "interface IFoo; interface IFoo;\n");
2631 io_delegate_.SetFileContents("Bar.aidl", "enum Bar { CONST = IFoo.NONE }\n");
2632
2633 vector<string> args = {"aidl", "--dumpapi", "-I.", "-o out", "Bar.aidl"};
2634 Options options = Options::From(args);
2635 CaptureStderr();
2636 EXPECT_FALSE(dump_api(options, io_delegate_));
2637 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Can't find NONE in IFoo"));
2638 }
2639
TEST_F(AidlTest,CheckNumGenericTypeSecifier)2640 TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
2641 const string expected_list_stderr =
2642 "ERROR: p/IFoo.aidl:1.37-41: List can only have one type parameter, but got: "
2643 "'List<String,String>'\n";
2644 const string expected_map_stderr =
2645 "ERROR: p/IFoo.aidl:1.37-40: Map must have 0 or 2 type parameters, but got 'Map<String>'\n";
2646 Options options = Options::From("aidl -I . p/IFoo.aidl IFoo.java");
2647 io_delegate_.SetFileContents(options.InputFiles().front(),
2648 "package p; interface IFoo {"
2649 "void foo(List<String, String> a);}");
2650 CaptureStderr();
2651 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2652 EXPECT_EQ(expected_list_stderr, GetCapturedStderr());
2653
2654 io_delegate_.SetFileContents(options.InputFiles().front(),
2655 "package p; interface IFoo {"
2656 "void foo(Map<String> a);}");
2657 CaptureStderr();
2658 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2659 EXPECT_EQ(expected_map_stderr, GetCapturedStderr());
2660 }
2661
TEST_F(AidlTest,CheckTypeParameterInMapType)2662 TEST_F(AidlTest, CheckTypeParameterInMapType) {
2663 const string expected_stderr =
2664 "ERROR: p/IFoo.aidl:1.28-31: The type of key in map must be String, but it is 'p.Bar'\n";
2665 Options options = Options::From("aidl -I . p/IFoo.aidl");
2666 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar { String s; }");
2667
2668 io_delegate_.SetFileContents("p/IFoo.aidl",
2669 "package p; interface IFoo {"
2670 "Map<String, p.Bar> foo();}");
2671 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2672
2673 io_delegate_.SetFileContents("p/IFoo.aidl",
2674 "package p; interface IFoo {"
2675 "Map<p.Bar, p.Bar> foo();}");
2676 CaptureStderr();
2677 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2678 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2679
2680 io_delegate_.SetFileContents("p/IFoo.aidl",
2681 "package p; interface IFoo {"
2682 "Map<String, String> foo();}");
2683 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2684
2685 io_delegate_.SetFileContents("p/IFoo.aidl",
2686 "package p; interface IFoo {"
2687 "Map<String, ParcelFileDescriptor> foo();}");
2688 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2689 }
2690
TEST_F(AidlTest,WrongGenericType)2691 TEST_F(AidlTest, WrongGenericType) {
2692 const string expected_stderr = "ERROR: p/IFoo.aidl:1.28-34: String is not a generic type.\n";
2693 Options options = Options::From("aidl -I . p/IFoo.aidl IFoo.java");
2694 io_delegate_.SetFileContents(options.InputFiles().front(),
2695 "package p; interface IFoo {"
2696 "String<String> foo(); }");
2697 CaptureStderr();
2698 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2699 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2700 }
2701
TEST_F(AidlTest,UserDefinedUnstructuredGenericParcelableType)2702 TEST_F(AidlTest, UserDefinedUnstructuredGenericParcelableType) {
2703 Options optionsForParcelable = Options::From("aidl -I . p/Bar.aidl");
2704 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, T>;");
2705 CaptureStderr();
2706 EXPECT_FALSE(compile_aidl(optionsForParcelable, io_delegate_));
2707 EXPECT_EQ("ERROR: p/Bar.aidl:1.22-26: Every type parameter should be unique.\n",
2708 GetCapturedStderr());
2709
2710 Options options = Options::From("aidl -I . p/IFoo.aidl");
2711 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar;");
2712 io_delegate_.SetFileContents("p/IFoo.aidl",
2713 "package p; interface IFoo {"
2714 "p.Bar<String, String> foo();}");
2715 CaptureStderr();
2716 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2717 EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar is not a generic type"));
2718 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T>;");
2719 CaptureStderr();
2720 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2721 EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar must have 1 type parameters, but got 2"));
2722 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, V>;");
2723 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2724 io_delegate_.SetFileContents("p/IFoo.aidl",
2725 "package p; interface IFoo {"
2726 "p.Bar<String, ParcelFileDescriptor> foo();}");
2727 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2728
2729 io_delegate_.SetFileContents("p/IFoo.aidl",
2730 "package p; interface IFoo {"
2731 "p.Bar<int, long> foo();}");
2732
2733 io_delegate_.SetFileContents("p/IFoo.aidl",
2734 "package p; interface IFoo {"
2735 "p.Bar<int[], long[]> foo();}");
2736
2737 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2738 }
2739
TEST_F(AidlTest,FailOnMultipleTypesInSingleFile)2740 TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
2741 std::vector<std::string> rawOptions{"aidl --lang=java -I . -o out foo/bar/Foo.aidl",
2742 "aidl --lang=cpp -I . -o out -h out/include foo/bar/Foo.aidl",
2743 "aidl --lang=rust -I . -o out foo/bar/Foo.aidl"};
2744 for (const auto& rawOption : rawOptions) {
2745 string expected_stderr =
2746 "ERROR: foo/bar/Foo.aidl:3.1-10: You must declare only one type per file.\n";
2747 Options options = Options::From(rawOption);
2748 io_delegate_.SetFileContents(options.InputFiles().front(),
2749 "package foo.bar;\n"
2750 "interface IFoo1 { int foo(); }\n"
2751 "interface IFoo2 { int foo(); }\n"
2752 "parcelable Data1 { int a; int b;}\n"
2753 "parcelable Data2 { int a; int b;}\n");
2754 CaptureStderr();
2755 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2756 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2757
2758 io_delegate_.SetFileContents(options.InputFiles().front(),
2759 "package foo.bar;\n"
2760 "interface IFoo1 { int foo(); }\n"
2761 "interface IFoo2 { int foo(); }\n");
2762 CaptureStderr();
2763 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2764 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2765
2766 expected_stderr = "ERROR: foo/bar/Foo.aidl:3.11-17: You must declare only one type per file.\n";
2767 io_delegate_.SetFileContents(options.InputFiles().front(),
2768 "package foo.bar;\n"
2769 "parcelable Data1 { int a; int b;}\n"
2770 "parcelable Data2 { int a; int b;}\n");
2771 CaptureStderr();
2772 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2773 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2774 }
2775 }
2776
TEST_P(AidlTest,FailParseOnEmptyFile)2777 TEST_P(AidlTest, FailParseOnEmptyFile) {
2778 const string contents = "";
2779 const string expected_stderr = "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected $end\n";
2780 const string expected_stderr_newbison =
2781 "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected end of file\n";
2782 CaptureStderr();
2783 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", contents, typenames_, GetLanguage()));
2784 EXPECT_THAT(GetCapturedStderr(),
2785 testing::AnyOf(testing::Eq(expected_stderr), testing::Eq(expected_stderr_newbison)));
2786 }
2787
TEST_F(AidlTest,MultipleInputFiles)2788 TEST_F(AidlTest, MultipleInputFiles) {
2789 Options options = Options::From(
2790 "aidl --lang=java -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2791
2792 io_delegate_.SetFileContents(options.InputFiles().at(0),
2793 "package foo.bar;\n"
2794 "import foo.bar.Data;\n"
2795 "interface IFoo { Data getData(); }\n");
2796
2797 io_delegate_.SetFileContents(options.InputFiles().at(1),
2798 "package foo.bar;\n"
2799 "import foo.bar.IFoo;\n"
2800 "parcelable Data { IFoo foo; }\n");
2801
2802 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2803
2804 string content;
2805 for (const auto file : {
2806 "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
2807 content.clear();
2808 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2809 EXPECT_FALSE(content.empty());
2810 }
2811 }
2812
TEST_F(AidlTest,MultipleInputFilesCpp)2813 TEST_F(AidlTest, MultipleInputFilesCpp) {
2814 Options options = Options::From(
2815 "aidl --lang=cpp -I . -o out -h out/include "
2816 "-I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2817
2818 io_delegate_.SetFileContents(options.InputFiles().at(0),
2819 "package foo.bar;\n"
2820 "import foo.bar.Data;\n"
2821 "interface IFoo { Data getData(); }\n");
2822
2823 io_delegate_.SetFileContents(options.InputFiles().at(1),
2824 "package foo.bar;\n"
2825 "import foo.bar.IFoo;\n"
2826 "parcelable Data { IFoo foo; }\n");
2827
2828 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2829
2830 string content;
2831 for (const auto file : {
2832 "out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp",
2833 "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
2834 "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
2835 "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
2836 content.clear();
2837 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2838 EXPECT_FALSE(content.empty());
2839 }
2840 }
2841
TEST_F(AidlTest,MultipleInputFilesRust)2842 TEST_F(AidlTest, MultipleInputFilesRust) {
2843 Options options =
2844 Options::From("aidl --lang=rust -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2845
2846 io_delegate_.SetFileContents(options.InputFiles().at(0),
2847 "package foo.bar;\n"
2848 "import foo.bar.Data;\n"
2849 "interface IFoo { Data getData(); }\n");
2850
2851 io_delegate_.SetFileContents(options.InputFiles().at(1),
2852 "package foo.bar;\n"
2853 "import foo.bar.IFoo;\n"
2854 "parcelable Data { IFoo foo; }\n");
2855
2856 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2857
2858 string content;
2859 for (const auto file : {"out/foo/bar/IFoo.rs", "out/foo/bar/Data.rs"}) {
2860 content.clear();
2861 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2862 EXPECT_FALSE(content.empty());
2863 }
2864 }
2865
TEST_F(AidlTest,ConflictWithMetaTransactionGetVersion)2866 TEST_F(AidlTest, ConflictWithMetaTransactionGetVersion) {
2867 const string expected_stderr =
2868 "ERROR: p/IFoo.aidl:1.31-51: method getInterfaceVersion() is reserved for internal use.\n";
2869 Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
2870 // int getInterfaceVersion() is one of the meta transactions
2871 io_delegate_.SetFileContents(options.InputFiles().front(),
2872 "package p; interface IFoo {"
2873 "int getInterfaceVersion(); }");
2874 CaptureStderr();
2875 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2876 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2877 }
2878
TEST_F(AidlTest,ConflictWithSimilarMetaTransaction)2879 TEST_F(AidlTest, ConflictWithSimilarMetaTransaction) {
2880 // boolean getInterfaceVersion() is not a meta transaction, but should be
2881 // prevented because return type is not part of a method signature
2882 const string expected_stderr =
2883 "ERROR: p/IFoo.aidl:1.35-55: method getInterfaceVersion() is reserved for internal use.\n";
2884 Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
2885 io_delegate_.SetFileContents(options.InputFiles().front(),
2886 "package p; interface IFoo {"
2887 "boolean getInterfaceVersion(); }");
2888 CaptureStderr();
2889 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2890 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2891 }
2892
TEST_F(AidlTest,ConflictWithMetaTransactionGetName)2893 TEST_F(AidlTest, ConflictWithMetaTransactionGetName) {
2894 // this is another reserved name
2895 const string expected_stderr =
2896 "ERROR: p/IFoo.aidl:1.34-53: method getTransactionName(int) is reserved for internal use.\n";
2897 Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
2898 io_delegate_.SetFileContents(options.InputFiles().front(),
2899 "package p; interface IFoo {"
2900 "String getTransactionName(int code); }");
2901 CaptureStderr();
2902 EXPECT_FALSE(compile_aidl(options, io_delegate_));
2903 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2904
2905 // this is not a meta interface method as it differs type arguments
2906 io_delegate_.SetFileContents(options.InputFiles().front(),
2907 "package p; interface IFoo {"
2908 "String getTransactionName(); }");
2909 EXPECT_TRUE(compile_aidl(options, io_delegate_));
2910 }
2911
TEST_F(AidlTest,CheckApiForEquality)2912 TEST_F(AidlTest, CheckApiForEquality) {
2913 CaptureStderr();
2914 Options options = Options::From("aidl --checkapi=equal old new");
2915
2916 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2917 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
2918 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2919 "package p; interface IFoo{ @utf8InCpp String foo();}");
2920
2921 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
2922 EXPECT_THAT(GetCapturedStderr(), HasSubstr("+ @utf8InCpp String foo();"));
2923 }
2924
TEST_F(AidlTest,DifferentOrderAnnotationsInCheckAPI)2925 TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
2926 Options options = Options::From("aidl --checkapi old new");
2927 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2928 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
2929 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2930 "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
2931
2932 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2933 }
2934
TEST_F(AidlTest,SuccessOnIdenticalApiDumps)2935 TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
2936 Options options = Options::From("aidl --checkapi old new");
2937 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
2938 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
2939
2940 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2941 }
2942
TEST_F(AidlTest,CheckApi_EnumFieldsWithDefaultValues)2943 TEST_F(AidlTest, CheckApi_EnumFieldsWithDefaultValues) {
2944 Options options = Options::From("aidl --checkapi old new");
2945 const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
2946 const string enum_definition = "package p; enum Enum { FOO }";
2947 io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
2948 io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
2949 io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
2950 io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
2951
2952 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2953 }
2954
TEST_F(AidlTest,CheckApi_EnumFieldsFromImported)2955 TEST_F(AidlTest, CheckApi_EnumFieldsFromImported) {
2956 Options options = Options::From("aidl --checkapi old new -I import");
2957
2958 io_delegate_.SetFileContents("old/p/Foo.aidl", "package p; parcelable Foo{ other.Enum e; }");
2959 io_delegate_.SetFileContents("new/p/Foo.aidl",
2960 "package p; parcelable Foo{ other.Enum e = other.Enum.FOO; }");
2961 io_delegate_.SetFileContents("import/other/Enum.aidl", "package other; enum Enum { FOO }");
2962
2963 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2964 }
2965
TEST_F(AidlTest,CheckApiEqual_EnumFieldsWithDefaultValues)2966 TEST_F(AidlTest, CheckApiEqual_EnumFieldsWithDefaultValues) {
2967 Options options = Options::From("aidl --checkapi=equal old new");
2968 const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
2969 const string enum_definition = "package p; enum Enum { FOO }";
2970 io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
2971 io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
2972 io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
2973 io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
2974 CaptureStderr();
2975 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2976 EXPECT_EQ("", GetCapturedStderr());
2977 }
2978
2979 class AidlTestCompatibleChanges : public AidlTest {
2980 protected:
2981 Options options_ = Options::From("aidl --checkapi old new");
2982 };
2983
TEST_F(AidlTestCompatibleChanges,NewType)2984 TEST_F(AidlTestCompatibleChanges, NewType) {
2985 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2986 "package p;"
2987 "interface IFoo {"
2988 " void foo(int a);"
2989 "}");
2990 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2991 "package p;"
2992 "interface IFoo {"
2993 " void foo(int a);"
2994 "}");
2995 io_delegate_.SetFileContents("new/p/IBar.aidl",
2996 "package p;"
2997 "interface IBar {"
2998 " void bar();"
2999 "}");
3000 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3001 }
3002
TEST_F(AidlTestCompatibleChanges,NewMethod)3003 TEST_F(AidlTestCompatibleChanges, NewMethod) {
3004 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3005 "package p;"
3006 "interface IFoo {"
3007 " void foo(int a);"
3008 "}");
3009 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3010 "package p;"
3011 "interface IFoo {"
3012 " void foo(int a);"
3013 " void bar();"
3014 " void baz(in List<String> arg);"
3015 "}");
3016 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3017 }
3018
TEST_F(AidlTestCompatibleChanges,NewField)3019 TEST_F(AidlTestCompatibleChanges, NewField) {
3020 io_delegate_.SetFileContents("old/p/Data.aidl",
3021 "package p;"
3022 "parcelable Data {"
3023 " int foo;"
3024 "}");
3025 io_delegate_.SetFileContents("new/p/Data.aidl",
3026 "package p;"
3027 "parcelable Data {"
3028 " int foo;"
3029 " int bar = 0;"
3030 " @nullable List<Data> list;"
3031 "}");
3032 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3033 }
3034
TEST_F(AidlTestCompatibleChanges,NewField2)3035 TEST_F(AidlTestCompatibleChanges, NewField2) {
3036 io_delegate_.SetFileContents("old/p/Data.aidl",
3037 "package p;"
3038 "parcelable Data {"
3039 "}");
3040 io_delegate_.SetFileContents("new/p/Data.aidl",
3041 "package p;"
3042 "parcelable Data {"
3043 " int foo = 0;"
3044 "}");
3045 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3046 }
3047
TEST_F(AidlTestCompatibleChanges,NewEnumerator)3048 TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
3049 io_delegate_.SetFileContents("old/p/Enum.aidl",
3050 "package p;"
3051 "enum Enum {"
3052 " FOO = 1,"
3053 "}");
3054 io_delegate_.SetFileContents("new/p/Enum.aidl",
3055 "package p;"
3056 "enum Enum {"
3057 " FOO = 1,"
3058 " BAR = 2,"
3059 "}");
3060 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3061 }
3062
TEST_F(AidlTestCompatibleChanges,ReorderedEnumerator)3063 TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
3064 io_delegate_.SetFileContents("old/p/Enum.aidl",
3065 "package p;"
3066 "enum Enum {"
3067 " FOO = 1,"
3068 " BAR = 2,"
3069 "}");
3070 io_delegate_.SetFileContents("new/p/Enum.aidl",
3071 "package p;"
3072 "enum Enum {"
3073 " BAR = 2,"
3074 " FOO = 1,"
3075 "}");
3076 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3077 }
3078
TEST_F(AidlTestCompatibleChanges,NewUnionField)3079 TEST_F(AidlTestCompatibleChanges, NewUnionField) {
3080 io_delegate_.SetFileContents("old/p/Union.aidl",
3081 "package p;"
3082 "union Union {"
3083 " String foo;"
3084 "}");
3085 io_delegate_.SetFileContents("new/p/Union.aidl",
3086 "package p;"
3087 "union Union {"
3088 " String foo;"
3089 " int num;"
3090 "}");
3091 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3092 }
3093
TEST_F(AidlTestCompatibleChanges,NewPackage)3094 TEST_F(AidlTestCompatibleChanges, NewPackage) {
3095 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3096 "package p;"
3097 "interface IFoo {"
3098 " void foo(int a);"
3099 "}");
3100 io_delegate_.SetFileContents("old/p/Data.aidl",
3101 "package p;"
3102 "parcelable Data {"
3103 " int foo;"
3104 "}");
3105 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3106 "package p;"
3107 "interface IFoo {"
3108 " void foo(int a);"
3109 "}");
3110 io_delegate_.SetFileContents("new/p/Data.aidl",
3111 "package p;"
3112 "parcelable Data {"
3113 " int foo;"
3114 "}");
3115 io_delegate_.SetFileContents("new/q/IFoo.aidl",
3116 "package q;"
3117 "interface IFoo {"
3118 " void foo(int a);"
3119 "}");
3120 io_delegate_.SetFileContents("new/q/Data.aidl",
3121 "package q;"
3122 "parcelable Data {"
3123 " int foo;"
3124 "}");
3125 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3126 }
3127
TEST_F(AidlTestCompatibleChanges,ArgNameChange)3128 TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
3129 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3130 "package p;"
3131 "interface IFoo {"
3132 " void foo(int a);"
3133 "}");
3134 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3135 "package p;"
3136 "interface IFoo {"
3137 " void foo(int b);"
3138 "}");
3139 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3140 }
3141
TEST_F(AidlTestCompatibleChanges,AddedConstValue)3142 TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
3143 io_delegate_.SetFileContents("old/p/I.aidl",
3144 "package p; interface I {"
3145 "const int A = 1; }");
3146 io_delegate_.SetFileContents("new/p/I.aidl",
3147 "package p ; interface I {"
3148 "const int A = 1; const int B = 2;}");
3149 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3150 }
3151
TEST_F(AidlTestCompatibleChanges,ChangedConstValueOrder)3152 TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
3153 io_delegate_.SetFileContents("old/p/I.aidl",
3154 "package p; interface I {"
3155 "const int A = 1; const int B = 2;}");
3156 io_delegate_.SetFileContents("new/p/I.aidl",
3157 "package p ; interface I {"
3158 "const int B = 2; const int A = 1;}");
3159 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3160 }
3161
TEST_F(AidlTestCompatibleChanges,ReorderedAnnatations)3162 TEST_F(AidlTestCompatibleChanges, ReorderedAnnatations) {
3163 io_delegate_.SetFileContents("old/p/Foo.aidl",
3164 "package p;"
3165 "@JavaPassthrough(annotation=\"Alice\")"
3166 "@JavaPassthrough(annotation=\"Bob\")"
3167 "parcelable Foo {}");
3168 io_delegate_.SetFileContents("new/p/Foo.aidl",
3169 "package p;"
3170 "@JavaPassthrough(annotation=\"Bob\")"
3171 "@JavaPassthrough(annotation=\"Alice\")"
3172 "parcelable Foo {}");
3173 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3174 }
3175
TEST_F(AidlTestCompatibleChanges,OkayToDeprecate)3176 TEST_F(AidlTestCompatibleChanges, OkayToDeprecate) {
3177 io_delegate_.SetFileContents("old/p/Foo.aidl",
3178 "package p;"
3179 "parcelable Foo {}");
3180 io_delegate_.SetFileContents("new/p/Foo.aidl",
3181 "package p;"
3182 "@JavaPassthrough(annotation=\"@Deprecated\")"
3183 "parcelable Foo {}");
3184 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3185 }
3186
TEST_F(AidlTestCompatibleChanges,NewFieldOfNewType)3187 TEST_F(AidlTestCompatibleChanges, NewFieldOfNewType) {
3188 io_delegate_.SetFileContents("old/p/Data.aidl",
3189 "package p;"
3190 "parcelable Data {"
3191 " int num;"
3192 "}");
3193 io_delegate_.SetFileContents(
3194 "new/p/Data.aidl",
3195 "package p;"
3196 "parcelable Data {"
3197 " int num;"
3198 " p.Enum e;" // this is considered as valid since 0(enum default) is valid for "Enum" type
3199 "}");
3200 io_delegate_.SetFileContents("new/p/Enum.aidl",
3201 "package p;"
3202 "enum Enum {"
3203 " FOO = 0,"
3204 " BAR = 1,"
3205 "}");
3206 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3207 }
3208
TEST_F(AidlTestCompatibleChanges,CompatibleExplicitDefaults)3209 TEST_F(AidlTestCompatibleChanges, CompatibleExplicitDefaults) {
3210 io_delegate_.SetFileContents("old/p/Data.aidl",
3211 "package p;\n"
3212 "parcelable Data {\n"
3213 " p.Enum e;\n"
3214 "}");
3215 io_delegate_.SetFileContents("old/p/Enum.aidl",
3216 "package p;\n"
3217 "enum Enum {\n"
3218 " FOO = 0,\n"
3219 " BAR = 1,\n"
3220 "}");
3221 io_delegate_.SetFileContents("new/p/Data.aidl",
3222 "package p;\n"
3223 "parcelable Data {\n"
3224 " p.Enum e = p.Enum.FOO;\n"
3225 "}");
3226 io_delegate_.SetFileContents("new/p/Enum.aidl",
3227 "package p;\n"
3228 "enum Enum {\n"
3229 " FOO = 0,\n"
3230 " BAR = 1,\n"
3231 "}");
3232 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3233 }
3234
TEST_F(AidlTestCompatibleChanges,NewNestedTypes)3235 TEST_F(AidlTestCompatibleChanges, NewNestedTypes) {
3236 io_delegate_.SetFileContents("old/p/Data.aidl",
3237 "package p;\n"
3238 "parcelable Data {\n"
3239 " int n;\n"
3240 "}");
3241 io_delegate_.SetFileContents("new/p/Data.aidl",
3242 "package p;\n"
3243 "parcelable Data {\n"
3244 " enum NewEnum { N = 3 }\n"
3245 " int n;\n"
3246 " NewEnum e = NewEnum.N;\n"
3247 "}");
3248 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3249 }
3250
TEST_F(AidlTestCompatibleChanges,NewJavaSuppressLint)3251 TEST_F(AidlTestCompatibleChanges, NewJavaSuppressLint) {
3252 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3253 "package p;"
3254 "interface IFoo {"
3255 " void foo(int a);"
3256 "}");
3257 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3258 "package p;"
3259 "@JavaSuppressLint({\"NewApi\"})"
3260 "interface IFoo {"
3261 " void foo(int a);"
3262 "}");
3263 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3264 }
3265
3266 class AidlTestIncompatibleChanges : public AidlTest {
3267 protected:
3268 Options options_ = Options::From("aidl --checkapi old new");
3269 };
3270
TEST_F(AidlTestIncompatibleChanges,RemovedType)3271 TEST_F(AidlTestIncompatibleChanges, RemovedType) {
3272 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
3273 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3274 "package p;"
3275 "interface IFoo {"
3276 " void foo(in String[] str);"
3277 " void bar(@utf8InCpp String str);"
3278 "}");
3279 CaptureStderr();
3280 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3281 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3282 }
3283
TEST_F(AidlTestIncompatibleChanges,RemovedMethod)3284 TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
3285 const string expected_stderr =
3286 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
3287 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3288 "package p;"
3289 "interface IFoo {"
3290 " void foo(in String[] str);"
3291 " void bar(@utf8InCpp String str);"
3292 "}");
3293 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3294 "package p;"
3295 "interface IFoo {"
3296 " void foo(in String[] str);"
3297 "}");
3298 CaptureStderr();
3299 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3300 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3301 }
3302
TEST_F(AidlTestIncompatibleChanges,UntypedListInInterface)3303 TEST_F(AidlTestIncompatibleChanges, UntypedListInInterface) {
3304 const string expected_stderr =
3305 "ERROR: new/p/IFoo.aidl:1.61-65: "
3306 "Encountered an untyped List or Map. The use of untyped List/Map is "
3307 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3308 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3309 "ERROR: new/p/IFoo.aidl: Failed to read.\n";
3310 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3311 "package p;"
3312 "interface IFoo {"
3313 " void foo(in String[] str);"
3314 "}");
3315 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3316 "package p;"
3317 "interface IFoo {"
3318 " void foo(in String[] str);"
3319 " void bar(in List arg);"
3320 "}");
3321 CaptureStderr();
3322 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3323 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3324 }
3325
TEST_F(AidlTestCompatibleChanges,UntypedListInParcelable)3326 TEST_F(AidlTestCompatibleChanges, UntypedListInParcelable) {
3327 const string expected_stderr =
3328 "ERROR: new/p/Data.aidl:1.54-59: "
3329 "Encountered an untyped List or Map. The use of untyped List/Map is "
3330 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3331 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3332 "ERROR: new/p/Data.aidl: Failed to read.\n";
3333 io_delegate_.SetFileContents("old/p/Data.aidl",
3334 "package p;"
3335 "parcelable Data {"
3336 " int foo;"
3337 "}");
3338 io_delegate_.SetFileContents("new/p/Data.aidl",
3339 "package p;"
3340 "parcelable Data {"
3341 " int foo;"
3342 " @nullable List list;"
3343 "}");
3344 CaptureStderr();
3345 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3346 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3347 }
3348
TEST_F(AidlTestIncompatibleChanges,RemovedField)3349 TEST_F(AidlTestIncompatibleChanges, RemovedField) {
3350 const string expected_stderr =
3351 "ERROR: new/p/Data.aidl:1.21-26: Number of fields in p.Data is reduced from 2 to 1.\n";
3352 io_delegate_.SetFileContents("old/p/Data.aidl",
3353 "package p;"
3354 "parcelable Data {"
3355 " int foo;"
3356 " int bar;"
3357 "}");
3358 io_delegate_.SetFileContents("new/p/Data.aidl",
3359 "package p;"
3360 "parcelable Data {"
3361 " int foo;"
3362 "}");
3363 CaptureStderr();
3364 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3365 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3366 }
3367
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNoDefault)3368 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNoDefault) {
3369 const string expected_stderr =
3370 "ERROR: new/p/Data.aidl:1.46-50: Field 'str' does not have a useful default in some "
3371 "backends. Please either provide a default value for this field or mark the field as "
3372 "@nullable. This value or a null value will be used automatically when an old version of "
3373 "this parcelable is sent to a process which understands a new version of this parcelable. In "
3374 "order to make sure your code continues to be backwards compatible, make sure the default or "
3375 "null value does not cause a semantic change to this parcelable.\n";
3376 io_delegate_.SetFileContents("old/p/Data.aidl",
3377 "package p;"
3378 "parcelable Data {"
3379 " int num;"
3380 "}");
3381 io_delegate_.SetFileContents("new/p/Data.aidl",
3382 "package p;"
3383 "parcelable Data {"
3384 " int num;"
3385 " String str;"
3386 "}");
3387 CaptureStderr();
3388 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3389 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3390 }
3391
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNonZeroEnum)3392 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNonZeroEnum) {
3393 const string expected_stderr =
3394 "ERROR: new/p/Data.aidl:1.46-48: Field 'e' of enum 'Enum' can't be initialized as '0'. "
3395 "Please make sure 'Enum' has '0' as a valid value.\n";
3396 io_delegate_.SetFileContents("old/p/Data.aidl",
3397 "package p;"
3398 "parcelable Data {"
3399 " int num;"
3400 "}");
3401 io_delegate_.SetFileContents("new/p/Data.aidl",
3402 "package p;"
3403 "parcelable Data {"
3404 " int num;"
3405 " p.Enum e;"
3406 "}");
3407 io_delegate_.SetFileContents("new/p/Enum.aidl",
3408 "package p;"
3409 "enum Enum {"
3410 " FOO = 1,"
3411 " BAR = 2,"
3412 "}");
3413 CaptureStderr();
3414 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3415 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3416 }
3417
TEST_F(AidlTestIncompatibleChanges,RemovedEnumerator)3418 TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
3419 const string expected_stderr =
3420 "ERROR: new/p/Enum.aidl:1.15-20: Removed enumerator from p.Enum: FOO\n";
3421 io_delegate_.SetFileContents("old/p/Enum.aidl",
3422 "package p;"
3423 "enum Enum {"
3424 " FOO = 1,"
3425 " BAR = 2,"
3426 "}");
3427 io_delegate_.SetFileContents("new/p/Enum.aidl",
3428 "package p;"
3429 "enum Enum {"
3430 " BAR = 2,"
3431 "}");
3432 CaptureStderr();
3433 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3434 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3435 }
3436
TEST_F(AidlTestIncompatibleChanges,RemovedUnionField)3437 TEST_F(AidlTestIncompatibleChanges, RemovedUnionField) {
3438 const string expected_stderr =
3439 "ERROR: new/p/Union.aidl:1.16-22: Number of fields in p.Union is reduced from 2 to 1.\n";
3440 io_delegate_.SetFileContents("old/p/Union.aidl",
3441 "package p;"
3442 "union Union {"
3443 " String str;"
3444 " int num;"
3445 "}");
3446 io_delegate_.SetFileContents("new/p/Union.aidl",
3447 "package p;"
3448 "union Union {"
3449 " String str;"
3450 "}");
3451 CaptureStderr();
3452 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3453 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3454 }
3455
TEST_F(AidlTestIncompatibleChanges,RenamedMethod)3456 TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
3457 const string expected_stderr =
3458 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
3459 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3460 "package p;"
3461 "interface IFoo {"
3462 " void foo(in String[] str);"
3463 " void bar(@utf8InCpp String str);"
3464 "}");
3465 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3466 "package p;"
3467 "interface IFoo {"
3468 " void foo(in String[] str);"
3469 " void bar2(@utf8InCpp String str);"
3470 "}");
3471 CaptureStderr();
3472 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3473 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3474 }
3475
TEST_F(AidlTestIncompatibleChanges,RenamedType)3476 TEST_F(AidlTestIncompatibleChanges, RenamedType) {
3477 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
3478 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3479 "package p;"
3480 "interface IFoo {"
3481 " void foo(in String[] str);"
3482 " void bar(@utf8InCpp String str);"
3483 "}");
3484 io_delegate_.SetFileContents("new/p/IFoo2.aidl",
3485 "package p;"
3486 "interface IFoo2 {"
3487 " void foo(in String[] str);"
3488 " void bar(@utf8InCpp String str);"
3489 "}");
3490 CaptureStderr();
3491 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3492 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3493 }
3494
TEST_F(AidlTestIncompatibleChanges,ChangedEnumerator)3495 TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
3496 const string expected_stderr =
3497 "ERROR: new/p/Enum.aidl:1.15-20: Changed enumerator value: p.Enum::FOO from 1 to 3.\n";
3498 io_delegate_.SetFileContents("old/p/Enum.aidl",
3499 "package p;"
3500 "enum Enum {"
3501 " FOO = 1,"
3502 " BAR = 2,"
3503 "}");
3504 io_delegate_.SetFileContents("new/p/Enum.aidl",
3505 "package p;"
3506 "enum Enum {"
3507 " FOO = 3,"
3508 " BAR = 2,"
3509 "}");
3510 CaptureStderr();
3511 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3512 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3513 }
3514
TEST_F(AidlTestIncompatibleChanges,ReorderedMethod)3515 TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
3516 const string expected_stderr =
3517 "ERROR: new/p/IFoo.aidl:1.67-71: Transaction ID changed: p.IFoo.foo(String[]) is changed "
3518 "from 0 to 1.\n"
3519 "ERROR: new/p/IFoo.aidl:1.33-37: Transaction ID changed: p.IFoo.bar(String) is changed from "
3520 "1 to 0.\n";
3521 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3522 "package p;"
3523 "interface IFoo {"
3524 " void foo(in String[] str);"
3525 " void bar(@utf8InCpp String str);"
3526 "}");
3527 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3528 "package p;"
3529 "interface IFoo {"
3530 " void bar(@utf8InCpp String str);"
3531 " void foo(in String[] str);"
3532 "}");
3533 CaptureStderr();
3534 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3535 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3536 }
3537
TEST_F(AidlTestIncompatibleChanges,ReorderedField)3538 TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
3539 const string expected_stderr =
3540 "ERROR: new/p/Data.aidl:1.33-37: Reordered bar from 1 to 0.\n"
3541 "ERROR: new/p/Data.aidl:1.43-47: Reordered foo from 0 to 1.\n";
3542 io_delegate_.SetFileContents("old/p/Data.aidl",
3543 "package p;"
3544 "parcelable Data {"
3545 " int foo;"
3546 " int bar;"
3547 "}");
3548 io_delegate_.SetFileContents("new/p/Data.aidl",
3549 "package p;"
3550 "parcelable Data {"
3551 " int bar;"
3552 " int foo;"
3553 "}");
3554 CaptureStderr();
3555 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3556 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3557 }
3558
TEST_F(AidlTestIncompatibleChanges,ChangedDirectionSpecifier)3559 TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
3560 const string expected_stderr = "ERROR: new/p/IFoo.aidl:1.33-37: Direction changed: in to out.\n";
3561 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3562 "package p;"
3563 "interface IFoo {"
3564 " void foo(in String[] str);"
3565 " void bar(@utf8InCpp String str);"
3566 "}");
3567 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3568 "package p;"
3569 "interface IFoo {"
3570 " void foo(out String[] str);"
3571 " void bar(@utf8InCpp String str);"
3572 "}");
3573 CaptureStderr();
3574 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3575 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3576 }
3577
TEST_F(AidlTestIncompatibleChanges,AddedAnnotation)3578 TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
3579 const string expected_stderr =
3580 "ERROR: new/p/IFoo.aidl:1.51-58: Changed annotations: (empty) to @utf8InCpp\n";
3581 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3582 "package p;"
3583 "interface IFoo {"
3584 " void foo(in String[] str);"
3585 " void bar(@utf8InCpp String str);"
3586 "}");
3587 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3588 "package p;"
3589 "interface IFoo {"
3590 " void foo(in @utf8InCpp String[] str);"
3591 " void bar(@utf8InCpp String str);"
3592 "}");
3593 CaptureStderr();
3594 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3595 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3596 }
3597
TEST_F(AidlTestIncompatibleChanges,RemovedAnnotation)3598 TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
3599 const string expected_stderr =
3600 "ERROR: new/p/IFoo.aidl:1.66-72: Changed annotations: @utf8InCpp to (empty)\n";
3601 io_delegate_.SetFileContents("old/p/IFoo.aidl",
3602 "package p;"
3603 "interface IFoo {"
3604 " void foo(in String[] str);"
3605 " void bar(@utf8InCpp String str);"
3606 "}");
3607 io_delegate_.SetFileContents("new/p/IFoo.aidl",
3608 "package p;"
3609 "interface IFoo {"
3610 " void foo(in String[] str);"
3611 " void bar(String str);"
3612 "}");
3613 CaptureStderr();
3614 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3615 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3616 }
3617
TEST_F(AidlTestIncompatibleChanges,ChangedBackingTypeOfEnum)3618 TEST_F(AidlTestIncompatibleChanges, ChangedBackingTypeOfEnum) {
3619 const string expected_stderr =
3620 "ERROR: new/p/Foo.aidl:1.11-32: Type changed: byte to long.\n"
3621 "ERROR: new/p/Foo.aidl:1.36-40: Changed backing types.\n";
3622 io_delegate_.SetFileContents("old/p/Foo.aidl",
3623 "package p;"
3624 "@Backing(type=\"byte\")"
3625 "enum Foo {"
3626 " FOO, BAR,"
3627 "}");
3628 io_delegate_.SetFileContents("new/p/Foo.aidl",
3629 "package p;"
3630 "@Backing(type=\"long\")"
3631 "enum Foo {"
3632 " FOO, BAR,"
3633 "}");
3634 CaptureStderr();
3635 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3636 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3637 }
3638
TEST_F(AidlTestIncompatibleChanges,ChangedFixedSizeArraySize)3639 TEST_F(AidlTestIncompatibleChanges, ChangedFixedSizeArraySize) {
3640 const string expected_stderr =
3641 "ERROR: new/p/Data.aidl:1.28-33: Type changed: int[8] to int[9].\n";
3642 io_delegate_.SetFileContents("old/p/Data.aidl",
3643 "package p;"
3644 "parcelable Data {"
3645 " int[8] bar;"
3646 "}");
3647 io_delegate_.SetFileContents("new/p/Data.aidl",
3648 "package p;"
3649 "parcelable Data {"
3650 " int[9] bar;"
3651 "}");
3652 CaptureStderr();
3653 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3654 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3655 }
3656
TEST_F(AidlTestIncompatibleChanges,ChangedAnnatationParams)3657 TEST_F(AidlTestIncompatibleChanges, ChangedAnnatationParams) {
3658 const string expected_stderr =
3659 "ERROR: new/p/Foo.aidl:1.55-59: Changed annotations: @JavaPassthrough(annotation=\"Alice\") "
3660 "to @JavaPassthrough(annotation=\"Bob\")\n";
3661 io_delegate_.SetFileContents("old/p/Foo.aidl",
3662 "package p;"
3663 "@JavaPassthrough(annotation=\"Alice\")"
3664 "parcelable Foo {}");
3665 io_delegate_.SetFileContents("new/p/Foo.aidl",
3666 "package p;"
3667 "@JavaPassthrough(annotation=\"Bob\")"
3668 "parcelable Foo {}");
3669
3670 CaptureStderr();
3671 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3672 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3673 }
3674
TEST_F(AidlTestIncompatibleChanges,AddedParcelableAnnotation)3675 TEST_F(AidlTestIncompatibleChanges, AddedParcelableAnnotation) {
3676 const string expected_stderr =
3677 "ERROR: new/p/Foo.aidl:1.32-36: Changed annotations: (empty) to @FixedSize\n";
3678 io_delegate_.SetFileContents("old/p/Foo.aidl",
3679 "package p;"
3680 "parcelable Foo {"
3681 " int A;"
3682 "}");
3683 io_delegate_.SetFileContents("new/p/Foo.aidl",
3684 "package p;"
3685 "@FixedSize parcelable Foo {"
3686 " int A;"
3687 "}");
3688 CaptureStderr();
3689 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3690 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3691 }
3692
TEST_F(AidlTestIncompatibleChanges,RemovedParcelableAnnotation)3693 TEST_F(AidlTestIncompatibleChanges, RemovedParcelableAnnotation) {
3694 const string expected_stderr =
3695 "ERROR: new/p/Foo.aidl:1.21-25: Changed annotations: @FixedSize to (empty)\n";
3696 io_delegate_.SetFileContents("old/p/Foo.aidl",
3697 "package p;"
3698 "@FixedSize parcelable Foo {"
3699 " int A;"
3700 "}");
3701 io_delegate_.SetFileContents("new/p/Foo.aidl",
3702 "package p;"
3703 "parcelable Foo {"
3704 " int A;"
3705 "}");
3706 CaptureStderr();
3707 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3708 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3709 }
3710
TEST_F(AidlTestIncompatibleChanges,RemovedPackage)3711 TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
3712 const string expected_stderr = "ERROR: old/q/IFoo.aidl:1.11-21: Removed type: q.IFoo\n";
3713 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
3714 io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
3715 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
3716 CaptureStderr();
3717 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3718 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3719 }
3720
TEST_F(AidlTestIncompatibleChanges,ChangedDefaultValue)3721 TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
3722 const string expected_stderr = "ERROR: new/p/D.aidl:1.30-32: Changed default value: 1 to 2.\n";
3723 io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
3724 io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
3725 CaptureStderr();
3726 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3727 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3728 }
3729
TEST_F(AidlTestIncompatibleChanges,RemovedConstValue)3730 TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
3731 const string expected_stderr =
3732 "ERROR: old/p/I.aidl:1.51-53: Removed constant declaration: p.I.B\n";
3733 io_delegate_.SetFileContents("old/p/I.aidl",
3734 "package p; interface I {"
3735 "const int A = 1; const int B = 2;}");
3736 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
3737 CaptureStderr();
3738 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3739 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3740 }
3741
TEST_F(AidlTestIncompatibleChanges,ChangedConstValue)3742 TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
3743 const string expected_stderr =
3744 "ERROR: new/p/I.aidl:1.11-21: Changed constant value: p.I.A from 1 to 2.\n";
3745 io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
3746 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
3747 CaptureStderr();
3748 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3749 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3750 }
3751
TEST_F(AidlTestIncompatibleChanges,FixedSizeAddedField)3752 TEST_F(AidlTestIncompatibleChanges, FixedSizeAddedField) {
3753 const string expected_stderr =
3754 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is changed from 1 to 2. "
3755 "This is an incompatible change for FixedSize types.\n";
3756 io_delegate_.SetFileContents("old/p/Foo.aidl",
3757 "package p; @FixedSize parcelable Foo { int A = 1; }");
3758 io_delegate_.SetFileContents("new/p/Foo.aidl",
3759 "package p; @FixedSize parcelable Foo { int A = 1; int B = 2; }");
3760 CaptureStderr();
3761 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3762 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3763 }
3764
TEST_F(AidlTestIncompatibleChanges,UidRangeParcelAddedField)3765 TEST_F(AidlTestIncompatibleChanges, UidRangeParcelAddedField) {
3766 const string expected_stderr =
3767 "ERROR: new/android/net/UidRangeParcel.aidl:1.32-47: Number of fields in "
3768 "android.net.UidRangeParcel is changed from 1 to 2. "
3769 "But it is forbidden because of legacy support.\n";
3770 io_delegate_.SetFileContents("old/android/net/UidRangeParcel.aidl",
3771 "package android.net; parcelable UidRangeParcel { int A = 1; }");
3772 io_delegate_.SetFileContents(
3773 "new/android/net/UidRangeParcel.aidl",
3774 "package android.net; parcelable UidRangeParcel { int A = 1; int B = 2; }");
3775 CaptureStderr();
3776 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3777 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3778 }
3779
TEST_F(AidlTestIncompatibleChanges,FixedSizeRemovedField)3780 TEST_F(AidlTestIncompatibleChanges, FixedSizeRemovedField) {
3781 const string expected_stderr =
3782 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
3783 io_delegate_.SetFileContents("old/p/Foo.aidl",
3784 "package p; @FixedSize parcelable Foo { int A = 1; int B = 1; }");
3785 io_delegate_.SetFileContents("new/p/Foo.aidl",
3786 "package p; @FixedSize parcelable Foo { int A = 1; }");
3787 CaptureStderr();
3788 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3789 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3790 }
3791
TEST_F(AidlTestIncompatibleChanges,IncompatibleChangesInNestedType)3792 TEST_F(AidlTestIncompatibleChanges, IncompatibleChangesInNestedType) {
3793 const string expected_stderr =
3794 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
3795 io_delegate_.SetFileContents("old/p/Foo.aidl",
3796 "package p;\n"
3797 "parcelable Foo {\n"
3798 " interface IBar {\n"
3799 " void foo();"
3800 " }\n"
3801 "}");
3802 io_delegate_.SetFileContents("new/p/Foo.aidl",
3803 "package p;\n"
3804 "parcelable Foo {\n"
3805 " interface IBar {\n"
3806 " void foo(int n);" // incompatible: signature changed
3807 " }\n"
3808 "}");
3809 CaptureStderr();
3810 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3811 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Removed or changed method: p.Foo.IBar.foo()"));
3812 }
3813
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize)3814 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize) {
3815 const string expected_stderr =
3816 "ERROR: Foo.aidl:2.8-10: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3817 "a.\n"
3818 "ERROR: Foo.aidl:3.6-8: The @FixedSize parcelable 'Foo' has a non-fixed size field named b.\n"
3819 "ERROR: Foo.aidl:4.9-11: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3820 "c.\n"
3821 "ERROR: Foo.aidl:5.23-25: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3822 "d.\n"
3823 "ERROR: Foo.aidl:6.10-12: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3824 "e.\n"
3825 "ERROR: Foo.aidl:7.15-17: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3826 "f.\n"
3827 "ERROR: Foo.aidl:9.23-33: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3828 "nullable1.\n"
3829 "ERROR: Foo.aidl:10.34-44: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3830 "nullable2.\n";
3831
3832 io_delegate_.SetFileContents("Foo.aidl",
3833 "@FixedSize parcelable Foo {\n"
3834 " int[] a;\n"
3835 " Bar b;\n"
3836 " String c;\n"
3837 " ParcelFileDescriptor d;\n"
3838 " IBinder e;\n"
3839 " List<String> f;\n"
3840 " int isFixedSize;\n"
3841 " @nullable OtherFixed nullable1;\n"
3842 " @nullable(heap=true) OtherFixed nullable2;\n"
3843 " float[16] floats;\n"
3844 "}");
3845 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
3846 io_delegate_.SetFileContents("OtherFixed.aidl", "@FixedSize parcelable OtherFixed { int a; }");
3847 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
3848
3849 CaptureStderr();
3850 EXPECT_FALSE(compile_aidl(options, io_delegate_));
3851 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3852 }
3853
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize_Union)3854 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize_Union) {
3855 const string expected_stderr =
3856 "ERROR: Foo.aidl:2.8-10: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3857 "a.\n"
3858 "ERROR: Foo.aidl:3.6-8: The @FixedSize parcelable 'Foo' has a non-fixed size field named b.\n"
3859 "ERROR: Foo.aidl:4.9-11: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3860 "c.\n"
3861 "ERROR: Foo.aidl:5.23-25: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3862 "d.\n"
3863 "ERROR: Foo.aidl:6.10-12: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3864 "e.\n"
3865 "ERROR: Foo.aidl:7.15-17: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3866 "f.\n"
3867 "ERROR: Foo.aidl:9.23-33: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3868 "nullable1.\n"
3869 "ERROR: Foo.aidl:10.34-44: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3870 "nullable2.\n";
3871
3872 io_delegate_.SetFileContents("Foo.aidl",
3873 "@FixedSize union Foo {\n"
3874 " int[] a = {};\n"
3875 " Bar b;\n"
3876 " String c;\n"
3877 " ParcelFileDescriptor d;\n"
3878 " IBinder e;\n"
3879 " List<String> f;\n"
3880 " int isFixedSize;\n"
3881 " @nullable OtherFixed nullable1;\n"
3882 " @nullable(heap=true) OtherFixed nullable2;\n"
3883 " float[16] floats;\n"
3884 "}");
3885 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
3886 io_delegate_.SetFileContents("OtherFixed.aidl", "@FixedSize parcelable OtherFixed { int a; }");
3887 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
3888
3889 CaptureStderr();
3890 EXPECT_FALSE(compile_aidl(options, io_delegate_));
3891 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3892 }
3893
TEST_P(AidlTest,AcceptFixedSizeFromFixedSize)3894 TEST_P(AidlTest, AcceptFixedSizeFromFixedSize) {
3895 const string expected_stderr = "";
3896
3897 io_delegate_.SetFileContents("Foo.aidl", "@FixedSize parcelable Foo { int a; Bar b; }");
3898 io_delegate_.SetFileContents("Bar.aidl", "@FixedSize parcelable Bar { Val c; }");
3899 io_delegate_.SetFileContents("Val.aidl", "enum Val { A, B, }");
3900 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
3901
3902 CaptureStderr();
3903 EXPECT_TRUE(compile_aidl(options, io_delegate_));
3904 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3905 }
3906
TEST_F(AidlTest,RejectAmbiguousImports)3907 TEST_F(AidlTest, RejectAmbiguousImports) {
3908 const string expected_stderr =
3909 "ERROR: p/IFoo.aidl: Duplicate files found for q.IBar from:\n"
3910 "dir1/q/IBar.aidl\n"
3911 "dir2/q/IBar.aidl\n";
3912 Options options = Options::From("aidl --lang=java -o out -I . -I dir1 -I dir2 p/IFoo.aidl");
3913 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
3914 io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
3915 io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
3916
3917 CaptureStderr();
3918 EXPECT_FALSE(compile_aidl(options, io_delegate_));
3919 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3920 }
3921
TEST_F(AidlTest,HandleManualIdAssignments)3922 TEST_F(AidlTest, HandleManualIdAssignments) {
3923 const string expected_stderr =
3924 "ERROR: new/p/IFoo.aidl:1.32-36: Transaction ID changed: p.IFoo.foo() is changed from 10 to "
3925 "11.\n";
3926 Options options = Options::From("aidl --checkapi old new");
3927 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
3928 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
3929
3930 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3931
3932 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
3933 CaptureStderr();
3934 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
3935 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3936 }
3937
TEST_P(AidlTest,ParcelFileDescriptorIsBuiltinType)3938 TEST_P(AidlTest, ParcelFileDescriptorIsBuiltinType) {
3939 Options options =
3940 Options::From("aidl -I . --lang=" + to_string(GetLanguage()) + " -h out -o out p/IFoo.aidl");
3941
3942 // use without import
3943 io_delegate_.SetFileContents("p/IFoo.aidl",
3944 "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
3945 EXPECT_TRUE(compile_aidl(options, io_delegate_));
3946
3947 // capture output files
3948 map<string, string> outputs = io_delegate_.OutputFiles();
3949
3950 // use without import but with full name
3951 io_delegate_.SetFileContents(
3952 "p/IFoo.aidl",
3953 "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
3954 EXPECT_TRUE(compile_aidl(options, io_delegate_));
3955 // output files should be the same
3956 EXPECT_EQ(outputs, io_delegate_.OutputFiles());
3957
3958 // use with import (as before)
3959 io_delegate_.SetFileContents("p/IFoo.aidl",
3960 "package p;"
3961 "import android.os.ParcelFileDescriptor;"
3962 "interface IFoo{"
3963 " void foo(in ParcelFileDescriptor fd);"
3964 "}");
3965 EXPECT_TRUE(compile_aidl(options, io_delegate_));
3966 // output files should be the same
3967 EXPECT_EQ(outputs, io_delegate_.OutputFiles());
3968 }
3969
TEST_P(AidlTest,RejectsOutputParcelFileDescriptor)3970 TEST_P(AidlTest, RejectsOutputParcelFileDescriptor) {
3971 Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
3972 CaptureStderr();
3973 io_delegate_.SetFileContents("p/IFoo.aidl",
3974 "package p;"
3975 "interface IFoo{"
3976 " void foo(out ParcelFileDescriptor fd);"
3977 "}");
3978 EXPECT_FALSE(compile_aidl(options, io_delegate_));
3979 EXPECT_THAT(GetCapturedStderr(), HasSubstr("can't be an out parameter"));
3980 }
3981
TEST_P(AidlTest,RejectsArgumentDirectionNotSpecified)3982 TEST_P(AidlTest, RejectsArgumentDirectionNotSpecified) {
3983 Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
3984 CaptureStderr();
3985 io_delegate_.SetFileContents("p/IFoo.aidl",
3986 "package p;"
3987 "interface IFoo{"
3988 " void foo(ParcelFileDescriptor fd);"
3989 "}");
3990 EXPECT_FALSE(compile_aidl(options, io_delegate_));
3991 EXPECT_THAT(GetCapturedStderr(),
3992 HasSubstr("ParcelFileDescriptor can be an in or inout parameter."));
3993 }
3994
TEST_F(AidlTest,ManualIds)3995 TEST_F(AidlTest, ManualIds) {
3996 Options options = Options::From("aidl --lang=java -I . -o out IFoo.aidl");
3997 io_delegate_.SetFileContents("IFoo.aidl",
3998 "interface IFoo {\n"
3999 " void foo() = 0;\n"
4000 " void bar() = 1;\n"
4001 "}");
4002 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4003 }
4004
TEST_F(AidlTest,ManualIdsWithMetaTransactions)4005 TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
4006 Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4007 io_delegate_.SetFileContents("IFoo.aidl",
4008 "interface IFoo {\n"
4009 " void foo() = 0;\n"
4010 " void bar() = 1;\n"
4011 "}");
4012 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4013 }
4014
TEST_F(AidlTest,FailOnDuplicatedIds)4015 TEST_F(AidlTest, FailOnDuplicatedIds) {
4016 const string expected_stderr =
4017 "ERROR: IFoo.aidl:3.7-11: Found duplicate method id (3) for method bar\n";
4018 Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4019 io_delegate_.SetFileContents("IFoo.aidl",
4020 "interface IFoo {\n"
4021 " void foo() = 3;\n"
4022 " void bar() = 3;\n"
4023 "}");
4024 CaptureStderr();
4025 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4026 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4027 }
4028
TEST_F(AidlTest,FailOnOutOfRangeIds)4029 TEST_F(AidlTest, FailOnOutOfRangeIds) {
4030 // 16777115 is kLastMetaMethodId + 1
4031 const string expected_stderr =
4032 "ERROR: IFoo.aidl:3.7-11: Found out of bounds id (16777115) for method bar. "
4033 "Value for id must be between 0 and 16777114 inclusive.\n";
4034 Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4035 io_delegate_.SetFileContents("IFoo.aidl",
4036 "interface IFoo {\n"
4037 " void foo() = 3;\n"
4038 " void bar() = 16777115;\n"
4039 "}");
4040 CaptureStderr();
4041 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4042 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4043 }
4044
TEST_F(AidlTest,FailOnPartiallyAssignedIds)4045 TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
4046 const string expected_stderr =
4047 "ERROR: IFoo.aidl:3.7-11: You must either assign id's to all methods or to none of them.\n";
4048 Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4049 io_delegate_.SetFileContents("IFoo.aidl",
4050 "interface IFoo {\n"
4051 " void foo() = 3;\n"
4052 " void bar();\n"
4053 "}");
4054 CaptureStderr();
4055 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4056 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4057 }
4058
TEST_F(AidlTest,AssignedIds)4059 TEST_F(AidlTest, AssignedIds) {
4060 CaptureStderr();
4061 EXPECT_NE(nullptr, Parse("IFoo.aidl",
4062 "interface IFoo {\n"
4063 " void foo();\n"
4064 " void bar();\n"
4065 " interface INested {\n"
4066 " void foo();\n"
4067 " void bar();\n"
4068 " }\n"
4069 "}",
4070 typenames_, Options::Language::JAVA));
4071 EXPECT_EQ("", GetCapturedStderr());
4072 auto foo = typenames_.ResolveTypename("IFoo").defined_type;
4073 ASSERT_EQ(2u, foo->GetMethods().size());
4074 EXPECT_EQ(0, foo->GetMethods()[0]->GetId());
4075 EXPECT_EQ(1, foo->GetMethods()[1]->GetId());
4076 auto nested = typenames_.ResolveTypename("IFoo.INested").defined_type;
4077 ASSERT_EQ(2u, nested->GetMethods().size());
4078 EXPECT_EQ(0, nested->GetMethods()[0]->GetId());
4079 EXPECT_EQ(1, nested->GetMethods()[1]->GetId());
4080 }
4081
TEST_F(AidlTest,AllowDuplicatedImportPaths)4082 TEST_F(AidlTest, AllowDuplicatedImportPaths) {
4083 Options options = Options::From("aidl --lang=java -I . -I dir -I dir IFoo.aidl");
4084 io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
4085 io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
4086 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4087 }
4088
TEST_F(AidlTest,UnusedImportDoesNotContributeInclude)4089 TEST_F(AidlTest, UnusedImportDoesNotContributeInclude) {
4090 io_delegate_.SetFileContents("a/b/IFoo.aidl",
4091 "package a.b;\n"
4092 "import a.b.IBar;\n"
4093 "import a.b.IQux;\n"
4094 "interface IFoo { IQux foo(); }\n");
4095 io_delegate_.SetFileContents("a/b/IBar.aidl", "package a.b; interface IBar { void foo(); }");
4096 io_delegate_.SetFileContents("a/b/IQux.aidl", "package a.b; interface IQux { void foo(); }");
4097
4098 Options options = Options::From("aidl --lang=ndk a/b/IFoo.aidl -I . -o out -h out/include");
4099 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4100
4101 string output;
4102 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/include/aidl/a/b/IFoo.h", &output));
4103 // IBar was imported but wasn't used. include is not expected.
4104 EXPECT_THAT(output, Not(testing::HasSubstr("#include <aidl/a/b/IBar.h>")));
4105 // IBar was imported and used. include is expected.
4106 EXPECT_THAT(output, (testing::HasSubstr("#include <aidl/a/b/IQux.h>")));
4107 }
4108
TEST_F(AidlTest,ParseJavaPassthroughAnnotation)4109 TEST_F(AidlTest, ParseJavaPassthroughAnnotation) {
4110 io_delegate_.SetFileContents("a/IFoo.aidl", R"--(package a;
4111 import a.MyEnum;
4112 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
4113 @JavaPassthrough(annotation="@com.android.AliceTwo")
4114 interface IFoo {
4115 @JavaPassthrough(annotation="@com.android.Bob")
4116 void foo(@JavaPassthrough(annotation="@com.android.Cat") int x, MyEnum y);
4117 const @JavaPassthrough(annotation="@com.android.David") int A = 3;
4118 })--");
4119 // JavaPassthrough should work with other types as well (e.g. enum)
4120 io_delegate_.SetFileContents("a/MyEnum.aidl", R"--(package a;
4121 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
4122 @JavaPassthrough(annotation="@com.android.AliceTwo")
4123 @Backing(type="byte")
4124 enum MyEnum {
4125 a, b, c
4126 })--");
4127
4128 Options java_options = Options::From("aidl -I . --lang=java -o out a/IFoo.aidl a/MyEnum.aidl");
4129 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
4130
4131 string java_out;
4132 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &java_out));
4133 // type-decl-level annotations with newline at the end
4134 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
4135 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
4136 // member-decl-level annotations with newline at the end
4137 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Bob\n"));
4138 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.David\n"));
4139 // inline annotations with space at the end
4140 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Cat "));
4141
4142 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/MyEnum.java", &java_out));
4143 // type-decl-level annotations with newline at the end
4144 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
4145 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
4146
4147 // Other backends shouldn't be bothered
4148 Options cpp_options =
4149 Options::From("aidl -I . --lang=cpp -o out -h out a/IFoo.aidl a/MyEnum.aidl");
4150 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
4151
4152 Options ndk_options =
4153 Options::From("aidl -I . --lang=ndk -o out -h out a/IFoo.aidl a/MyEnum.aidl");
4154 EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
4155
4156 Options rust_options = Options::From("aidl -I . --lang=rust -o out a/IFoo.aidl a/MyEnum.aidl");
4157 EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
4158 }
4159
TEST_F(AidlTest,ParseRustDerive)4160 TEST_F(AidlTest, ParseRustDerive) {
4161 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
4162 @RustDerive(Clone=true, Copy=false)
4163 parcelable Foo {
4164 int a;
4165 })");
4166
4167 Options rust_options = Options::From("aidl -I . --lang=rust -o out a/Foo.aidl");
4168 EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
4169
4170 string rust_out;
4171 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.rs", &rust_out));
4172 EXPECT_THAT(rust_out, testing::HasSubstr("#[derive(Debug, Clone)]"));
4173
4174 // Other backends shouldn't be bothered
4175 Options cpp_options = Options::From("aidl --lang=cpp -I . -o out -h out a/Foo.aidl");
4176 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
4177
4178 Options ndk_options = Options::From("aidl --lang=ndk -I . -o out -h out a/Foo.aidl");
4179 EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
4180
4181 Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
4182 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
4183 }
4184
TEST_P(AidlTest,TypesShouldHaveRustDerive)4185 TEST_P(AidlTest, TypesShouldHaveRustDerive) {
4186 CaptureStderr();
4187 string code =
4188 "@RustDerive(PartialEq=true)\n"
4189 "parcelable Foo {\n"
4190 " parcelable Bar {}\n"
4191 " Bar bar;\n"
4192 "}";
4193 EXPECT_EQ(nullptr, Parse("Foo.aidl", code, typenames_, GetLanguage(), nullptr, {}));
4194 EXPECT_THAT(
4195 GetCapturedStderr(),
4196 testing::HasSubstr("Field bar of type with @RustDerive PartialEq also needs to derive this"));
4197 }
4198
TEST_F(AidlTest,EmptyEnforceAnnotation)4199 TEST_F(AidlTest, EmptyEnforceAnnotation) {
4200 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4201 interface IFoo {
4202 @EnforcePermission()
4203 void Protected();
4204 })");
4205
4206 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4207 CaptureStderr();
4208 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4209 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Unable to parse @EnforcePermission annotation"));
4210 }
4211
TEST_F(AidlTest,InterfaceEnforceCondition)4212 TEST_F(AidlTest, InterfaceEnforceCondition) {
4213 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4214 @EnforcePermission("INTERNET")
4215 interface IFoo {
4216 void Protected();
4217 })");
4218
4219 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4220 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4221 }
4222
TEST_F(AidlTest,EnforceConditionAny)4223 TEST_F(AidlTest, EnforceConditionAny) {
4224 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4225 interface IFoo {
4226 @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"})
4227 void Protected();
4228 })");
4229
4230 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4231 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4232 }
4233
TEST_F(AidlTest,EnforceConditionAll)4234 TEST_F(AidlTest, EnforceConditionAll) {
4235 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4236 interface IFoo {
4237 @EnforcePermission(allOf={"INTERNET", "READ_PHONE_STATE"})
4238 void Protected();
4239 })");
4240
4241 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4242 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4243 }
4244
TEST_F(AidlTest,InterfaceAndMethodEnforceCondition)4245 TEST_F(AidlTest, InterfaceAndMethodEnforceCondition) {
4246 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4247 @EnforcePermission("INTERNET")
4248 interface IFoo {
4249 @EnforcePermission("SYSTEM_UID")
4250 void Protected();
4251 })");
4252
4253 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4254 CaptureStderr();
4255 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4256 EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4257 "the method Protected is also annotated"));
4258 }
4259
TEST_F(AidlTest,NoPermissionInterfaceEnforceMethod)4260 TEST_F(AidlTest, NoPermissionInterfaceEnforceMethod) {
4261 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4262 @RequiresNoPermission
4263 interface IFoo {
4264 @EnforcePermission("INTERNET")
4265 void Protected();
4266 })");
4267
4268 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4269 CaptureStderr();
4270 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4271 EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4272 "the method Protected is also annotated"));
4273 }
4274
TEST_F(AidlTest,ManualPermissionInterfaceEnforceMethod)4275 TEST_F(AidlTest, ManualPermissionInterfaceEnforceMethod) {
4276 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4277 @PermissionManuallyEnforced
4278 interface IFoo {
4279 @EnforcePermission("INTERNET")
4280 void Protected();
4281 })");
4282
4283 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4284 CaptureStderr();
4285 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4286 EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4287 "the method Protected is also annotated"));
4288 }
4289
TEST_F(AidlTest,EnforceInterfaceNoPermissionsMethod)4290 TEST_F(AidlTest, EnforceInterfaceNoPermissionsMethod) {
4291 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4292 @EnforcePermission("INTERNET")
4293 interface IFoo {
4294 @RequiresNoPermission
4295 void Protected();
4296 })");
4297
4298 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4299 CaptureStderr();
4300 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4301 EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4302 "the method Protected is also annotated"));
4303 }
4304
TEST_F(AidlTest,EnforceInterfaceManualPermissionMethod)4305 TEST_F(AidlTest, EnforceInterfaceManualPermissionMethod) {
4306 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4307 @EnforcePermission("INTERNET")
4308 interface IFoo {
4309 @PermissionManuallyEnforced
4310 void Protected();
4311 })");
4312
4313 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4314 CaptureStderr();
4315 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4316 EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4317 "the method Protected is also annotated"));
4318 }
4319
TEST_F(AidlTest,JavaSuppressLint)4320 TEST_F(AidlTest, JavaSuppressLint) {
4321 io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4322 @JavaSuppressLint({"NewApi"})
4323 interface IFoo {
4324 })");
4325
4326 Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4327 CaptureStderr();
4328 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4329 EXPECT_EQ(GetCapturedStderr(), "");
4330 string code;
4331 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &code));
4332 EXPECT_THAT(code, HasSubstr("@android.annotation.SuppressLint(value = {\"NewApi\"})"));
4333 }
4334
4335 class AidlOutputPathTest : public AidlTest {
4336 protected:
SetUp()4337 void SetUp() override {
4338 AidlTest::SetUp();
4339 io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
4340 }
4341
Test(const Options & options,const std::string expected_output_path)4342 void Test(const Options& options, const std::string expected_output_path) {
4343 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4344 // check the existence
4345 EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
4346 }
4347 };
4348
TEST_F(AidlOutputPathTest,OutDirWithNoOutputFile)4349 TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
4350 // <out_dir> / <package_name> / <type_name>.java
4351 Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
4352 }
4353
TEST_F(AidlOutputPathTest,OutDirWithOutputFile)4354 TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
4355 // when output file is explicitly set, it is always respected. -o option is
4356 // ignored.
4357 Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"),
4358 "output/IFoo.java");
4359 }
4360
TEST_F(AidlOutputPathTest,NoOutDirWithOutputFile)4361 TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
4362 Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"),
4363 "output/IFoo.java");
4364 }
4365
TEST_F(AidlOutputPathTest,NoOutDirWithNoOutputFile)4366 TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
4367 // output is the same as the input file except for the suffix
4368 Test(Options::From("aidl -I sub/dir sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
4369 }
4370
TEST_P(AidlTest,FailOnOutOfBoundsInt32MaxConstInt)4371 TEST_P(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
4372 AidlError error;
4373 const string expected_stderr =
4374 "ERROR: p/IFoo.aidl:3.58-69: Invalid type specifier for an int64 literal: int (2147483650)\n";
4375 CaptureStderr();
4376 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4377 R"(package p;
4378 interface IFoo {
4379 const int int32_max_oob = 2147483650;
4380 }
4381 )",
4382 typenames_, GetLanguage(), &error));
4383 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4384 EXPECT_EQ(AidlError::BAD_TYPE, error);
4385 }
4386
TEST_P(AidlTest,FailOnOutOfBoundsInt32MinConstInt)4387 TEST_P(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
4388 AidlError error;
4389 const string expected_stderr =
4390 "ERROR: p/IFoo.aidl:3.58-60: Invalid type specifier for an int64 literal: int "
4391 "(-2147483650)\n";
4392 CaptureStderr();
4393 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4394 R"(package p;
4395 interface IFoo {
4396 const int int32_min_oob = -2147483650;
4397 }
4398 )",
4399 typenames_, GetLanguage(), &error));
4400 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4401 EXPECT_EQ(AidlError::BAD_TYPE, error);
4402 }
4403
TEST_P(AidlTest,FailOnOutOfBoundsInt64MaxConstInt)4404 TEST_P(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
4405 AidlError error;
4406 const string expected_stderr =
4407 "ERROR: p/IFoo.aidl:3.59-86: Could not parse integer: 21474836509999999999999999\n";
4408 CaptureStderr();
4409 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4410 R"(package p;
4411 interface IFoo {
4412 const long int64_max_oob = 21474836509999999999999999;
4413 }
4414 )",
4415 typenames_, GetLanguage(), &error));
4416 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4417 EXPECT_EQ(AidlError::PARSE_ERROR, error);
4418 }
4419
TEST_P(AidlTest,FailOnOutOfBoundsInt64MinConstInt)4420 TEST_P(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
4421 AidlError error;
4422 const string expected_stderr =
4423 "ERROR: p/IFoo.aidl:3.61-87: Could not parse integer: 21474836509999999999999999\n";
4424 CaptureStderr();
4425 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4426 R"(package p;
4427 interface IFoo {
4428 const long int64_min_oob = -21474836509999999999999999;
4429 }
4430 )",
4431 typenames_, GetLanguage(), &error));
4432 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4433 EXPECT_EQ(AidlError::PARSE_ERROR, error);
4434 }
4435
TEST_P(AidlTest,FailOnOutOfBoundsAutofilledEnum)4436 TEST_P(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
4437 AidlError error;
4438 const string expected_stderr =
4439 "ERROR: p/TestEnum.aidl:5.1-36: Invalid type specifier for an int32 literal: byte (FOO+1)\n"
4440 "ERROR: p/TestEnum.aidl:5.1-36: Enumerator type differs from enum backing type.\n";
4441 CaptureStderr();
4442 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4443 R"(package p;
4444 @Backing(type="byte")
4445 enum TestEnum {
4446 FOO = 127,
4447 BAR,
4448 }
4449 )",
4450 typenames_, GetLanguage(), &error));
4451 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4452 EXPECT_EQ(AidlError::BAD_TYPE, error);
4453 }
4454
TEST_P(AidlTest,FailOnUnsupportedBackingType)4455 TEST_P(AidlTest, FailOnUnsupportedBackingType) {
4456 AidlError error;
4457 const string expected_stderr =
4458 "ERROR: p/TestEnum.aidl:3.35-44: Invalid backing type: boolean. Backing type must be one of: "
4459 "byte, int, long\n";
4460 CaptureStderr();
4461 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4462 R"(package p;
4463 @Backing(type="boolean")
4464 enum TestEnum {
4465 FOO = 0,
4466 BAR = 1,
4467 }
4468 )",
4469 typenames_, GetLanguage(), &error));
4470 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4471 EXPECT_EQ(AidlError::BAD_TYPE, error);
4472 }
4473
TEST_P(AidlTest,UnsupportedBackingAnnotationParam)4474 TEST_P(AidlTest, UnsupportedBackingAnnotationParam) {
4475 AidlError error;
4476 const string expected_stderr =
4477 "ERROR: p/TestEnum.aidl:2.1-51: Parameter foo not supported for annotation Backing. It must "
4478 "be one of: type\n";
4479 CaptureStderr();
4480 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4481 R"(package p;
4482 @Backing(foo="byte")
4483 enum TestEnum {
4484 FOO = 1,
4485 BAR,
4486 }
4487 )",
4488 typenames_, GetLanguage(), &error));
4489 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4490 EXPECT_EQ(AidlError::BAD_TYPE, error);
4491 }
4492
TEST_P(AidlTest,BackingAnnotationRequireTypeParameter)4493 TEST_P(AidlTest, BackingAnnotationRequireTypeParameter) {
4494 const string expected_stderr = "ERROR: Enum.aidl:1.1-9: Missing 'type' on @Backing.\n";
4495 CaptureStderr();
4496 EXPECT_EQ(nullptr, Parse("Enum.aidl", "@Backing enum Enum { FOO }", typenames_, GetLanguage()));
4497 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4498 }
4499
TEST_F(AidlTest,SupportJavaOnlyImmutableAnnotation)4500 TEST_F(AidlTest, SupportJavaOnlyImmutableAnnotation) {
4501 io_delegate_.SetFileContents("Foo.aidl",
4502 "@JavaOnlyImmutable parcelable Foo { int a; Bar b; List<Bar> c; "
4503 "Map<String, Baz> d; Bar[] e; }");
4504 io_delegate_.SetFileContents("Bar.aidl", "@JavaOnlyImmutable parcelable Bar { String a; }");
4505 io_delegate_.SetFileContents("Baz.aidl",
4506 "@JavaOnlyImmutable @JavaOnlyStableParcelable parcelable Baz;");
4507 Options options = Options::From("aidl --lang=java -I . Foo.aidl");
4508 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4509 }
4510
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableParcelable)4511 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableParcelable) {
4512 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
4513 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
4514 string expected_error =
4515 "ERROR: Foo.aidl:1.40-44: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
4516 "named 'bar'.\n";
4517 CaptureStderr();
4518 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4519 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4520 EXPECT_EQ(expected_error, GetCapturedStderr());
4521 }
4522
TEST_F(AidlTest,JavaOnlyImmutableParcelableWithEnumFields)4523 TEST_F(AidlTest, JavaOnlyImmutableParcelableWithEnumFields) {
4524 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
4525 io_delegate_.SetFileContents("Bar.aidl", "enum Bar { FOO }");
4526 CaptureStderr();
4527 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4528 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4529 EXPECT_EQ("", GetCapturedStderr());
4530 }
4531
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableUnion)4532 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableUnion) {
4533 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable union Foo { Bar bar; }");
4534 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
4535 string expected_error =
4536 "ERROR: Foo.aidl:1.35-39: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
4537 "named 'bar'.\n";
4538 CaptureStderr();
4539 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4540 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4541 EXPECT_EQ(expected_error, GetCapturedStderr());
4542 }
4543
TEST_F(AidlTest,ImmutableParcelableCannotBeInOut)4544 TEST_F(AidlTest, ImmutableParcelableCannotBeInOut) {
4545 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
4546 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(inout Foo foo); }");
4547 string expected_error =
4548 "ERROR: IBar.aidl:1.35-39: 'foo' can't be an inout parameter because @JavaOnlyImmutable can "
4549 "only be an in parameter.\n";
4550 CaptureStderr();
4551 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
4552 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4553 EXPECT_EQ(expected_error, GetCapturedStderr());
4554 }
4555
TEST_F(AidlTest,ImmutableParcelableCannotBeOut)4556 TEST_F(AidlTest, ImmutableParcelableCannotBeOut) {
4557 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
4558 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(out Foo foo); }");
4559 string expected_error =
4560 "ERROR: IBar.aidl:1.33-37: 'foo' can't be an out parameter because @JavaOnlyImmutable can "
4561 "only be an in parameter.\n";
4562 CaptureStderr();
4563 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
4564 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4565 EXPECT_EQ(expected_error, GetCapturedStderr());
4566 }
4567
TEST_F(AidlTest,ImmutableParcelableFieldNameRestriction)4568 TEST_F(AidlTest, ImmutableParcelableFieldNameRestriction) {
4569 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; int A; }");
4570 Options options = Options::From("aidl -I . --lang=java Foo.aidl");
4571 const string expected_stderr =
4572 "ERROR: Foo.aidl:1.47-49: 'Foo' has duplicate field name 'A' after capitalizing the first "
4573 "letter\n";
4574 CaptureStderr();
4575 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4576 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4577 }
4578
TEST_P(AidlTest,UnionInUnion)4579 TEST_P(AidlTest, UnionInUnion) {
4580 import_paths_.insert(".");
4581 io_delegate_.SetFileContents("Bar.aidl", "union Bar { int n = 42; long l; }");
4582 CaptureStderr();
4583 EXPECT_NE(nullptr, Parse("Foo.aidl", "union Foo { Bar b; int n; }", typenames_, GetLanguage()));
4584 EXPECT_THAT("", GetCapturedStderr());
4585 }
4586
TEST_P(AidlTest,UnionRejectsEmptyDecl)4587 TEST_P(AidlTest, UnionRejectsEmptyDecl) {
4588 const string method = "package a; union Foo {}";
4589 const string expected_stderr = "ERROR: a/Foo.aidl:1.17-21: The union 'Foo' has no fields.\n";
4590 CaptureStderr();
4591 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
4592 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
4593 }
4594
TEST_P(AidlTest,UnionRejectsParcelableHolder)4595 TEST_P(AidlTest, UnionRejectsParcelableHolder) {
4596 const string method = "package a; union Foo { ParcelableHolder x; }";
4597 const string expected_stderr =
4598 "ERROR: a/Foo.aidl:1.40-42: A union can't have a member of ParcelableHolder 'x'\n";
4599 CaptureStderr();
4600 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
4601 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
4602 }
4603
TEST_P(AidlTest,UnionRejectsFirstEnumWithNoDefaults)4604 TEST_P(AidlTest, UnionRejectsFirstEnumWithNoDefaults) {
4605 import_paths_.insert(".");
4606 io_delegate_.SetFileContents("a/Enum.aidl", "package a; enum Enum { FOO, BAR }");
4607 const string expected_err = "The union's first member should have a useful default value.";
4608 CaptureStderr();
4609 EXPECT_EQ(nullptr,
4610 Parse("a/Foo.aidl", "package a; union Foo { a.Enum e; }", typenames_, GetLanguage()));
4611 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_err));
4612 }
4613
TEST_P(AidlTest,GenericStructuredParcelable)4614 TEST_P(AidlTest, GenericStructuredParcelable) {
4615 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T, U> { int a; int A; }");
4616 Options options = Options::From("aidl -I . Foo.aidl --lang=" + to_string(GetLanguage()));
4617 const string expected_stderr = "";
4618 CaptureStderr();
4619 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4620 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4621 }
4622
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Cpp)4623 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
4624 io_delegate_.SetFileContents("Foo.aidl",
4625 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4626 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(Options::Language::CPP) +
4627 " -o out -h out");
4628 const string expected_stderr = "";
4629 CaptureStderr();
4630 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4631 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4632
4633 string code;
4634 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
4635 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4636 const ::android::String16& Foo<T,U>::s() {
4637 static const ::android::String16 value(::android::String16(""));
4638 return value;
4639 })--"));
4640 }
4641
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Ndk)4642 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
4643 io_delegate_.SetFileContents("Foo.aidl",
4644 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4645 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(Options::Language::NDK) +
4646 " -o out -h out");
4647 const string expected_stderr = "";
4648 CaptureStderr();
4649 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4650 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4651
4652 string code;
4653 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
4654 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4655 const char* Foo<T, U>::s = "";
4656 )--"));
4657 }
4658
TEST_F(AidlTest,NestedTypeArgs)4659 TEST_F(AidlTest, NestedTypeArgs) {
4660 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
4661 io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");
4662
4663 io_delegate_.SetFileContents("a/Foo.aidl",
4664 "package a; import a.Bar; import a.Baz; parcelable Foo { "
4665 "Baz<Bar<Bar<String[]>>[], Bar<String>> barss; }");
4666 Options options = Options::From("aidl a/Foo.aidl -I . -o out --lang=java");
4667 const string expected_stderr = "";
4668 CaptureStderr();
4669 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4670 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4671
4672 string code;
4673 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
4674 EXPECT_THAT(code,
4675 testing::HasSubstr(
4676 "a.Baz<a.Bar<a.Bar<java.lang.String[]>>[],a.Bar<java.lang.String>> barss;"));
4677 }
4678
TEST_F(AidlTest,AcceptMultiDimensionalFixedSizeArray)4679 TEST_F(AidlTest, AcceptMultiDimensionalFixedSizeArray) {
4680 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[2][3] a; }");
4681
4682 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4683 CaptureStderr();
4684 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4685 EXPECT_EQ("", GetCapturedStderr());
4686 }
4687
TEST_F(AidlTest,AcceptBinarySizeArray)4688 TEST_F(AidlTest, AcceptBinarySizeArray) {
4689 io_delegate_.SetFileContents(
4690 "a/Bar.aidl", "package a; parcelable Bar { const int CONST = 3; String[CONST + 1] a; }");
4691
4692 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4693 CaptureStderr();
4694 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4695 EXPECT_EQ("", GetCapturedStderr());
4696 }
4697
TEST_F(AidlTest,AcceptRefSizeArray)4698 TEST_F(AidlTest, AcceptRefSizeArray) {
4699 io_delegate_.SetFileContents(
4700 "a/Bar.aidl", "package a; parcelable Bar { const int CONST = 3; String[CONST] a; }");
4701
4702 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4703 CaptureStderr();
4704 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4705 EXPECT_EQ("", GetCapturedStderr());
4706 }
4707
TEST_F(AidlTest,RejectArrayOfFixedSizeArray)4708 TEST_F(AidlTest, RejectArrayOfFixedSizeArray) {
4709 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[2][] a; }");
4710
4711 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4712 CaptureStderr();
4713 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4714 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4715 }
4716
TEST_F(AidlTest,RejectFixedSizeArrayOfDynamicArray)4717 TEST_F(AidlTest, RejectFixedSizeArrayOfDynamicArray) {
4718 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][3] a; }");
4719
4720 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4721 CaptureStderr();
4722 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4723 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4724 }
4725
TEST_F(AidlTest,RejectArrayOfArray)4726 TEST_F(AidlTest, RejectArrayOfArray) {
4727 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][] a; }");
4728
4729 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4730 CaptureStderr();
4731 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4732 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4733 }
4734
TEST_F(AidlTest,RejectInvalidArraySize_Negative)4735 TEST_F(AidlTest, RejectInvalidArraySize_Negative) {
4736 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[-1] a; }");
4737
4738 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4739 CaptureStderr();
4740 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4741 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Array size must be a positive number"));
4742 }
4743
TEST_F(AidlTest,RejectInvalidArraySize_WrongType)4744 TEST_F(AidlTest, RejectInvalidArraySize_WrongType) {
4745 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[\"3\"] a; }");
4746
4747 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4748 CaptureStderr();
4749 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4750 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Array size must be a positive number"));
4751 }
4752
TEST_F(AidlTest,DoubleGenericError)4753 TEST_F(AidlTest, DoubleGenericError) {
4754 io_delegate_.SetFileContents("a/Bar.aidl",
4755 "package a; parcelable Bar { List<String><String> a; }");
4756
4757 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4758 const string expected_stderr =
4759 "ERROR: a/Bar.aidl:1.28-33: Can only specify one set of type parameters.\n";
4760 CaptureStderr();
4761 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4762 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4763 }
4764
TEST_F(AidlTest,ArrayBeforeGenericError)4765 TEST_F(AidlTest, ArrayBeforeGenericError) {
4766 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { List[]<String> a; }");
4767
4768 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4769 CaptureStderr();
4770 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4771 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("syntax error, unexpected '<'"));
4772 }
4773
TEST_F(AidlTest,NullableArraysAreNotSupported)4774 TEST_F(AidlTest, NullableArraysAreNotSupported) {
4775 io_delegate_.SetFileContents("a/Bar.aidl",
4776 "package a; parcelable Bar { String @nullable [] a; }");
4777
4778 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4779 CaptureStderr();
4780 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4781 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("Annotations for arrays are not supported."));
4782 }
4783
TEST_F(AidlTest,ListOfNullablesAreNotSupported)4784 TEST_F(AidlTest, ListOfNullablesAreNotSupported) {
4785 io_delegate_.SetFileContents("a/Bar.aidl",
4786 "package a; parcelable Bar { List<@nullable String> a; }");
4787
4788 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4789 CaptureStderr();
4790 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4791 EXPECT_THAT(GetCapturedStderr(),
4792 testing::HasSubstr("Annotations for type arguments are not supported."));
4793 }
4794
TEST_F(AidlTest,DefaultShouldMatchWithFixedSizeArray)4795 TEST_F(AidlTest, DefaultShouldMatchWithFixedSizeArray) {
4796 io_delegate_.SetFileContents("a/Bar.aidl",
4797 "package a;\n"
4798 "parcelable Bar {\n"
4799 " int[2][3] a = {{1,2,3}, {4,5,6}};\n"
4800 "}");
4801
4802 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4803 CaptureStderr();
4804 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4805 EXPECT_EQ("", GetCapturedStderr());
4806 }
4807
TEST_F(AidlTest,FixedSizeArrayWithWrongTypeDefaultValue)4808 TEST_F(AidlTest, FixedSizeArrayWithWrongTypeDefaultValue) {
4809 io_delegate_.SetFileContents("a/Bar.aidl",
4810 "package a;\n"
4811 "parcelable Bar {\n"
4812 " int[2][3] a = {{\"1\",\"2\",\"3\"}, {4,5,6}};\n"
4813 "}");
4814
4815 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4816 CaptureStderr();
4817 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4818 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Invalid type specifier for a literal string: int"));
4819 }
4820
TEST_F(AidlTest,FixedSizeArrayWithMoreElements)4821 TEST_F(AidlTest, FixedSizeArrayWithMoreElements) {
4822 io_delegate_.SetFileContents("a/Bar.aidl",
4823 "package a;\n"
4824 "parcelable Bar {\n"
4825 " int[2][3] a = {{1,2,3,4}, {4,5,6}};\n"
4826 "}");
4827
4828 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4829 CaptureStderr();
4830 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4831 EXPECT_THAT(GetCapturedStderr(),
4832 HasSubstr("Expected an array of 3 elements, but found one with 4 elements"));
4833 }
4834
TEST_F(AidlTest,FixedSizeArrayWithFewerElements)4835 TEST_F(AidlTest, FixedSizeArrayWithFewerElements) {
4836 io_delegate_.SetFileContents("a/Bar.aidl",
4837 "package a;\n"
4838 "parcelable Bar {\n"
4839 " int[2][3] a = {};\n"
4840 "}");
4841
4842 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4843 CaptureStderr();
4844 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4845 EXPECT_THAT(GetCapturedStderr(),
4846 HasSubstr("Expected an array of 2 elements, but found one with 0 elements"));
4847 }
4848
4849 struct GenericAidlTest : ::testing::Test {
4850 FakeIoDelegate io_delegate_;
Compileandroid::aidl::GenericAidlTest4851 void Compile(string cmd) {
4852 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { Bar<Baz<Qux>> x; }");
4853 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar<T> { }");
4854 io_delegate_.SetFileContents("Baz.aidl", "parcelable Baz<T> { }");
4855 io_delegate_.SetFileContents("Qux.aidl", "parcelable Qux { }");
4856
4857 Options options = Options::From(cmd);
4858 CaptureStderr();
4859 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4860 EXPECT_EQ("", GetCapturedStderr());
4861 }
4862 };
4863
TEST_F(GenericAidlTest,ImportGenericParameterTypesCPP)4864 TEST_F(GenericAidlTest, ImportGenericParameterTypesCPP) {
4865 Compile("aidl Foo.aidl --lang=cpp -I . -o out -h out");
4866 string code;
4867 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
4868 EXPECT_THAT(code, testing::HasSubstr("#include <Bar.h>"));
4869 EXPECT_THAT(code, testing::HasSubstr("#include <Baz.h>"));
4870 EXPECT_THAT(code, testing::HasSubstr("#include <Qux.h>"));
4871 }
4872
TEST_F(GenericAidlTest,ImportGenericParameterTypesNDK)4873 TEST_F(GenericAidlTest, ImportGenericParameterTypesNDK) {
4874 Compile("aidl Foo.aidl --lang=ndk -I . -o out -h out");
4875 string code;
4876 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
4877 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Bar.h>"));
4878 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Baz.h>"));
4879 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Qux.h>"));
4880 }
4881
TEST_P(AidlTest,RejectGenericStructuredParcelabelRepeatedParam)4882 TEST_P(AidlTest, RejectGenericStructuredParcelabelRepeatedParam) {
4883 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { int a; int A; }");
4884 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
4885 const string expected_stderr =
4886 "ERROR: Foo.aidl:1.11-15: Every type parameter should be unique.\n";
4887 CaptureStderr();
4888 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4889 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4890 }
4891
TEST_P(AidlTest,RejectGenericStructuredParcelableField)4892 TEST_P(AidlTest, RejectGenericStructuredParcelableField) {
4893 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { T a; int A; }");
4894 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
4895 const string expected_stderr =
4896 "ERROR: Foo.aidl: Couldn't find import for class T. Searched here:\n - ./\nERROR: "
4897 "Foo.aidl:1.22-24: Failed to resolve 'T'\n";
4898 CaptureStderr();
4899 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4900 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4901 }
4902
TEST_P(AidlTest,LongCommentWithinConstExpression)4903 TEST_P(AidlTest, LongCommentWithinConstExpression) {
4904 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { FOO = (1 << 1) /* comment */ | 0x0 }");
4905 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
4906 CaptureStderr();
4907 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4908 EXPECT_EQ("", GetCapturedStderr());
4909 }
4910
TEST_F(AidlTest,RejectUntypdeListAndMapInUnion)4911 TEST_F(AidlTest, RejectUntypdeListAndMapInUnion) {
4912 io_delegate_.SetFileContents("a/Foo.aidl", "package a; union Foo { List l; Map m; }");
4913 Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
4914 std::string expectedErr =
4915 "ERROR: a/Foo.aidl:1.28-30: "
4916 "Encountered an untyped List or Map. The use of untyped List/Map is "
4917 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4918 "the receiving side. Consider switching to an array or a generic List/Map.\n"
4919 "ERROR: a/Foo.aidl:1.35-37: "
4920 "Encountered an untyped List or Map. The use of untyped List/Map is "
4921 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4922 "the receiving side. Consider switching to an array or a generic List/Map.\n";
4923 CaptureStderr();
4924 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4925 EXPECT_EQ(expectedErr, GetCapturedStderr());
4926 }
4927
TEST_F(AidlTest,RejectUntypdeListAndMapInUnstructuredParcelable)4928 TEST_F(AidlTest, RejectUntypdeListAndMapInUnstructuredParcelable) {
4929 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { List l; Map m; }");
4930 Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
4931 std::string expectedErr =
4932 "ERROR: a/Foo.aidl:1.33-35: "
4933 "Encountered an untyped List or Map. The use of untyped List/Map is "
4934 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4935 "the receiving side. Consider switching to an array or a generic List/Map.\n"
4936 "ERROR: a/Foo.aidl:1.40-42: "
4937 "Encountered an untyped List or Map. The use of untyped List/Map is "
4938 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4939 "the receiving side. Consider switching to an array or a generic List/Map.\n";
4940 CaptureStderr();
4941 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4942 EXPECT_EQ(expectedErr, GetCapturedStderr());
4943 }
4944
TEST_F(AidlTest,RejectNestedUntypedListAndMap)4945 TEST_F(AidlTest, RejectNestedUntypedListAndMap) {
4946 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<T>;");
4947 io_delegate_.SetFileContents(
4948 "a/Foo.aidl", "package a; import a.Bar; parcelable Foo { Bar<List> a; Bar<Map> b; }");
4949 Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
4950 std::string expectedErr =
4951 "ERROR: a/Foo.aidl:1.52-54: "
4952 "Encountered an untyped List or Map. The use of untyped List/Map is "
4953 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4954 "the receiving side. Consider switching to an array or a generic List/Map.\n"
4955 "ERROR: a/Foo.aidl:1.64-66: "
4956 "Encountered an untyped List or Map. The use of untyped List/Map is "
4957 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4958 "the receiving side. Consider switching to an array or a generic List/Map.\n";
4959 CaptureStderr();
4960 EXPECT_FALSE(compile_aidl(options, io_delegate_));
4961 EXPECT_EQ(expectedErr, GetCapturedStderr());
4962 }
4963
TEST_F(AidlTest,EnumWithDefaults_Java)4964 TEST_F(AidlTest, EnumWithDefaults_Java) {
4965 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
4966 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
4967 package p;
4968 import p.Enum;
4969 parcelable Foo {
4970 Enum e = Enum.BAR;
4971 })");
4972 CaptureStderr();
4973 auto options = Options::From("aidl -I a --lang java -o out a/p/Foo.aidl");
4974 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4975 auto err = GetCapturedStderr();
4976 EXPECT_EQ("", err);
4977
4978 string code;
4979 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.java", &code));
4980 EXPECT_THAT(code, testing::HasSubstr("byte e = p.Enum.BAR"));
4981 }
4982
TEST_F(AidlTest,EnumWithDefaults_Cpp)4983 TEST_F(AidlTest, EnumWithDefaults_Cpp) {
4984 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
4985 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
4986 package p;
4987 import p.Enum;
4988 parcelable Foo {
4989 Enum e = Enum.BAR;
4990 })");
4991 CaptureStderr();
4992 auto options = Options::From("aidl -I a --lang cpp -o out -h out a/p/Foo.aidl");
4993 EXPECT_TRUE(compile_aidl(options, io_delegate_));
4994 auto err = GetCapturedStderr();
4995 EXPECT_EQ("", err);
4996
4997 string code;
4998 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.h", &code));
4999 EXPECT_THAT(code, testing::HasSubstr("::p::Enum e = ::p::Enum::BAR;"));
5000 }
5001
TEST_F(AidlTest,EnumWithDefaults_Ndk)5002 TEST_F(AidlTest, EnumWithDefaults_Ndk) {
5003 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5004 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5005 package p;
5006 import p.Enum;
5007 parcelable Foo {
5008 Enum e = Enum.BAR;
5009 })");
5010 CaptureStderr();
5011 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5012 EXPECT_TRUE(compile_aidl(options, io_delegate_));
5013 auto err = GetCapturedStderr();
5014 EXPECT_EQ("", err);
5015
5016 string code;
5017 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
5018 EXPECT_THAT(code, testing::HasSubstr("::aidl::p::Enum e = ::aidl::p::Enum::BAR;"));
5019 }
5020
TEST_F(AidlTest,EnumWithDefaults_Rust)5021 TEST_F(AidlTest, EnumWithDefaults_Rust) {
5022 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5023 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5024 package p;
5025 import p.Enum;
5026 parcelable Foo {
5027 int n = 42;
5028 Enum e = Enum.BAR;
5029 })");
5030 CaptureStderr();
5031 auto options = Options::From("aidl -I a --lang rust -o out -h out a/p/Foo.aidl");
5032 EXPECT_TRUE(compile_aidl(options, io_delegate_));
5033 auto err = GetCapturedStderr();
5034 EXPECT_EQ("", err);
5035
5036 string code;
5037 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.rs", &code));
5038 EXPECT_THAT(code, testing::HasSubstr(R"(
5039 fn default() -> Self {
5040 Self {
5041 r#n: 42,
5042 r#e: crate::mangled::_1_p_4_Enum::BAR,
5043 }
5044 })"));
5045 }
5046
TEST_P(AidlTest,EnumeratorIsConstantValue_DefaultValue)5047 TEST_P(AidlTest, EnumeratorIsConstantValue_DefaultValue) {
5048 import_paths_.insert("a");
5049 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5050 CaptureStderr();
5051 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
5052 package p;
5053 import p.Enum;
5054 parcelable Foo {
5055 int e = Enum.FOO | Enum.BAR;
5056 })",
5057 typenames_, GetLanguage());
5058 auto err = GetCapturedStderr();
5059 EXPECT_EQ("", err);
5060 EXPECT_TRUE(type);
5061 const auto& fields = type->AsStructuredParcelable()->GetFields();
5062 EXPECT_EQ("int e = 3", fields[0]->ToString());
5063 }
5064
TEST_F(AidlTest,EnumeratorIsConstantValue_CanDefineOtherEnumerator)5065 TEST_F(AidlTest, EnumeratorIsConstantValue_CanDefineOtherEnumerator) {
5066 CaptureStderr();
5067 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
5068 package a.p;
5069 @Backing(type="int")
5070 enum Foo {
5071 STANDARD_SHIFT = 16,
5072 STANDARD_BT709 = 1 << STANDARD_SHIFT,
5073 STANDARD_BT601_625 = 2 << STANDARD_SHIFT,
5074 }
5075 )",
5076 typenames_, Options::Language::JAVA);
5077 auto err = GetCapturedStderr();
5078 EXPECT_EQ("", err);
5079 ASSERT_NE(type, nullptr);
5080 const auto& enum_type = type->AsEnumDeclaration();
5081 string code;
5082 auto writer = CodeWriter::ForString(&code);
5083 DumpVisitor visitor(*writer, /*inline_constants=*/true);
5084 visitor.Visit(*enum_type);
5085 writer->Close();
5086 EXPECT_EQ(R"--(@Backing(type="int")
5087 enum Foo {
5088 STANDARD_SHIFT = 16,
5089 STANDARD_BT709 = 65536,
5090 STANDARD_BT601_625 = 131072,
5091 }
5092 )--",
5093 code);
5094 }
5095
TEST_F(AidlTest,DumpApiWithConstantReferences)5096 TEST_F(AidlTest, DumpApiWithConstantReferences) {
5097 io_delegate_.SetFileContents("foo/bar/Foo.aidl", R"(
5098 package foo.bar;
5099 import foo.bar.Bar;
5100 import foo.bar.Enum;
5101 parcelable Foo {
5102 int n = Bar.A + 1;
5103 int[] ns = {1, Bar.A, Bar.B + 1};
5104 Enum e = Enum.A;
5105 Enum[] es = {Enum.A, Enum.B};
5106 }
5107 )");
5108 io_delegate_.SetFileContents("foo/bar/Bar.aidl", R"(
5109 package foo.bar;
5110 parcelable Bar {
5111 const int A = 1;
5112 const int B = A + 1;
5113 }
5114 )");
5115 io_delegate_.SetFileContents("foo/bar/Enum.aidl", R"(
5116 package foo.bar;
5117 enum Enum {
5118 A,
5119 B = A + 2,
5120 }
5121 )");
5122 vector<string> args = {"aidl",
5123 "--dumpapi",
5124 "--out=dump",
5125 "--include=.",
5126 "foo/bar/Foo.aidl",
5127 "foo/bar/Bar.aidl",
5128 "foo/bar/Enum.aidl"};
5129 ASSERT_TRUE(dump_api(Options::From(args), io_delegate_));
5130
5131 string actual;
5132 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
5133 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5134 parcelable Foo {
5135 int n = (foo.bar.Bar.A + 1) /* 2 */;
5136 int[] ns = {1, foo.bar.Bar.A /* 1 */, (foo.bar.Bar.B + 1) /* 3 */};
5137 foo.bar.Enum e = foo.bar.Enum.A;
5138 foo.bar.Enum[] es = {foo.bar.Enum.A, foo.bar.Enum.B};
5139 }
5140 )"),
5141 actual);
5142 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Bar.aidl", &actual));
5143 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5144 parcelable Bar {
5145 const int A = 1;
5146 const int B = (A + 1) /* 2 */;
5147 }
5148 )"),
5149 actual);
5150 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
5151 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5152 enum Enum {
5153 A,
5154 B = (A + 2) /* 2 */,
5155 }
5156 )"),
5157 actual);
5158 }
5159
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators)5160 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators) {
5161 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5162 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5163 package p;
5164 import p.Enum;
5165 parcelable Foo {
5166 Enum e = Enum.FOO | Enum.BAR;
5167 })");
5168 CaptureStderr();
5169 auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
5170 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5171 auto err = GetCapturedStderr();
5172 EXPECT_EQ("ERROR: a/p/Foo.aidl:5.11-20: Invalid value (Enum.FOO|Enum.BAR) for enum p.Enum\n",
5173 err);
5174 }
5175
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators_RejectsNumericValue)5176 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators_RejectsNumericValue) {
5177 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5178 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5179 package p;
5180 import p.Enum;
5181 parcelable Foo {
5182 Enum e = 1;
5183 })");
5184 CaptureStderr();
5185 auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
5186 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5187 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Invalid value (1) for enum p.Enum"));
5188 }
5189
TEST_P(AidlTest,DefaultWithEmptyArray)5190 TEST_P(AidlTest, DefaultWithEmptyArray) {
5191 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; parcelable Foo { p.Bar[] bars = {}; }");
5192 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; parcelable Bar { }");
5193 CaptureStderr();
5194 auto options =
5195 Options::From("aidl -I a --lang " + to_string(GetLanguage()) + " -o out -h out a/p/Foo.aidl");
5196 EXPECT_TRUE(compile_aidl(options, io_delegate_));
5197 auto err = GetCapturedStderr();
5198 EXPECT_EQ("", err);
5199 }
5200
TEST_P(AidlTest,RejectRefsInAnnotation)5201 TEST_P(AidlTest, RejectRefsInAnnotation) {
5202 io_delegate_.SetFileContents("a/p/IFoo.aidl",
5203 "package p; interface IFoo {\n"
5204 " const String ANNOTATION = \"@Annotation\";\n"
5205 " @JavaPassthrough(annotation=ANNOTATION) void foo();\n"
5206 "}");
5207 CaptureStderr();
5208 auto options = Options::From("aidl -I a --lang " + to_string(GetLanguage()) +
5209 " -o out -h out a/p/IFoo.aidl");
5210 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5211 auto err = GetCapturedStderr();
5212 EXPECT_EQ(
5213 "ERROR: a/p/IFoo.aidl:3.31-41: Value must be a constant expression but contains reference to "
5214 "ANNOTATION.\n",
5215 err);
5216 }
5217
TEST_F(AidlTest,DefaultWithEnumValues)5218 TEST_F(AidlTest, DefaultWithEnumValues) {
5219 io_delegate_.SetFileContents(
5220 "a/p/Foo.aidl",
5221 "package p; import p.Bar; parcelable Foo { Bar[] bars = { Bar.FOO, Bar.FOO }; }");
5222 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; enum Bar { FOO, BAR }");
5223 CaptureStderr();
5224 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5225 EXPECT_TRUE(compile_aidl(options, io_delegate_));
5226 auto err = GetCapturedStderr();
5227 EXPECT_EQ("", err);
5228 string code;
5229 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
5230 EXPECT_THAT(
5231 code, testing::HasSubstr(
5232 "std::vector<::aidl::p::Bar> bars = {::aidl::p::Bar::FOO, ::aidl::p::Bar::FOO};"));
5233 }
5234
TEST_F(AidlTest,RejectsCircularReferencingEnumerators)5235 TEST_F(AidlTest, RejectsCircularReferencingEnumerators) {
5236 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; enum Foo { A = B, B }");
5237 CaptureStderr();
5238 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5239 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5240 auto err = GetCapturedStderr();
5241 EXPECT_EQ("ERROR: a/p/Foo.aidl:1.26-28: Found a circular reference: B -> A -> B\n", err);
5242 }
5243
TEST_F(AidlTest,RejectsCircularReferencingConsts)5244 TEST_F(AidlTest, RejectsCircularReferencingConsts) {
5245 io_delegate_.SetFileContents("a/p/Foo.aidl",
5246 "package p; parcelable Foo { const int A = A + 1; }");
5247 CaptureStderr();
5248 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5249 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5250 auto err = GetCapturedStderr();
5251 EXPECT_EQ("ERROR: a/p/Foo.aidl:1.42-44: Found a circular reference: A -> A\n", err);
5252 }
5253
TEST_F(AidlTest,RecursiveReferences)5254 TEST_F(AidlTest, RecursiveReferences) {
5255 io_delegate_.SetFileContents("a/p/Foo.aidl",
5256 "package p; parcelable Foo { const int A = p.Bar.A + 1; }");
5257 io_delegate_.SetFileContents("a/p/Bar.aidl",
5258 "package p; parcelable Bar { const int A = p.Baz.A + 1; }");
5259 io_delegate_.SetFileContents("a/p/Baz.aidl", "package p; parcelable Baz { const int A = 1; }");
5260 CaptureStderr();
5261 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5262 EXPECT_TRUE(compile_aidl(options, io_delegate_));
5263 EXPECT_EQ("", GetCapturedStderr());
5264 }
5265
TEST_P(AidlTest,CircularReferenceWithFullyQualified)5266 TEST_P(AidlTest, CircularReferenceWithFullyQualified) {
5267 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = Foo.A }");
5268 auto options =
5269 Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Foo.aidl");
5270 const string err = "ERROR: Foo.aidl:1.15-21: Found a circular reference: Foo.A -> Foo.A\n";
5271 CaptureStderr();
5272 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5273 EXPECT_EQ(err, GetCapturedStderr());
5274 }
5275
TEST_P(AidlTest,ConstRefsCanPointToTheSameValue)5276 TEST_P(AidlTest, ConstRefsCanPointToTheSameValue) {
5277 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = 0 }");
5278 // this demonstrates the case that "Foo.A" const-ref node is visited twice by B and C.
5279 io_delegate_.SetFileContents("Bar.aidl", "enum Bar { A = Foo.A, B = A, C = A }");
5280 auto options =
5281 Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Bar.aidl");
5282 CaptureStderr();
5283 EXPECT_TRUE(compile_aidl(options, io_delegate_));
5284 EXPECT_EQ("", GetCapturedStderr());
5285 }
5286
TEST_P(AidlTest,UnknownConstReference)5287 TEST_P(AidlTest, UnknownConstReference) {
5288 io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { int field = UNKNOWN_REF; }");
5289 auto options =
5290 Options::From("aidl -I . --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
5291 const string err =
5292 "ERROR: Foo.aidl:1.30-42: Can't find UNKNOWN_REF in Foo\n"
5293 "ERROR: Foo.aidl:1.30-42: Unknown reference 'UNKNOWN_REF'\n";
5294 CaptureStderr();
5295 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5296 EXPECT_EQ(err, GetCapturedStderr());
5297 }
5298
TEST_P(AidlTest,JavaCompatibleBuiltinTypes)5299 TEST_P(AidlTest, JavaCompatibleBuiltinTypes) {
5300 string contents = R"(
5301 import android.os.IBinder;
5302 import android.os.IInterface;
5303 interface IFoo {}
5304 )";
5305 EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
5306 }
5307
TEST_P(AidlTest,WarningInterfaceName)5308 TEST_P(AidlTest, WarningInterfaceName) {
5309 io_delegate_.SetFileContents("p/Foo.aidl", "package p; interface Foo {}");
5310 auto options = Options::From("aidl -I . --lang " + to_string(GetLanguage()) +
5311 " -Winterface-name -o out -h out p/Foo.aidl");
5312 CaptureStderr();
5313 EXPECT_TRUE(compile_aidl(options, io_delegate_));
5314 EXPECT_EQ(
5315 "WARNING: p/Foo.aidl:1.11-21: Interface names should start with I. [-Winterface-name]\n",
5316 GetCapturedStderr());
5317 }
5318
TEST_P(AidlTest,ErrorInterfaceName)5319 TEST_P(AidlTest, ErrorInterfaceName) {
5320 io_delegate_.SetFileContents("p/Foo.aidl", "package p; interface Foo {}");
5321 auto options = Options::From("aidl -I . --lang " + to_string(GetLanguage()) +
5322 " -Winterface-name -Werror -o out -h out p/Foo.aidl");
5323 CaptureStderr();
5324 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5325 EXPECT_EQ("ERROR: p/Foo.aidl:1.11-21: Interface names should start with I. [-Winterface-name]\n",
5326 GetCapturedStderr());
5327 }
5328
TEST_F(AidlTest,RejectsIncorrectOutputFilePathOnLegacyCppInput)5329 TEST_F(AidlTest, RejectsIncorrectOutputFilePathOnLegacyCppInput) {
5330 const std::string input_file = "base/p/q/IFoo.aidl";
5331 const std::string header_dir = "out/";
5332 const std::string output_file = "out/base/p/q/IFoo.cpp";
5333 io_delegate_.SetFileContents(input_file, "package p.q; interface IFoo {}");
5334
5335 auto options = Options::From({"aidl-cpp", "-I base", input_file, header_dir, output_file});
5336 CaptureStderr();
5337 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5338 EXPECT_THAT(
5339 GetCapturedStderr(),
5340 testing::StartsWith(
5341 "ERROR: base/p/q/IFoo.aidl:1.13-23: Output file is expected to be at out/p/q/IFoo.cpp, "
5342 "but is out/base/p/q/IFoo.cpp."));
5343 }
5344
TEST_F(AidlTest,FormatCommentsForJava)5345 TEST_F(AidlTest, FormatCommentsForJava) {
5346 using android::aidl::FormatCommentsForJava;
5347
5348 struct TestCase {
5349 vector<Comment> comments;
5350 string formatted;
5351 };
5352 vector<TestCase> testcases = {
5353 {{}, ""},
5354 {{{"// line comments\n"}}, "// line comments\n"},
5355 {{{"// @hide \n"}}, "// @hide \n"},
5356 // Transform the last block comment as Javadoc.
5357 {{{"/*\n"
5358 " * Hello, world!\n"
5359 " */"}},
5360 "/** Hello, world! */\n"},
5361 {{{"/* @hide */"}}, "/** @hide */\n"},
5362 {{{"/**\n"
5363 " @param foo ...\n"
5364 "*/"}},
5365 "/** @param foo ... */\n"},
5366 {{{"/* @hide */"}, {"/* @hide */"}}, "/* @hide */\n/** @hide */\n"},
5367 {{{"/* @deprecated first */"}, {"/* @deprecated second */"}},
5368 "/* @deprecated first */\n/** @deprecated second */\n"},
5369 {{{"/* @deprecated */"}, {"/** @param foo */"}}, "/* @deprecated */\n/** @param foo */\n"},
5370 // Line comments are printed as they are
5371 {{{"/* @deprecated */"}, {"// line comments\n"}}, "/* @deprecated */\n// line comments\n"},
5372 };
5373 for (const auto& [input, formatted] : testcases) {
5374 EXPECT_EQ(formatted, FormatCommentsForJava(input));
5375 }
5376 }
5377
TEST_F(AidlTest,SuppressWarningsIsNotForArgs)5378 TEST_F(AidlTest, SuppressWarningsIsNotForArgs) {
5379 io_delegate_.SetFileContents(
5380 "IFoo.aidl",
5381 "interface IFoo {\n"
5382 " void foo(in @SuppressWarnings(value={\"inout-parameter\"}) int x);\n"
5383 "}");
5384 auto options = Options::From("aidl -I . --lang=java IFoo.aidl");
5385 CaptureStderr();
5386 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5387 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@SuppressWarnings is not available"));
5388 }
5389
TEST_F(AidlTest,VoidCantBeUsedInMethodParameterType)5390 TEST_F(AidlTest, VoidCantBeUsedInMethodParameterType) {
5391 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; interface IFoo{ void j(void n);}");
5392 auto options = Options::From("aidl -I . --lang=java -o out p/IFoo.aidl");
5393 CaptureStderr();
5394 EXPECT_FALSE(compile_aidl(options, io_delegate_));
5395 EXPECT_THAT(GetCapturedStderr(), HasSubstr("'void' is an invalid type for the parameter 'n'"));
5396 }
5397
TEST_F(AidlTest,InterfaceVectorIsAvailableAfterTiramisu)5398 TEST_F(AidlTest, InterfaceVectorIsAvailableAfterTiramisu) {
5399 io_delegate_.SetFileContents("p/IFoo.aidl",
5400 "package p;\n"
5401 "interface IFoo{\n"
5402 " void foo(in IFoo[] n);\n"
5403 " void bar(in List<IFoo> n);\n"
5404 "}");
5405 CaptureStderr();
5406 EXPECT_FALSE(
5407 compile_aidl(Options::From("aidl -I . --lang=java --min_sdk_version 30 -o out p/IFoo.aidl"),
5408 io_delegate_));
5409 auto captured_stderr = GetCapturedStderr();
5410 EXPECT_THAT(captured_stderr, HasSubstr("Array of interfaces is available since"));
5411 EXPECT_THAT(captured_stderr, HasSubstr("List of interfaces is available since"));
5412
5413 CaptureStderr();
5414 EXPECT_TRUE(compile_aidl(
5415 Options::From("aidl -I . --lang=java --min_sdk_version Tiramisu -o out p/IFoo.aidl"),
5416 io_delegate_));
5417 EXPECT_EQ(GetCapturedStderr(), "");
5418 }
5419
TEST_F(AidlTest,RustNameOf_PfdFixedArray)5420 TEST_F(AidlTest, RustNameOf_PfdFixedArray) {
5421 auto pfd = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "ParcelFileDescriptor", false);
5422 ASSERT_TRUE(pfd->MakeArray(FixedSizeArray{
5423 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(AIDL_LOCATION_HERE, "2"))}));
5424 ASSERT_TRUE(pfd->MakeArray(FixedSizeArray{
5425 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(AIDL_LOCATION_HERE, "3"))}));
5426 EXPECT_EQ(
5427 rust::RustNameOf(*pfd, typenames_, rust::StorageMode::PARCELABLE_FIELD, rust::Lifetime::NONE),
5428 "[[Option<binder::ParcelFileDescriptor>; 3]; 2]");
5429 EXPECT_EQ(
5430 rust::RustNameOf(*pfd, typenames_, rust::StorageMode::DEFAULT_VALUE, rust::Lifetime::NONE),
5431 "[[Option<binder::ParcelFileDescriptor>; 3]; 2]");
5432 EXPECT_EQ(
5433 rust::RustNameOf(*pfd, typenames_, rust::StorageMode::IN_ARGUMENT, rust::Lifetime::NONE),
5434 "&[[binder::ParcelFileDescriptor; 3]; 2]");
5435 EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::VALUE, rust::Lifetime::NONE),
5436 "[[binder::ParcelFileDescriptor; 3]; 2]");
5437 }
5438
TEST_F(AidlTest,RustNameOf_PfdDynamicArray)5439 TEST_F(AidlTest, RustNameOf_PfdDynamicArray) {
5440 auto pfd = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "ParcelFileDescriptor", true);
5441 EXPECT_EQ(
5442 rust::RustNameOf(*pfd, typenames_, rust::StorageMode::PARCELABLE_FIELD, rust::Lifetime::NONE),
5443 "Vec<binder::ParcelFileDescriptor>");
5444 EXPECT_EQ(
5445 rust::RustNameOf(*pfd, typenames_, rust::StorageMode::DEFAULT_VALUE, rust::Lifetime::NONE),
5446 "Vec<Option<binder::ParcelFileDescriptor>>");
5447 // we use UNSIZED_ARGUMENT mode for input argument of dynamic array
5448 EXPECT_EQ(
5449 rust::RustNameOf(*pfd, typenames_, rust::StorageMode::UNSIZED_ARGUMENT, rust::Lifetime::NONE),
5450 "&[binder::ParcelFileDescriptor]");
5451 EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::VALUE, rust::Lifetime::NONE),
5452 "Vec<binder::ParcelFileDescriptor>");
5453 }
5454
5455 struct TypeParam {
5456 string kind;
5457 string literal;
5458 };
5459
5460 const TypeParam kTypeParams[] = {
5461 {"primitive", "int"},
5462 {"primitiveArray", "int[]"},
5463 {"primitiveFixedArray", "int[3]"},
5464 {"String", "String"},
5465 {"StringArray", "String[]"},
5466 {"IBinder", "IBinder"},
5467 {"ParcelFileDescriptor", "ParcelFileDescriptor"},
5468 {"parcelable", "a.Foo"},
5469 {"enum", "a.Enum"},
5470 {"union", "a.Union"},
5471 {"interface", "a.IBar"},
5472 };
5473
5474 struct ExpectedResult {
5475 string expected_error;
5476 string expected_error_for_nullable;
5477 };
5478
5479 const std::map<std::string, ExpectedResult> kListSupportExpectations = {
5480 {"cpp_primitive", {"A generic type cannot", "A generic type cannot"}},
5481 {"java_primitive", {"A generic type cannot", "A generic type cannot"}},
5482 {"ndk_primitive", {"A generic type cannot", "A generic type cannot"}},
5483 {"rust_primitive", {"A generic type cannot", "A generic type cannot"}},
5484 {"cpp_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5485 {"java_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5486 {"ndk_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5487 {"rust_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5488 {"cpp_primitiveFixedArray",
5489 {"List of arrays is not supported", "List of arrays is not supported"}},
5490 {"java_primitiveFixedArray",
5491 {"List of arrays is not supported", "List of arrays is not supported"}},
5492 {"ndk_primitiveFixedArray",
5493 {"List of arrays is not supported", "List of arrays is not supported"}},
5494 {"rust_primitiveFixedArray",
5495 {"List of arrays is not supported", "List of arrays is not supported"}},
5496 {"cpp_String", {"", ""}},
5497 {"java_String", {"", ""}},
5498 {"ndk_String", {"", ""}},
5499 {"rust_String", {"", ""}},
5500 {"cpp_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5501 {"java_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5502 {"ndk_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5503 {"rust_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5504 {"cpp_IBinder", {"", ""}},
5505 {"java_IBinder", {"", ""}},
5506 {"ndk_IBinder", {"", ""}},
5507 {"rust_IBinder", {"", ""}},
5508 {"cpp_ParcelFileDescriptor", {"", ""}},
5509 {"java_ParcelFileDescriptor", {"", ""}},
5510 {"ndk_ParcelFileDescriptor", {"", ""}},
5511 {"rust_ParcelFileDescriptor", {"", ""}},
5512 {"cpp_interface", {"", ""}},
5513 {"java_interface", {"", ""}},
5514 {"ndk_interface", {"", ""}},
5515 {"rust_interface", {"", ""}},
5516 {"cpp_parcelable", {"", ""}},
5517 {"java_parcelable", {"", ""}},
5518 {"ndk_parcelable", {"", ""}},
5519 {"rust_parcelable", {"", ""}},
5520 {"cpp_enum", {"A generic type cannot", "A generic type cannot"}},
5521 {"java_enum", {"A generic type cannot", "A generic type cannot"}},
5522 {"ndk_enum", {"A generic type cannot", "A generic type cannot"}},
5523 {"rust_enum", {"A generic type cannot", "A generic type cannot"}},
5524 {"cpp_union", {"", ""}},
5525 {"java_union", {"", ""}},
5526 {"ndk_union", {"", ""}},
5527 {"rust_union", {"", ""}},
5528 };
5529
5530 const std::map<std::string, ExpectedResult> kArraySupportExpectations = {
5531 {"cpp_primitive", {"", ""}},
5532 {"java_primitive", {"", ""}},
5533 {"ndk_primitive", {"", ""}},
5534 {"rust_primitive", {"", ""}},
5535 {"cpp_primitiveArray",
5536 {"Multi-dimensional arrays must be fixed size.",
5537 "Multi-dimensional arrays must be fixed size."}},
5538 {"java_primitiveArray",
5539 {"Multi-dimensional arrays must be fixed size.",
5540 "Multi-dimensional arrays must be fixed size."}},
5541 {"ndk_primitiveArray",
5542 {"Multi-dimensional arrays must be fixed size.",
5543 "Multi-dimensional arrays must be fixed size."}},
5544 {"rust_primitiveArray",
5545 {"Multi-dimensional arrays must be fixed size.",
5546 "Multi-dimensional arrays must be fixed size."}},
5547 {"cpp_primitiveFixedArray",
5548 {"Multi-dimensional arrays must be fixed size.",
5549 "Multi-dimensional arrays must be fixed size."}},
5550 {"java_primitiveFixedArray",
5551 {"Multi-dimensional arrays must be fixed size.",
5552 "Multi-dimensional arrays must be fixed size."}},
5553 {"ndk_primitiveFixedArray",
5554 {"Multi-dimensional arrays must be fixed size.",
5555 "Multi-dimensional arrays must be fixed size."}},
5556 {"rust_primitiveFixedArray",
5557 {"Multi-dimensional arrays must be fixed size.",
5558 "Multi-dimensional arrays must be fixed size."}},
5559 {"cpp_String", {"", ""}},
5560 {"java_String", {"", ""}},
5561 {"ndk_String", {"", ""}},
5562 {"rust_String", {"", ""}},
5563 {"cpp_StringArray",
5564 {"Multi-dimensional arrays must be fixed size.",
5565 "Multi-dimensional arrays must be fixed size."}},
5566 {"java_StringArray",
5567 {"Multi-dimensional arrays must be fixed size.",
5568 "Multi-dimensional arrays must be fixed size."}},
5569 {"ndk_StringArray",
5570 {"Multi-dimensional arrays must be fixed size.",
5571 "Multi-dimensional arrays must be fixed size."}},
5572 {"rust_StringArray",
5573 {"Multi-dimensional arrays must be fixed size.",
5574 "Multi-dimensional arrays must be fixed size."}},
5575 {"cpp_IBinder", {"", ""}},
5576 {"java_IBinder", {"", ""}},
5577 {"ndk_IBinder", {"", ""}},
5578 {"rust_IBinder", {"", ""}},
5579 {"cpp_ParcelFileDescriptor", {"", ""}},
5580 {"java_ParcelFileDescriptor", {"", ""}},
5581 {"ndk_ParcelFileDescriptor", {"", ""}},
5582 {"rust_ParcelFileDescriptor", {"", ""}},
5583 {"cpp_interface", {"", ""}},
5584 {"java_interface", {"", ""}},
5585 {"ndk_interface", {"", ""}},
5586 {"rust_interface", {"", ""}},
5587 {"cpp_parcelable", {"", ""}},
5588 {"java_parcelable", {"", ""}},
5589 {"ndk_parcelable", {"", ""}},
5590 {"rust_parcelable", {"", ""}},
5591 {"cpp_enum", {"", ""}},
5592 {"java_enum", {"", ""}},
5593 {"ndk_enum", {"", ""}},
5594 {"rust_enum", {"", ""}},
5595 {"cpp_union", {"", ""}},
5596 {"java_union", {"", ""}},
5597 {"ndk_union", {"", ""}},
5598 {"rust_union", {"", ""}},
5599 };
5600
5601 const std::map<std::string, ExpectedResult> kFieldSupportExpectations = {
5602 {"cpp_primitive", {"", "cannot get nullable annotation"}},
5603 {"java_primitive", {"", "cannot get nullable annotation"}},
5604 {"ndk_primitive", {"", "cannot get nullable annotation"}},
5605 {"rust_primitive", {"", "cannot get nullable annotation"}},
5606 {"cpp_primitiveArray", {"", ""}},
5607 {"java_primitiveArray", {"", ""}},
5608 {"ndk_primitiveArray", {"", ""}},
5609 {"rust_primitiveArray", {"", ""}},
5610 {"cpp_primitiveFixedArray", {"", ""}},
5611 {"java_primitiveFixedArray", {"", ""}},
5612 {"ndk_primitiveFixedArray", {"", ""}},
5613 {"rust_primitiveFixedArray", {"", ""}},
5614 {"cpp_String", {"", ""}},
5615 {"java_String", {"", ""}},
5616 {"ndk_String", {"", ""}},
5617 {"rust_String", {"", ""}},
5618 {"cpp_StringArray", {"", ""}},
5619 {"java_StringArray", {"", ""}},
5620 {"ndk_StringArray", {"", ""}},
5621 {"rust_StringArray", {"", ""}},
5622 {"cpp_IBinder", {"", ""}},
5623 {"java_IBinder", {"", ""}},
5624 {"ndk_IBinder", {"", ""}},
5625 {"rust_IBinder", {"", ""}},
5626 {"cpp_ParcelFileDescriptor", {"", ""}},
5627 {"java_ParcelFileDescriptor", {"", ""}},
5628 {"ndk_ParcelFileDescriptor", {"", ""}},
5629 {"rust_ParcelFileDescriptor", {"", ""}},
5630 {"cpp_interface", {"", ""}},
5631 {"java_interface", {"", ""}},
5632 {"ndk_interface", {"", ""}},
5633 {"rust_interface", {"", ""}},
5634 {"cpp_parcelable", {"", ""}},
5635 {"java_parcelable", {"", ""}},
5636 {"ndk_parcelable", {"", ""}},
5637 {"rust_parcelable", {"", ""}},
5638 {"cpp_enum", {"", "cannot get nullable annotation"}},
5639 {"java_enum", {"", "cannot get nullable annotation"}},
5640 {"ndk_enum", {"", "cannot get nullable annotation"}},
5641 {"rust_enum", {"", "cannot get nullable annotation"}},
5642 {"cpp_union", {"", ""}},
5643 {"java_union", {"", ""}},
5644 {"ndk_union", {"", ""}},
5645 {"rust_union", {"", ""}},
5646 };
5647
5648 class AidlTypeParamTest
5649 : public testing::TestWithParam<std::tuple<Options::Language, TypeParam, bool>> {
5650 public:
Run(const std::string & generic_type_decl,const std::map<std::string,ExpectedResult> & expectations)5651 void Run(const std::string& generic_type_decl,
5652 const std::map<std::string, ExpectedResult>& expectations) {
5653 const auto& param = GetParam();
5654 const auto& lang = to_string(std::get<0>(param));
5655 const auto& kind = std::get<1>(param).kind;
5656 const bool nullable = std::get<2>(param);
5657
5658 FakeIoDelegate io;
5659 io.SetFileContents("a/IBar.aidl", "package a; interface IBar { }");
5660 io.SetFileContents("a/Enum.aidl", "package a; enum Enum { A }");
5661 io.SetFileContents("a/Union.aidl", "package a; union Union { int a; }");
5662 io.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { int a; }");
5663 std::string decl = fmt::format(generic_type_decl, std::get<1>(param).literal);
5664 if (nullable) {
5665 decl = "@nullable " + decl;
5666 }
5667 io.SetFileContents("a/Target.aidl", "package a; parcelable Target { " + decl + " f; }");
5668
5669 const auto options = Options::From(fmt::format(
5670 "aidl -I . --min_sdk_version current --lang={} a/Target.aidl -o out -h out", lang));
5671 CaptureStderr();
5672 compile_aidl(options, io);
5673 auto it = expectations.find(lang + "_" + kind);
5674 ASSERT_TRUE(it != expectations.end()) << "missing expectation for " << lang << "_" << kind;
5675 const string err = GetCapturedStderr();
5676 const string expected_error =
5677 nullable ? it->second.expected_error_for_nullable : it->second.expected_error;
5678 if (expected_error.empty()) {
5679 EXPECT_EQ("", err);
5680 } else {
5681 EXPECT_THAT(err, testing::HasSubstr(expected_error));
5682 }
5683 }
5684 };
5685
5686 INSTANTIATE_TEST_SUITE_P(
5687 AidlTestSuite, AidlTypeParamTest,
5688 testing::Combine(testing::Values(Options::Language::CPP, Options::Language::JAVA,
5689 Options::Language::NDK, Options::Language::RUST),
5690 testing::ValuesIn(kTypeParams), testing::Values(true, false)),
__anon0e32cfeb0702(const testing::TestParamInfo<std::tuple<Options::Language, TypeParam, bool>>& info) 5691 [](const testing::TestParamInfo<std::tuple<Options::Language, TypeParam, bool>>& info) {
5692 string name = to_string(std::get<0>(info.param)) + "_" + std::get<1>(info.param).kind;
5693 if (std::get<2>(info.param)) {
5694 name += "_nullable";
5695 }
5696 return name;
5697 });
5698
TEST_P(AidlTypeParamTest,ListSupportedTypes)5699 TEST_P(AidlTypeParamTest, ListSupportedTypes) {
5700 Run("List<{}>", kListSupportExpectations);
5701 }
5702
TEST_P(AidlTypeParamTest,ArraySupportedTypes)5703 TEST_P(AidlTypeParamTest, ArraySupportedTypes) {
5704 Run("{}[]", kArraySupportExpectations);
5705 }
5706
TEST_P(AidlTypeParamTest,ParcelableFieldTypes)5707 TEST_P(AidlTypeParamTest, ParcelableFieldTypes) {
5708 Run("{}", kFieldSupportExpectations);
5709 }
5710
5711 } // namespace aidl
5712 } // namespace android
5713