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