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