blob: 4d77f84628f5b016c4550843cbcf1df29f284328 [file] [log] [blame]
Christopher Wiley90be4e32015-10-20 14:55:25 -07001/*
2 * Copyright (C) 2015, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jooyung Han1f14ab32020-10-14 13:48:29 +090017#include "aidl.h"
Christopher Wiley90be4e32015-10-20 14:55:25 -070018
Jooyung Hane87cdd02020-12-11 16:47:35 +090019#include <android-base/format.h>
Christopher Wileyec31a052016-01-25 07:28:51 -080020#include <android-base/stringprintf.h>
Jiyong Parkf1f5c802020-05-19 17:33:00 +090021#include <gmock/gmock.h>
Christopher Wiley90be4e32015-10-20 14:55:25 -070022#include <gtest/gtest.h>
23
Jooyung Han1f14ab32020-10-14 13:48:29 +090024#include <map>
25#include <memory>
26#include <set>
27#include <string>
28#include <vector>
29
Steven Moreland49585242019-12-18 16:06:49 -080030#include "aidl_checkapi.h"
Christopher Wiley90be4e32015-10-20 14:55:25 -070031#include "aidl_language.h"
Steven Moreland860b1942018-08-16 14:59:28 -070032#include "aidl_to_cpp.h"
Jeongik Cha047c5ee2019-08-07 23:16:49 +090033#include "aidl_to_java.h"
Jiyong Park2a7c92b2020-07-22 19:12:36 +090034#include "logging.h"
Jeongik Cha047c5ee2019-08-07 23:16:49 +090035#include "options.h"
Christopher Wiley90be4e32015-10-20 14:55:25 -070036#include "tests/fake_io_delegate.h"
Christopher Wiley90be4e32015-10-20 14:55:25 -070037
Jeongik Cha2a5b4d82019-08-06 19:37:59 +090038using android::aidl::internals::parse_preprocessed_file;
Christopher Wiley90be4e32015-10-20 14:55:25 -070039using android::aidl::test::FakeIoDelegate;
Christopher Wileyec31a052016-01-25 07:28:51 -080040using android::base::StringPrintf;
Jooyung Han1f14ab32020-10-14 13:48:29 +090041using std::map;
Christopher Wiley12e894a2016-01-29 11:55:07 -080042using std::set;
Christopher Wiley90be4e32015-10-20 14:55:25 -070043using std::string;
44using std::unique_ptr;
Christopher Wiley12e894a2016-01-29 11:55:07 -080045using std::vector;
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +090046using testing::HasSubstr;
Devin Moore7b8d5c92020-03-17 14:14:08 -070047using testing::TestParamInfo;
Jeongik Cha2a5b4d82019-08-06 19:37:59 +090048using testing::internal::CaptureStderr;
49using testing::internal::GetCapturedStderr;
Christopher Wiley90be4e32015-10-20 14:55:25 -070050
51namespace android {
52namespace aidl {
Christopher Wileyf8136192016-04-12 14:19:35 -070053namespace {
54
55const char kExpectedDepFileContents[] =
56R"(place/for/output/p/IFoo.java : \
57 p/IFoo.aidl
58
59p/IFoo.aidl :
60)";
61
Dan Willemsen93298ee2016-11-10 23:55:55 -080062const char kExpectedNinjaDepFileContents[] =
63R"(place/for/output/p/IFoo.java : \
64 p/IFoo.aidl
65)";
66
Jiyong Parkdf202122019-09-30 20:48:35 +090067const char kExpectedParcelableDeclarationDepFileContents[] =
68 R"( : \
69 p/Foo.aidl
70
71p/Foo.aidl :
72)";
73
74const char kExpectedStructuredParcelableDepFileContents[] =
Steven Moreland2a9a7d62019-02-05 16:11:54 -080075 R"(place/for/output/p/Foo.java : \
Christopher Wileyb1bbdf82016-04-21 11:43:45 -070076 p/Foo.aidl
77
78p/Foo.aidl :
79)";
80
Jooyung Hand2fa0232020-10-19 02:51:41 +090081const char kExpectedJavaParcelableOutputContents[] =
Jeongik Chaa755c2a2018-12-12 16:28:23 +090082 R"(/*
83 * This file is auto-generated. DO NOT MODIFY.
Jeongik Chaa755c2a2018-12-12 16:28:23 +090084 */
Makoto Onuki78a1c1c2020-03-04 16:57:23 -080085@android.annotation.Hide
Jeongik Chaa755c2a2018-12-12 16:28:23 +090086public class Rect implements android.os.Parcelable
87{
88 // Comment
89
Makoto Onuki78a1c1c2020-03-04 16:57:23 -080090 @android.annotation.Hide
Jeongik Chaa755c2a2018-12-12 16:28:23 +090091 public int x = 5;
92
Makoto Onuki78a1c1c2020-03-04 16:57:23 -080093 @android.annotation.Hide
94 @android.compat.annotation.UnsupportedAppUsage(expectedSignature = "dummy", implicitMember = "dummy", maxTargetSdk = 28, publicAlternatives = "dummy", trackingBug = 42L, overrideSourcePosition="Rect.aidl:7:1:10:14")
Steven Moreland541788d2020-05-21 22:05:52 +000095 public int y = 0;
Jiyong Parkd4e73c82019-07-24 21:39:15 +090096
97 public android.os.ParcelFileDescriptor fd;
Jooyung Hand2fa0232020-10-19 02:51:41 +090098
99 public java.util.List<android.os.ParcelFileDescriptor> fds;
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900100 public static final android.os.Parcelable.Creator<Rect> CREATOR = new android.os.Parcelable.Creator<Rect>() {
101 @Override
102 public Rect createFromParcel(android.os.Parcel _aidl_source) {
103 Rect _aidl_out = new Rect();
104 _aidl_out.readFromParcel(_aidl_source);
105 return _aidl_out;
106 }
107 @Override
108 public Rect[] newArray(int _aidl_size) {
109 return new Rect[_aidl_size];
110 }
111 };
112 @Override public final void writeToParcel(android.os.Parcel _aidl_parcel, int _aidl_flag)
113 {
114 int _aidl_start_pos = _aidl_parcel.dataPosition();
115 _aidl_parcel.writeInt(0);
116 _aidl_parcel.writeInt(x);
117 _aidl_parcel.writeInt(y);
Jiyong Parkd4e73c82019-07-24 21:39:15 +0900118 if ((fd!=null)) {
119 _aidl_parcel.writeInt(1);
120 fd.writeToParcel(_aidl_parcel, 0);
121 }
122 else {
123 _aidl_parcel.writeInt(0);
124 }
Jooyung Hana61aa232020-10-20 04:00:08 +0900125 _aidl_parcel.writeTypedList(fds);
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900126 int _aidl_end_pos = _aidl_parcel.dataPosition();
127 _aidl_parcel.setDataPosition(_aidl_start_pos);
128 _aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);
129 _aidl_parcel.setDataPosition(_aidl_end_pos);
130 }
131 public final void readFromParcel(android.os.Parcel _aidl_parcel)
132 {
133 int _aidl_start_pos = _aidl_parcel.dataPosition();
134 int _aidl_parcelable_size = _aidl_parcel.readInt();
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900135 try {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900136 if (_aidl_parcelable_size < 0) return;
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900137 x = _aidl_parcel.readInt();
138 if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
139 y = _aidl_parcel.readInt();
140 if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
Jiyong Parkd4e73c82019-07-24 21:39:15 +0900141 if ((0!=_aidl_parcel.readInt())) {
142 fd = android.os.ParcelFileDescriptor.CREATOR.createFromParcel(_aidl_parcel);
143 }
144 else {
145 fd = null;
146 }
147 if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
Jooyung Hana61aa232020-10-20 04:00:08 +0900148 fds = _aidl_parcel.createTypedArrayList(android.os.ParcelFileDescriptor.CREATOR);
Jooyung Hand2fa0232020-10-19 02:51:41 +0900149 if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900150 } finally {
Jeongik Cha8b329982020-09-01 20:59:36 +0900151 if (_aidl_start_pos > (Integer.MAX_VALUE - _aidl_parcelable_size)) {
152 throw new android.os.BadParcelableException("Overflow in the size of parcelable");
153 }
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900154 _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);
155 }
156 }
Jooyung Hand2fa0232020-10-19 02:51:41 +0900157 @Override
158 public int describeContents() {
159 int _mask = 0;
Jooyung Hanea2147c2020-10-21 18:16:56 +0900160 _mask |= describeContents(fd);
161 _mask |= describeContents(fds);
Jooyung Hand2fa0232020-10-19 02:51:41 +0900162 return _mask;
Jeongik Cha372a8c82018-12-12 16:31:11 +0900163 }
Jooyung Hanea2147c2020-10-21 18:16:56 +0900164 private int describeContents(Object _v) {
165 if (_v == null) return 0;
166 if (_v instanceof java.util.Collection) {
167 int _mask = 0;
168 for (Object o : (java.util.Collection) _v) {
169 _mask |= describeContents(o);
170 }
171 return _mask;
172 }
173 if (_v instanceof android.os.Parcelable) {
174 return ((android.os.Parcelable) _v).describeContents();
175 }
176 return 0;
177 }
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900178}
179)";
180
Devin Moore2f2077a2020-08-28 11:27:53 -0700181// clang-format off
182const char kExpectedCppHeaderOutput[] =
183 R"(#pragma once
184
185#include <binder/IBinder.h>
186#include <binder/IInterface.h>
187#include <binder/Status.h>
188#include <optional>
189#include <utils/String16.h>
190#include <utils/StrongPointer.h>
191#include <vector>
192
193class IFoo : public ::android::IInterface {
194public:
195 DECLARE_META_INTERFACE(Foo)
196 virtual ::android::binder::Status foo(::std::optional<::std::vector<::std::optional<::android::String16>>>* _aidl_return) = 0;
197}; // class IFoo
198class IFooDefault : public IFoo {
199public:
200 ::android::IBinder* onAsBinder() override {
201 return nullptr;
202 }
203 ::android::binder::Status foo(::std::optional<::std::vector<::std::optional<::android::String16>>>*) override {
204 return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
205 }
206}; // class IFooDefault
207)";
208// clang-format on
209
Christopher Wileyf8136192016-04-12 14:19:35 -0700210} // namespace
Christopher Wiley90be4e32015-10-20 14:55:25 -0700211
Devin Moore7b8d5c92020-03-17 14:14:08 -0700212class AidlTest : public ::testing::TestWithParam<Options::Language> {
Christopher Wiley90be4e32015-10-20 14:55:25 -0700213 protected:
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900214 AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
215 Options::Language lang, AidlError* error = nullptr,
Steven Moreland1eac5fa2018-08-27 19:35:05 -0700216 const vector<string> additional_arguments = {}) {
Christopher Wiley0522cd52015-10-28 15:39:44 -0700217 io_delegate_.SetFileContents(path, contents);
Jiyong Parkfbbfa932018-07-30 21:44:10 +0900218 vector<string> args;
Devin Moore7b8d5c92020-03-17 14:14:08 -0700219 args.emplace_back("aidl");
Jooyung Han9435e9a2021-01-06 10:16:31 +0900220 args.emplace_back("--lang=" + to_string(lang));
Steven Moreland1eac5fa2018-08-27 19:35:05 -0700221 for (const string& s : additional_arguments) {
222 args.emplace_back(s);
223 }
224 for (const string& f : preprocessed_files_) {
Jiyong Parkfbbfa932018-07-30 21:44:10 +0900225 args.emplace_back("--preprocessed=" + f);
226 }
Steven Moreland1eac5fa2018-08-27 19:35:05 -0700227 for (const string& i : import_paths_) {
Jiyong Parkfbbfa932018-07-30 21:44:10 +0900228 args.emplace_back("--include=" + i);
229 }
230 args.emplace_back(path);
231 Options options = Options::From(args);
Jiyong Parkb034bf02018-07-30 17:44:33 +0900232 vector<string> imported_files;
Jiyong Park8c380532018-08-30 14:55:26 +0900233 ImportResolver import_resolver{io_delegate_, path, import_paths_, {}};
Christopher Wiley69b44cf2016-05-03 13:43:33 -0700234 AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900235 path, options, io_delegate_, &typenames_, &imported_files);
Jiyong Parkb034bf02018-07-30 17:44:33 +0900236
Christopher Wiley69b44cf2016-05-03 13:43:33 -0700237 if (error != nullptr) {
238 *error = actual_error;
239 }
Jiyong Parkb034bf02018-07-30 17:44:33 +0900240
241 if (actual_error != AidlError::OK) {
242 return nullptr;
243 }
244
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900245 const auto& defined_types = typenames_.MainDocument().DefinedTypes();
Jiyong Parkb034bf02018-07-30 17:44:33 +0900246 EXPECT_EQ(1ul, defined_types.size());
247
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900248 return defined_types.front().get();
Christopher Wiley90be4e32015-10-20 14:55:25 -0700249 }
Christopher Wiley0522cd52015-10-28 15:39:44 -0700250
Devin Moore7b8d5c92020-03-17 14:14:08 -0700251 Options::Language GetLanguage() { return GetParam(); }
252
Christopher Wiley0522cd52015-10-28 15:39:44 -0700253 FakeIoDelegate io_delegate_;
Christopher Wiley41544372015-11-03 14:52:29 -0800254 vector<string> preprocessed_files_;
Jiyong Park8c380532018-08-30 14:55:26 +0900255 set<string> import_paths_;
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900256 AidlTypenames typenames_;
Christopher Wiley90be4e32015-10-20 14:55:25 -0700257};
258
Devin Moore7b8d5c92020-03-17 14:14:08 -0700259// Instantiate the AidlTest parameterized suite, calling all of the TEST_P
260// tests with each of the supported languages as a parameter.
261INSTANTIATE_TEST_SUITE_P(AidlTestSuite, AidlTest,
262 testing::Values(Options::Language::CPP, Options::Language::JAVA,
Andrei Homescub62afd92020-05-11 19:24:59 -0700263 Options::Language::NDK, Options::Language::RUST),
Devin Moore7b8d5c92020-03-17 14:14:08 -0700264 [](const testing::TestParamInfo<Options::Language>& info) {
Jooyung Han9435e9a2021-01-06 10:16:31 +0900265 return to_string(info.param);
Devin Moore7b8d5c92020-03-17 14:14:08 -0700266 });
267
268TEST_P(AidlTest, AcceptMissingPackage) {
269 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, GetLanguage()));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700270}
271
Devin Moore7b8d5c92020-03-17 14:14:08 -0700272TEST_P(AidlTest, EndsInSingleLineComment) {
273 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, GetLanguage()));
Steven Moreland9c2988f2019-07-17 17:49:10 -0700274}
275
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000276TEST_P(AidlTest, InterfaceRequiresCorrectPath) {
277 const string expected_stderr =
278 "ERROR: a/Foo.aidl:1.11-21: IBar should be declared in a file called a/IBar.aidl\n";
279 const std::string file_contents = "package a; interface IBar {}";
280 CaptureStderr();
281 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
282 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
283}
284
285TEST_P(AidlTest, ParcelableRequiresCorrectPath) {
286 const string expected_stderr =
287 "ERROR: a/Foo.aidl:1.11-21: Bar should be declared in a file called a/Bar.aidl\n";
288 const std::string file_contents = "package a; interface Bar {}";
289 CaptureStderr();
290 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
291 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
292}
293
294TEST_P(AidlTest, UnstructuredParcelableRequiresCorrectPath) {
295 const string expected_stderr =
296 "ERROR: a/Foo.aidl:1.22-26: Bar should be declared in a file called a/Bar.aidl\n";
297 const std::string file_contents = "package a; parcelable Bar cpp_header \"anything.h\";";
298 CaptureStderr();
299 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
300 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
301}
302
303TEST_P(AidlTest, EnumRequiresCorrectPath) {
304 const string expected_stderr =
305 "ERROR: a/Foo.aidl:1.16-20: Bar should be declared in a file called a/Bar.aidl\n";
306 const std::string file_contents = "package a; enum Bar { A, }";
307 CaptureStderr();
308 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
309 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
310}
311
Devin Moore7b8d5c92020-03-17 14:14:08 -0700312TEST_P(AidlTest, RejectsArraysOfBinders) {
Jiyong Park8c380532018-08-30 14:55:26 +0900313 import_paths_.emplace("");
Christopher Wiley0522cd52015-10-28 15:39:44 -0700314 io_delegate_.SetFileContents("bar/IBar.aidl",
315 "package bar; interface IBar {}");
Devin Moore097a3ab2020-03-11 16:08:44 -0700316 const string path = "foo/IFoo.aidl";
317 const string contents =
318 "package foo;\n"
319 "import bar.IBar;\n"
320 "interface IFoo { void f(in IBar[] input); }";
321 const string expected_stderr = "ERROR: foo/IFoo.aidl:3.27-32: Binder type cannot be an array\n";
322 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700323 EXPECT_EQ(nullptr, Parse(path, contents, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700324 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley0522cd52015-10-28 15:39:44 -0700325}
326
Devin Moore7b8d5c92020-03-17 14:14:08 -0700327TEST_P(AidlTest, SupportOnlyOutParameters) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700328 const string interface_list = "package a; interface IBar { void f(out List<String> bar); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700329 EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, GetLanguage()));
Jiyong Park40782d02020-07-24 19:17:43 +0900330}
Devin Moore097a3ab2020-03-11 16:08:44 -0700331
Jiyong Park40782d02020-07-24 19:17:43 +0900332TEST_P(AidlTest, RejectOutParametersForIBinder) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700333 const string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
334 const string expected_ibinder_stderr =
Jooyung Han15fd6c62020-10-23 13:54:46 +0900335 "ERROR: a/IBaz.aidl:1.47-51: 'bar' can't be an out parameter because IBinder can only be an "
336 "in parameter.\n";
Devin Moore097a3ab2020-03-11 16:08:44 -0700337 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700338 EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700339 EXPECT_EQ(expected_ibinder_stderr, GetCapturedStderr());
Jeongik Chaa2080bf2019-06-18 16:44:29 +0900340}
341
Jiyong Park40782d02020-07-24 19:17:43 +0900342TEST_P(AidlTest, RejectsOutParametersInOnewayInterface) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700343 const string oneway_interface = "package a; oneway interface IBar { void f(out int bar); }";
344 const string expected_stderr =
345 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700346 CaptureStderr();
347 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
348 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park40782d02020-07-24 19:17:43 +0900349}
Devin Moore7b8d5c92020-03-17 14:14:08 -0700350
Jiyong Park40782d02020-07-24 19:17:43 +0900351TEST_P(AidlTest, RejectsOutParametersInOnewayMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700352 const string oneway_method = "package a; interface IBar { oneway void f(out int bar); }";
Jiyong Park40782d02020-07-24 19:17:43 +0900353 const string expected_stderr =
354 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
Devin Moore097a3ab2020-03-11 16:08:44 -0700355 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700356 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700357 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley90be4e32015-10-20 14:55:25 -0700358}
359
Devin Moore7b8d5c92020-03-17 14:14:08 -0700360TEST_P(AidlTest, RejectsOnewayNonVoidReturn) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700361 const string oneway_method = "package a; interface IFoo { oneway int f(); }";
362 const string expected_stderr =
363 "ERROR: a/IFoo.aidl:1.39-41: oneway method 'f' cannot return a value\n";
364 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700365 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700366 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley90be4e32015-10-20 14:55:25 -0700367}
368
Devin Moore7b8d5c92020-03-17 14:14:08 -0700369TEST_P(AidlTest, RejectsNullablePrimitive) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700370 const string oneway_method = "package a; interface IFoo { @nullable int f(); }";
371 const string expected_stderr =
372 "ERROR: a/IFoo.aidl:1.38-42: Primitive type cannot get nullable annotation\n";
373 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700374 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700375 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Casey Dahlin57dbe242015-12-04 11:44:02 -0800376}
377
Devin Moore2f2077a2020-08-28 11:27:53 -0700378TEST_P(AidlTest, AcceptNullableList) {
379 const string oneway_method = "package a; interface IFoo { @nullable List<String> f(); }";
380 const string expected_stderr = "";
381 CaptureStderr();
382 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
383 EXPECT_EQ(expected_stderr, GetCapturedStderr());
384}
385
Devin Moore7b8d5c92020-03-17 14:14:08 -0700386TEST_P(AidlTest, RejectsDuplicatedArgumentNames) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700387 const string method = "package a; interface IFoo { void f(int a, int a); }";
388 const string expected_stderr =
389 "ERROR: a/IFoo.aidl:1.33-35: method 'f' has duplicate argument name 'a'\n";
390 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700391 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700392 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelandb3cd3c72018-10-11 12:37:45 -0700393}
394
Jeongik Cha13066da2020-08-06 15:43:19 +0900395TEST_P(AidlTest, RejectsDuplicatedFieldNames) {
396 const string method = "package a; parcelable Foo { int a; String a; }";
Jooyung Han59af9cc2020-10-25 21:44:14 +0900397 const string expected_stderr = "ERROR: a/Foo.aidl:1.42-44: 'Foo' has duplicate field name 'a'\n";
Jeongik Cha13066da2020-08-06 15:43:19 +0900398 CaptureStderr();
399 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
400 EXPECT_EQ(expected_stderr, GetCapturedStderr());
401}
402
Jooyung Hand902a972020-10-23 17:32:44 +0900403TEST_P(AidlTest, RejectsRepeatedAnnotations) {
404 const string method = R"(@Hide @Hide parcelable Foo {})";
405 const string expected_stderr =
406 "ERROR: Foo.aidl:1.23-27: 'Hide' is repeated, but not allowed. Previous location: "
407 "Foo.aidl:1.1-6\n";
408 CaptureStderr();
409 EXPECT_EQ(nullptr, Parse("Foo.aidl", method, typenames_, GetLanguage()));
410 EXPECT_EQ(expected_stderr, GetCapturedStderr());
411}
412
Devin Moore7b8d5c92020-03-17 14:14:08 -0700413TEST_P(AidlTest, RejectsDuplicatedAnnotationParams) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700414 const string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
415 const string expected_stderr = "ERROR: a/IFoo.aidl:1.56-62: Trying to redefine parameter foo.\n";
416 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700417 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700418 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Andrei Onea9445fc62019-06-27 18:11:59 +0100419}
420
Devin Moore7b8d5c92020-03-17 14:14:08 -0700421TEST_P(AidlTest, RejectUnsupportedInterfaceAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700422 AidlError error;
423 const string method = "package a; @nullable interface IFoo { int f(); }";
Devin Moorec054bf82020-03-10 16:31:48 -0700424 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700425 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900426 EXPECT_THAT(GetCapturedStderr(), HasSubstr("'nullable' is not a supported annotation"));
Devin Moorec054bf82020-03-10 16:31:48 -0700427 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800428}
429
Devin Moore7b8d5c92020-03-17 14:14:08 -0700430TEST_P(AidlTest, RejectUnsupportedTypeAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700431 AidlError error;
432 const string method = "package a; interface IFoo { @JavaOnlyStableParcelable int f(); }";
Devin Moorec054bf82020-03-10 16:31:48 -0700433 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700434 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900435 EXPECT_THAT(GetCapturedStderr(),
436 HasSubstr("'JavaOnlyStableParcelable' is not a supported annotation"));
Devin Moorec054bf82020-03-10 16:31:48 -0700437 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800438}
439
Devin Moore7b8d5c92020-03-17 14:14:08 -0700440TEST_P(AidlTest, RejectUnsupportedParcelableAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700441 AidlError error;
442 const string method = "package a; @nullable parcelable IFoo cpp_header \"IFoo.h\";";
Devin Moorec054bf82020-03-10 16:31:48 -0700443 CaptureStderr();
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000444 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900445 EXPECT_THAT(GetCapturedStderr(), HasSubstr("'nullable' is not a supported annotation"));
Devin Moorec054bf82020-03-10 16:31:48 -0700446 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800447}
448
Devin Moore7b8d5c92020-03-17 14:14:08 -0700449TEST_P(AidlTest, RejectUnsupportedParcelableDefineAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700450 AidlError error;
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000451 const string method = "package a; @nullable parcelable IFoo { String a; String b; }";
Devin Moorec054bf82020-03-10 16:31:48 -0700452 CaptureStderr();
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000453 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900454 EXPECT_THAT(GetCapturedStderr(), HasSubstr("'nullable' is not a supported annotation"));
Devin Moorec054bf82020-03-10 16:31:48 -0700455 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800456}
457
Jiyong Park40782d02020-07-24 19:17:43 +0900458TEST_P(AidlTest, ParsesNonNullableAnnotation) {
459 auto parse_result =
460 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
461 ASSERT_NE(nullptr, parse_result);
462 const AidlInterface* interface = parse_result->AsInterface();
463 ASSERT_NE(nullptr, interface);
464 ASSERT_FALSE(interface->GetMethods().empty());
465 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsNullable());
466}
467
Devin Moore7b8d5c92020-03-17 14:14:08 -0700468TEST_P(AidlTest, ParsesNullableAnnotation) {
Jiyong Park40782d02020-07-24 19:17:43 +0900469 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @nullable String f(); }",
470 typenames_, GetLanguage());
471 ASSERT_NE(nullptr, parse_result);
472 const AidlInterface* interface = parse_result->AsInterface();
473 ASSERT_NE(nullptr, interface);
474 ASSERT_FALSE(interface->GetMethods().empty());
475 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsNullable());
476}
477
478TEST_P(AidlTest, ParsesNonUtf8Annotations) {
479 auto parse_result =
480 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
481 ASSERT_NE(nullptr, parse_result);
482 const AidlInterface* interface = parse_result->AsInterface();
483 ASSERT_NE(nullptr, interface);
484 ASSERT_FALSE(interface->GetMethods().empty());
485 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
Christopher Wileyec31a052016-01-25 07:28:51 -0800486}
487
Devin Moore7b8d5c92020-03-17 14:14:08 -0700488TEST_P(AidlTest, ParsesUtf8Annotations) {
Jiyong Park40782d02020-07-24 19:17:43 +0900489 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @utf8InCpp String f(); }",
490 typenames_, GetLanguage());
491 ASSERT_NE(nullptr, parse_result);
492 const AidlInterface* interface = parse_result->AsInterface();
493 ASSERT_NE(nullptr, interface);
494 ASSERT_FALSE(interface->GetMethods().empty());
495 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
Christopher Wileyec31a052016-01-25 07:28:51 -0800496}
497
Devin Moore7b8d5c92020-03-17 14:14:08 -0700498TEST_P(AidlTest, VintfRequiresStructuredAndStability) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700499 AidlError error;
Devin Moore0d0e3f62020-03-30 17:45:39 -0700500 const string expected_stderr =
501 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
502 "\"vintf\"'\n"
503 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
504 "--structured\n";
505 CaptureStderr();
Devin Moore097a3ab2020-03-11 16:08:44 -0700506 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
Devin Moore7b8d5c92020-03-17 14:14:08 -0700507 GetLanguage(), &error));
Devin Moore0d0e3f62020-03-30 17:45:39 -0700508 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700509 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700510}
511
Devin Moore7b8d5c92020-03-17 14:14:08 -0700512TEST_P(AidlTest, VintfRequiresStructured) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700513 AidlError error;
Devin Moore0d0e3f62020-03-30 17:45:39 -0700514 const string expected_stderr =
515 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
516 "--structured\n";
517 CaptureStderr();
Devin Moore097a3ab2020-03-11 16:08:44 -0700518 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
Devin Moore7b8d5c92020-03-17 14:14:08 -0700519 GetLanguage(), &error, {"--stability", "vintf"}));
Devin Moore0d0e3f62020-03-30 17:45:39 -0700520 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700521 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700522}
523
Devin Moore7b8d5c92020-03-17 14:14:08 -0700524TEST_P(AidlTest, VintfRequiresSpecifiedStability) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700525 AidlError error;
Devin Moore097a3ab2020-03-11 16:08:44 -0700526 const string expected_stderr =
527 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
528 "\"vintf\"'\n";
529 CaptureStderr();
530 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
Devin Moore7b8d5c92020-03-17 14:14:08 -0700531 GetLanguage(), &error, {"--structured"}));
Devin Moore097a3ab2020-03-11 16:08:44 -0700532 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700533 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700534}
535
Devin Moore7b8d5c92020-03-17 14:14:08 -0700536TEST_P(AidlTest, ParsesStabilityAnnotations) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700537 AidlError error;
Devin Moore7b8d5c92020-03-17 14:14:08 -0700538 auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
539 GetLanguage(), &error, {"--structured", "--stability", "vintf"});
Steven Morelanda57d0a62019-07-30 09:41:14 -0700540 ASSERT_EQ(AidlError::OK, error);
541 ASSERT_NE(nullptr, parse_result);
542 const AidlInterface* interface = parse_result->AsInterface();
543 ASSERT_NE(nullptr, interface);
544 ASSERT_TRUE(interface->IsVintfStability());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700545}
546
Jeongik Cha64783ed2019-06-07 18:30:54 +0900547TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
548 Options java_options = Options::From("aidl -o out --structured a/Foo.aidl");
Jeongik Cha88f95a82020-01-15 13:02:16 +0900549 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out/include a/Foo.aidl");
550 Options cpp_structured_options =
Jeongik Cha64783ed2019-06-07 18:30:54 +0900551 Options::From("aidl --lang=cpp --structured -o out -h out/include a/Foo.aidl");
Andrei Homescub62afd92020-05-11 19:24:59 -0700552 Options rust_options = Options::From("aidl --lang=rust -o out --structured a/Foo.aidl");
Jeongik Cha64783ed2019-06-07 18:30:54 +0900553 io_delegate_.SetFileContents(
Jeongik Cha88f95a82020-01-15 13:02:16 +0900554 "a/Foo.aidl",
555 StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
Jeongik Cha64783ed2019-06-07 18:30:54 +0900556
557 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
Jeongik Cha88f95a82020-01-15 13:02:16 +0900558 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -0700559 const string expected_stderr =
Jeongik Cha88f95a82020-01-15 13:02:16 +0900560 "ERROR: a/Foo.aidl:1.48-52: Cannot declared parcelable in a --structured interface. "
Devin Moorec054bf82020-03-10 16:31:48 -0700561 "Parcelable must be defined in AIDL directly.\n";
562 CaptureStderr();
Jeongik Cha88f95a82020-01-15 13:02:16 +0900563 EXPECT_NE(0, ::android::aidl::compile_aidl(cpp_structured_options, io_delegate_));
Devin Moorec054bf82020-03-10 16:31:48 -0700564 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Andrei Homescub62afd92020-05-11 19:24:59 -0700565
566 CaptureStderr();
567 EXPECT_NE(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
568 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jeongik Cha64783ed2019-06-07 18:30:54 +0900569}
570
Jooyung Han1cbc4962020-10-25 10:07:15 +0900571TEST_F(AidlTest, ParcelableSupportJavaDeriveToString) {
572 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
573 @JavaDerive(toString=true) parcelable Foo { int a; float b; })");
574 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
Jiyong Park43113fb2020-07-20 16:26:19 +0900575 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
576
577 string java_out;
Jooyung Han1cbc4962020-10-25 10:07:15 +0900578 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
Jiyong Park43113fb2020-07-20 16:26:19 +0900579 EXPECT_THAT(java_out, testing::HasSubstr("public String toString() {"));
580
581 // Other backends shouldn't be bothered
Jooyung Han1cbc4962020-10-25 10:07:15 +0900582 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
Jiyong Park43113fb2020-07-20 16:26:19 +0900583 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
584
Jooyung Han1cbc4962020-10-25 10:07:15 +0900585 Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
Jiyong Park43113fb2020-07-20 16:26:19 +0900586 EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
587}
588
Jooyung Han1cbc4962020-10-25 10:07:15 +0900589TEST_F(AidlTest, UnionSupportJavaDeriveToString) {
590 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
591 @JavaDerive(toString=true) union Foo { int a; int[] b; })");
592 CaptureStderr();
593 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
594 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
595 EXPECT_EQ("", GetCapturedStderr());
596
597 const string expected_to_string_method = R"--(
598 @Override
599 public String toString() {
600 switch (_tag) {
601 case a: return "a.Foo.a(" + (getA()) + ")";
602 case b: return "a.Foo.b(" + (java.util.Arrays.toString(getB())) + ")";
603 }
604 throw new IllegalStateException("unknown field: " + _tag);
605 }
606)--";
607
608 string java_out;
609 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
610 EXPECT_THAT(java_out, testing::HasSubstr(expected_to_string_method));
611}
612
Jiyong Park9aa3d042020-12-04 23:30:02 +0900613TEST_F(AidlTest, ParcelableSupportJavaDeriveEquals) {
614 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
615 @JavaDerive(equals=true) parcelable Foo { int a; float b; })");
616 CaptureStderr();
617 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
618 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
619 EXPECT_EQ("", GetCapturedStderr());
620
621 const std::string expected = R"--(
622 @Override
623 public boolean equals(Object other) {
624 if (this == other) return true;
625 if (other == null) return false;
626 if (!(other instanceof Foo)) return false;
627 Foo that = (Foo)other;
628 if (!java.util.Objects.deepEquals(a, that.a)) return false;
629 if (!java.util.Objects.deepEquals(b, that.b)) return false;
630 return true;
631 }
632
633 @Override
634 public int hashCode() {
635 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(a, b).toArray());
636 }
637)--";
638
639 string java_out;
640 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
641 EXPECT_THAT(java_out, testing::HasSubstr(expected));
642}
643
644TEST_F(AidlTest, UnionSupportJavaDeriveEquals) {
645 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
646 @JavaDerive(equals=true) union Foo { int a; int[] b; })");
647 CaptureStderr();
648 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
649 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
650 EXPECT_EQ("", GetCapturedStderr());
651
652 const std::string expected = R"--(
653 @Override
654 public boolean equals(Object other) {
655 if (this == other) return true;
656 if (other == null) return false;
657 if (!(other instanceof Foo)) return false;
658 Foo that = (Foo)other;
659 if (_tag != that._tag) return false;
660 if (!java.util.Objects.deepEquals(_value, that._value)) return false;
661 return true;
662 }
663
664 @Override
665 public int hashCode() {
666 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(_tag, _value).toArray());
667 }
668)--";
669
670 string java_out;
671 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
672 EXPECT_THAT(java_out, testing::HasSubstr(expected));
673}
674
Jooyung Han90345002020-10-23 15:28:53 +0900675TEST_F(AidlTest, RejectsJavaDeriveAnnotation) {
Jiyong Park43113fb2020-07-20 16:26:19 +0900676 {
Jooyung Han90345002020-10-23 15:28:53 +0900677 io_delegate_.SetFileContents("a/Foo.aidl",
678 "package a; @JavaDerive(blah=true) parcelable Foo{}");
679 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
680 CaptureStderr();
681 EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
682 const std::string expected_stderr =
683 "ERROR: a/Foo.aidl:1.11-34: Parameter blah not supported for annotation JavaDerive.";
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900684 EXPECT_THAT(GetCapturedStderr(),
685 HasSubstr("Parameter blah not supported for annotation JavaDerive."));
Jooyung Han90345002020-10-23 15:28:53 +0900686 }
687
688 {
689 io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive interface IFoo{}");
Jiyong Park43113fb2020-07-20 16:26:19 +0900690 Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
691 CaptureStderr();
692 EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900693 EXPECT_THAT(GetCapturedStderr(), HasSubstr("'JavaDerive' is not a supported annotation"));
Jiyong Park43113fb2020-07-20 16:26:19 +0900694 }
695
696 {
Jooyung Han90345002020-10-23 15:28:53 +0900697 io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive enum IFoo { A=1, }");
Jiyong Park43113fb2020-07-20 16:26:19 +0900698 Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
699 CaptureStderr();
700 EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900701 EXPECT_THAT(GetCapturedStderr(), HasSubstr("'JavaDerive' is not a supported annotation"));
Jiyong Park43113fb2020-07-20 16:26:19 +0900702 }
703}
704
Jiyong Park27fd7fd2020-08-27 16:25:09 +0900705TEST_P(AidlTest, ParseDescriptorAnnotation) {
706 AidlError error;
707 auto parse_result = Parse("IFoo.aidl", R"(@Descriptor(value="IBar") interface IFoo{})",
708 typenames_, GetLanguage(), &error, {"--structured"});
709 ASSERT_EQ(AidlError::OK, error);
710 ASSERT_NE(nullptr, parse_result);
711 const AidlInterface* interface = parse_result->AsInterface();
712 ASSERT_NE(nullptr, interface);
713 ASSERT_EQ("IBar", interface->GetDescriptor());
714}
715
Jiyong Park40782d02020-07-24 19:17:43 +0900716TEST_P(AidlTest, AcceptsOnewayMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700717 const string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700718 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Jiyong Park40782d02020-07-24 19:17:43 +0900719}
720
721TEST_P(AidlTest, AcceptsOnewayInterface) {
722 const string oneway_interface = "package a; oneway interface IBar { void f(int a); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700723 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700724}
Christopher Wileyef140932015-11-03 09:29:19 -0800725
Devin Moore7b8d5c92020-03-17 14:14:08 -0700726TEST_P(AidlTest, AcceptsAnnotatedOnewayMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700727 const string oneway_method =
728 "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700729 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Artur Satayev91fe8712019-07-29 13:06:01 +0100730}
731
Steven Moreland65297cc2020-04-20 20:17:36 -0700732TEST_P(AidlTest, AnnotationsInMultiplePlaces) {
733 const string oneway_method =
734 "package a; interface IFoo { @UnsupportedAppUsage oneway @Hide void f(int a); }";
735 const AidlDefinedType* defined = Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage());
736 ASSERT_NE(nullptr, defined);
737 const AidlInterface* iface = defined->AsInterface();
738 ASSERT_NE(nullptr, iface);
739
740 const auto& methods = iface->GetMethods();
741 ASSERT_EQ(1u, methods.size());
742 const auto& method = methods[0];
743 const AidlTypeSpecifier& ret_type = method->GetType();
744
745 // TODO(b/151102494): these annotations should be on the method
746 ASSERT_NE(nullptr, ret_type.UnsupportedAppUsage());
747 ASSERT_TRUE(ret_type.IsHide());
748}
749
Devin Moore7b8d5c92020-03-17 14:14:08 -0700750TEST_P(AidlTest, WritesComments) {
Artur Satayev91fe8712019-07-29 13:06:01 +0100751 string foo_interface =
752 "package a; /* foo */ interface IFoo {"
753 " /* i */ int i();"
754 " /* j */ @nullable String j();"
755 " /* k */ @UnsupportedAppUsage oneway void k(int a); }";
756
Devin Moore7b8d5c92020-03-17 14:14:08 -0700757 auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, GetLanguage());
Artur Satayev91fe8712019-07-29 13:06:01 +0100758 EXPECT_NE(nullptr, parse_result);
759 EXPECT_EQ("/* foo */", parse_result->GetComments());
760
761 const AidlInterface* interface = parse_result->AsInterface();
762 EXPECT_EQ("/* i */", interface->GetMethods()[0]->GetComments());
763 EXPECT_EQ("/* j */", interface->GetMethods()[1]->GetComments());
764 EXPECT_EQ("/* k */", interface->GetMethods()[2]->GetComments());
765}
766
Jooyung Han1a551d32020-10-05 15:37:26 +0900767TEST_P(AidlTest, CppHeaderCanBeIdentifierAsWell) {
768 io_delegate_.SetFileContents("p/cpp_header.aidl",
769 R"(package p;
770 parcelable cpp_header cpp_header "bar/header";)");
771 import_paths_.emplace("");
772 const string input_path = "p/IFoo.aidl";
773 const string input = R"(package p;
774 import p.cpp_header;
775 interface IFoo {
776 // get bar
777 cpp_header get();
778 })";
779
780 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
781 EXPECT_NE(nullptr, parse_result);
782 const AidlInterface* interface = parse_result->AsInterface();
783 EXPECT_EQ("// get bar\n", interface->GetMethods()[0]->GetComments());
784}
785
Christopher Wileyef140932015-11-03 09:29:19 -0800786TEST_F(AidlTest, ParsesPreprocessedFile) {
787 string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
788 io_delegate_.SetFileContents("path", simple_content);
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700789 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900790 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700791 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
792 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
Christopher Wileyef140932015-11-03 09:29:19 -0800793}
794
795TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
796 string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
797 io_delegate_.SetFileContents("path", simple_content);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900798
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700799 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900800 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700801 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
802 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
Christopher Wileyef140932015-11-03 09:29:19 -0800803}
804
Devin Moore7b8d5c92020-03-17 14:14:08 -0700805TEST_P(AidlTest, PreferImportToPreprocessed) {
Christopher Wiley41544372015-11-03 14:52:29 -0800806 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
807 io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
808 "interface IBar {}");
809 preprocessed_files_.push_back("preprocessed");
Jiyong Park8c380532018-08-30 14:55:26 +0900810 import_paths_.emplace("");
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900811 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
Devin Moore7b8d5c92020-03-17 14:14:08 -0700812 typenames_, GetLanguage());
Christopher Wiley41544372015-11-03 14:52:29 -0800813 EXPECT_NE(nullptr, parse_result);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900814
Christopher Wiley41544372015-11-03 14:52:29 -0800815 // We expect to know about both kinds of IBar
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700816 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
817 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
Christopher Wiley41544372015-11-03 14:52:29 -0800818 // But if we request just "IBar" we should get our imported one.
Steven Moreland02e012e2018-08-02 14:58:10 -0700819 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, "");
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900820 ambiguous_type.Resolve(typenames_);
821 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
Christopher Wiley41544372015-11-03 14:52:29 -0800822}
823
Jiyong Park8f6ec462020-01-19 20:52:47 +0900824// Special case of PreferImportToPreprocessed. Imported type should be preferred
825// even when the preprocessed file already has the same type.
Devin Moore7b8d5c92020-03-17 14:14:08 -0700826TEST_P(AidlTest, B147918827) {
Jiyong Park8f6ec462020-01-19 20:52:47 +0900827 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;\ninterface one.IBar;");
828 io_delegate_.SetFileContents("one/IBar.aidl",
829 "package one; "
830 "interface IBar {}");
831 preprocessed_files_.push_back("preprocessed");
832 import_paths_.emplace("");
833 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
Devin Moore7b8d5c92020-03-17 14:14:08 -0700834 typenames_, GetLanguage());
Jiyong Park8f6ec462020-01-19 20:52:47 +0900835 EXPECT_NE(nullptr, parse_result);
836
837 // We expect to know about both kinds of IBar
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700838 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
839 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
Jiyong Park8f6ec462020-01-19 20:52:47 +0900840 // But if we request just "IBar" we should get our imported one.
841 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, "");
842 ambiguous_type.Resolve(typenames_);
843 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
844}
845
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800846TEST_F(AidlTest, WritePreprocessedFile) {
847 io_delegate_.SetFileContents("p/Outer.aidl",
848 "package p; parcelable Outer.Inner;");
849 io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
850 "interface IBar {}");
851
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900852 vector<string> args {
853 "aidl",
854 "--preprocess",
855 "preprocessed",
856 "p/Outer.aidl",
857 "one/IBar.aidl"};
858 Options options = Options::From(args);
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800859 EXPECT_TRUE(::android::aidl::preprocess_aidl(options, io_delegate_));
860
861 string output;
862 EXPECT_TRUE(io_delegate_.GetWrittenContents("preprocessed", &output));
863 EXPECT_EQ("parcelable p.Outer.Inner;\ninterface one.IBar;\n", output);
864}
865
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900866TEST_F(AidlTest, JavaParcelableOutput) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100867 io_delegate_.SetFileContents(
868 "Rect.aidl",
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800869 "@Hide\n"
Andrei Onea9445fc62019-06-27 18:11:59 +0100870 "parcelable Rect {\n"
871 " // Comment\n"
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800872 " @Hide\n"
Andrei Onea9445fc62019-06-27 18:11:59 +0100873 " int x=5;\n"
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800874 " @Hide\n"
Andrei Onea9445fc62019-06-27 18:11:59 +0100875 " @UnsupportedAppUsage(maxTargetSdk = 28, trackingBug = 42, implicitMember = \"dummy\", "
Andrei Onea07fa3e02019-07-04 17:55:19 +0100876 "expectedSignature = \"dummy\", publicAlternatives = \"d\" \n + \"u\" + \n \"m\" \n + \"m\" "
877 "+ \"y\")\n"
Andrei Onea9445fc62019-06-27 18:11:59 +0100878 " int y;\n"
Jiyong Parkd4e73c82019-07-24 21:39:15 +0900879 " ParcelFileDescriptor fd;\n"
Jooyung Hand2fa0232020-10-19 02:51:41 +0900880 " List<ParcelFileDescriptor> fds;\n"
Andrei Onea9445fc62019-06-27 18:11:59 +0100881 "}");
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900882
883 vector<string> args{"aidl", "Rect.aidl"};
884 Options options = Options::From(args);
885 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
886
887 string output;
888 EXPECT_TRUE(io_delegate_.GetWrittenContents("Rect.java", &output));
Jooyung Hand2fa0232020-10-19 02:51:41 +0900889 EXPECT_EQ(kExpectedJavaParcelableOutputContents, output);
Jeongik Chaa755c2a2018-12-12 16:28:23 +0900890}
891
Devin Moore2f2077a2020-08-28 11:27:53 -0700892TEST_F(AidlTest, CppHeaderIncludes) {
893 io_delegate_.SetFileContents("IFoo.aidl",
894 "interface IFoo {\n"
895 " @nullable List<String> foo();\n"
896 "}");
897
898 vector<string> args{"aidl", "--lang=cpp", "IFoo.aidl"};
899 Options options = Options::From(args);
900 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
901 std::vector<std::string> empty;
902 EXPECT_EQ(empty, io_delegate_.ListFiles(""));
903 EXPECT_EQ(empty, io_delegate_.ListFiles("/"));
904 EXPECT_EQ(empty, io_delegate_.ListFiles("out"));
905
906 // Make sure the optional and String16.h includes are added
907 string output;
908 EXPECT_TRUE(io_delegate_.GetWrittenContents("IFoo.h", &output));
909 EXPECT_EQ(kExpectedCppHeaderOutput, output);
910}
911
Jooyung Han720253d2021-01-05 19:13:17 +0900912TEST_P(AidlTest, SupportDeprecated) {
913 struct TestCase {
914 std::string output_file;
915 std::string annotation;
916 };
917
918 auto CheckDeprecated = [&](const std::string& filename, const std::string& contents,
919 std::map<Options::Language, TestCase> expectation) {
920 io_delegate_.SetFileContents(filename, contents);
921
922 auto options = Options::From("aidl --lang=" + to_string(GetLanguage()) + " " + filename +
923 " --out=out --header_out=out");
924 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
925 if (auto it = expectation.find(GetLanguage()); it != expectation.end()) {
926 const auto& test_case = it->second;
927 string output;
928 EXPECT_TRUE(io_delegate_.GetWrittenContents(test_case.output_file, &output))
929 << base::Join(io_delegate_.ListOutputFiles(), ",");
930 EXPECT_THAT(output, HasSubstr(test_case.annotation));
931 }
932 };
933
934 CheckDeprecated("IFoo.aidl",
935 "interface IFoo {\n"
936 " /** @deprecated use bar() */\n"
937 " List<String> foo();\n"
938 "}",
939 {
940 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
941 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
942 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
943 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
944 });
945
946 CheckDeprecated("Foo.aidl",
947 "parcelable Foo {\n"
948 " /** @deprecated use bar*/\n"
949 " int foo = 0;\n"
950 "}",
951 {
952 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
953 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
954 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
955 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
956 });
957
958 CheckDeprecated("IFoo.aidl",
959 "interface IFoo {\n"
960 " /** @deprecated use bar*/\n"
961 " const int FOO = 0;\n"
962 "}",
963 {
964 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
965 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
966 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
967 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
968 });
969
970 // union fields
971 CheckDeprecated("Foo.aidl",
972 "union Foo {\n"
973 " int bar = 0;\n"
974 " /** @deprecated use bar*/\n"
975 " int foo;\n"
976 "}",
977 {
978 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
979 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
980 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
981 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
982 });
983
984 CheckDeprecated("Foo.aidl",
985 "/** @deprecated use Bar */\n"
986 "parcelable Foo {}",
987 {
988 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
989 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
990 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
991 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
992 });
993
994 CheckDeprecated("Foo.aidl",
995 "/** @deprecated use Bar */\n"
996 "union Foo { int foo = 0; }",
997 {
998 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
999 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1000 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1001 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1002 });
1003
1004 CheckDeprecated("IFoo.aidl",
1005 "/** @deprecated use IBar */\n"
1006 "interface IFoo {}",
1007 {
1008 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1009 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1010 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1011 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1012 });
1013
1014 CheckDeprecated("Foo.aidl",
1015 "/** @deprecated use IBar */\n"
1016 "enum Foo { FOO }",
1017 {
1018 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1019 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1020 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1021 // TODO(b/174514415) support "deprecated"
1022 // {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1023 });
1024}
1025
Devin Moore7b8d5c92020-03-17 14:14:08 -07001026TEST_P(AidlTest, RequireOuterClass) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001027 const string expected_stderr = "ERROR: p/IFoo.aidl:1.54-60: Failed to resolve 'Inner'\n";
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001028 io_delegate_.SetFileContents("p/Outer.aidl",
1029 "package p; parcelable Outer.Inner;");
Jiyong Park8c380532018-08-30 14:55:26 +09001030 import_paths_.emplace("");
Devin Moore097a3ab2020-03-11 16:08:44 -07001031 CaptureStderr();
1032 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1033 "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001034 typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -07001035 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001036}
1037
Devin Moore7b8d5c92020-03-17 14:14:08 -07001038TEST_P(AidlTest, ParseCompoundParcelableFromPreprocess) {
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001039 io_delegate_.SetFileContents("preprocessed",
1040 "parcelable p.Outer.Inner;");
1041 preprocessed_files_.push_back("preprocessed");
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001042 auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001043 typenames_, GetLanguage());
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001044 // TODO(wiley): This should actually return nullptr because we require
1045 // the outer class name. However, for legacy reasons,
1046 // this behavior must be maintained. b/17415692
1047 EXPECT_NE(nullptr, parse_result);
1048}
1049
Christopher Wiley632801d2015-11-05 14:15:49 -08001050TEST_F(AidlTest, FailOnParcelable) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001051 const string expected_foo_stderr =
1052 "ERROR: p/IFoo.aidl:1.22-27: Refusing to generate code with unstructured parcelables. "
1053 "Declared parcelables should be in their own file and/or cannot be used with --structured "
1054 "interfaces.\n";
Steven Morelande2c64b42018-09-18 15:06:37 -07001055 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; parcelable IFoo;");
1056
Christopher Wiley632801d2015-11-05 14:15:49 -08001057 // By default, we shouldn't fail on parcelable.
Steven Morelande2c64b42018-09-18 15:06:37 -07001058 Options options1 = Options::From("aidl p/IFoo.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001059 CaptureStderr();
Jiyong Parkb034bf02018-07-30 17:44:33 +09001060 EXPECT_EQ(0, ::android::aidl::compile_aidl(options1, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001061 EXPECT_EQ("", GetCapturedStderr());
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001062
Steven Morelande2c64b42018-09-18 15:06:37 -07001063 // -b considers this an error
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001064 Options options2 = Options::From("aidl -b p/IFoo.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001065 CaptureStderr();
Jiyong Parkb034bf02018-07-30 17:44:33 +09001066 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001067 EXPECT_EQ(expected_foo_stderr, GetCapturedStderr());
Steven Morelande2c64b42018-09-18 15:06:37 -07001068
Devin Moore097a3ab2020-03-11 16:08:44 -07001069 const string expected_bar_stderr =
1070 "ERROR: p/IBar.aidl:1.22-26: Refusing to generate code with unstructured parcelables. "
1071 "Declared parcelables should be in their own file and/or cannot be used with --structured "
1072 "interfaces.\n";
Steven Morelande2c64b42018-09-18 15:06:37 -07001073 io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
1074
Jiyong Parkda8c6932019-08-12 19:56:08 +09001075 // With '-b' option, a parcelable and an interface should fail.
Steven Morelande2c64b42018-09-18 15:06:37 -07001076 Options options3 = Options::From("aidl p/IBar.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001077 CaptureStderr();
Jiyong Parkda8c6932019-08-12 19:56:08 +09001078 EXPECT_EQ(0, ::android::aidl::compile_aidl(options3, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001079 EXPECT_EQ("", GetCapturedStderr());
Steven Morelande2c64b42018-09-18 15:06:37 -07001080 Options options4 = Options::From("aidl -b p/IBar.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001081 CaptureStderr();
Steven Morelande2c64b42018-09-18 15:06:37 -07001082 EXPECT_NE(0, ::android::aidl::compile_aidl(options4, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001083 EXPECT_EQ(expected_bar_stderr, GetCapturedStderr());
Christopher Wiley632801d2015-11-05 14:15:49 -08001084}
1085
Devin Moore7b8d5c92020-03-17 14:14:08 -07001086TEST_P(AidlTest, StructuredFailOnUnstructuredParcelable) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001087 const string expected_stderr =
1088 "ERROR: ./o/WhoKnowsWhat.aidl:1.22-35: o.WhoKnowsWhat is not structured, but this is a "
1089 "structured interface.\n";
Steven Moreland1eac5fa2018-08-27 19:35:05 -07001090 io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl", "package o; parcelable WhoKnowsWhat;");
1091 import_paths_.emplace("");
Devin Moore097a3ab2020-03-11 16:08:44 -07001092 AidlError error;
1093 CaptureStderr();
1094 EXPECT_EQ(
1095 nullptr,
Steven Moreland1eac5fa2018-08-27 19:35:05 -07001096 Parse("p/IFoo.aidl",
1097 "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001098 typenames_, GetLanguage(), &error, {"--structured"}));
Devin Moore097a3ab2020-03-11 16:08:44 -07001099 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1100 EXPECT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Moreland1eac5fa2018-08-27 19:35:05 -07001101}
1102
Devin Moore7b8d5c92020-03-17 14:14:08 -07001103TEST_P(AidlTest, FailOnDuplicateConstantNames) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001104 AidlError error;
1105 const string expected_stderr =
1106 "ERROR: p/IFoo.aidl:4.34-45: Found duplicate constant name 'DUPLICATED'\n";
1107 CaptureStderr();
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001108 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1109 R"(package p;
Christopher Wiley69b44cf2016-05-03 13:43:33 -07001110 interface IFoo {
1111 const String DUPLICATED = "d";
1112 const int DUPLICATED = 1;
1113 }
1114 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001115 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07001116 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1117 EXPECT_EQ(AidlError::BAD_TYPE, error);
Christopher Wiley69b44cf2016-05-03 13:43:33 -07001118}
1119
Steven Morelande689da22020-11-10 02:06:30 +00001120TEST_P(AidlTest, FailOnTooBigConstant) {
1121 AidlError error;
1122 const string expected_stderr =
1123 "ERROR: p/IFoo.aidl:3.48-52: Invalid type specifier for an int32 literal: byte\n";
1124 CaptureStderr();
1125 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1126 R"(package p;
1127 interface IFoo {
1128 const byte type2small = 256;
1129 }
1130 )",
1131 typenames_, GetLanguage(), &error));
1132 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1133 EXPECT_EQ(AidlError::BAD_TYPE, error);
1134}
1135
Jooyung Han30f64ad2020-12-15 08:16:31 +09001136TEST_F(AidlTest, BoolConstantsEvaluatesToIntegers) {
1137 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { const int y = true; }");
1138 CaptureStderr();
1139 auto options = Options::From("aidl --lang java -o out a/Foo.aidl");
1140 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
1141 EXPECT_EQ("", GetCapturedStderr());
1142 string code;
1143 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
1144 EXPECT_THAT(code, testing::HasSubstr("public static final int y = 1;"));
1145}
1146
Jooyung Han535c5e82020-12-29 15:16:59 +09001147TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) {
Jooyung Han71a1b582020-12-25 23:58:41 +09001148 using Ptr = unique_ptr<AidlConstantValue>;
1149 const AidlLocation& loc = AIDL_LOCATION_HERE;
1150
Jooyung Han535c5e82020-12-29 15:16:59 +09001151 EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, 'c'))->EvaluatedValue<char>());
1152 EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>());
1153 EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>());
1154 EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>());
Jooyung Han71a1b582020-12-25 23:58:41 +09001155
1156 AidlBinaryConstExpression one_plus_one(loc, Ptr(AidlConstantValue::Integral(loc, "1")), "+",
1157 Ptr(AidlConstantValue::Integral(loc, "1")));
Jooyung Han535c5e82020-12-29 15:16:59 +09001158 EXPECT_EQ(2, one_plus_one.EvaluatedValue<int32_t>());
Jooyung Han71a1b582020-12-25 23:58:41 +09001159
1160 auto values = unique_ptr<vector<Ptr>>{new vector<Ptr>};
1161 values->emplace_back(AidlConstantValue::String(loc, "\"hello\""));
1162 values->emplace_back(AidlConstantValue::String(loc, "\"world\""));
1163 vector<string> expected{"hello", "world"};
Jooyung Han535c5e82020-12-29 15:16:59 +09001164 EXPECT_EQ(
1165 expected,
1166 Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>());
Jooyung Han71a1b582020-12-25 23:58:41 +09001167}
1168
Devin Moore7b8d5c92020-03-17 14:14:08 -07001169TEST_P(AidlTest, FailOnManyDefinedTypes) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001170 AidlError error;
Devin Moore5de18ed2020-04-02 13:52:29 -07001171 const string expected_stderr =
1172 "ERROR: p/IFoo.aidl:3.33-38: You must declare only one type per file.\n";
Devin Moorec054bf82020-03-10 16:31:48 -07001173 CaptureStderr();
Steven Morelandc258abc2018-07-10 14:03:38 -07001174 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1175 R"(package p;
1176 interface IFoo {}
Steven Morelandc258abc2018-07-10 14:03:38 -07001177 parcelable IBar {}
1178 parcelable StructuredParcelable {}
1179 interface IBaz {}
Jeongik Cha2a5b4d82019-08-06 19:37:59 +09001180 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001181 typenames_, GetLanguage(), &error));
Devin Moorec054bf82020-03-10 16:31:48 -07001182 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelandc258abc2018-07-10 14:03:38 -07001183 // Parse success is important for clear error handling even if the cases aren't
1184 // actually supported in code generation.
Devin Moore097a3ab2020-03-11 16:08:44 -07001185 EXPECT_EQ(AidlError::BAD_TYPE, error);
Steven Morelandc258abc2018-07-10 14:03:38 -07001186}
1187
Devin Moore7b8d5c92020-03-17 14:14:08 -07001188TEST_P(AidlTest, FailOnNoDefinedTypes) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001189 AidlError error;
1190 const string expected_stderr = "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected $end\n";
1191 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -07001192 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07001193 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1194 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Steven Morelandc258abc2018-07-10 14:03:38 -07001195}
1196
Steven Morelandf9e922f2020-07-08 21:15:27 +00001197TEST_P(AidlTest, FailOnEmptyListWithComma) {
1198 AidlError error;
1199 const string expected_stderr =
1200 "ERROR: p/Foo.aidl:1.45-47: syntax error, unexpected ',', expecting '}'\n";
1201 CaptureStderr();
1202 EXPECT_EQ(nullptr, Parse("p/Foo.aidl", R"(package p; parcelable Foo { uint64_t[] a = { , }; })",
1203 typenames_, GetLanguage(), &error));
1204 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1205 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1206}
1207
Devin Moore7b8d5c92020-03-17 14:14:08 -07001208TEST_P(AidlTest, FailOnMalformedConstHexValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001209 AidlError error;
1210 const string expected_stderr =
Devin Moore2a088902020-09-17 10:51:19 -07001211 "ERROR: p/IFoo.aidl:3.50-71: Could not parse hexvalue: 0xffffffffffffffffff\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07001212 CaptureStderr();
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001213 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1214 R"(package p;
Roshan Pius3b2203d2016-07-22 16:13:20 -07001215 interface IFoo {
1216 const int BAD_HEX_VALUE = 0xffffffffffffffffff;
1217 }
1218 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001219 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07001220 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1221 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Roshan Pius3b2203d2016-07-22 16:13:20 -07001222}
1223
Jiyong Park18132182020-06-08 20:24:40 +09001224TEST_P(AidlTest, FailOnMalformedQualifiedNameAsIdentifier) {
1225 AidlError error;
1226 const string expected_stderr =
1227 "ERROR: p/IFoo.aidl:1.25-26: syntax error, unexpected ';', expecting identifier or "
1228 "cpp_header (which can also be used as an identifier)\n";
1229 CaptureStderr();
1230 // Notice the trailing dot(.) in the name, which isn't a correct name
1231 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p; parcelable A.; )", typenames_,
1232 GetLanguage(), &error));
1233 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1234 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1235}
1236
1237TEST_P(AidlTest, FailOnMalformedQualifiedNameAsPackage) {
1238 AidlError error;
1239 const string expected_stderr =
1240 "ERROR: p/IFoo.aidl:1.11-12: syntax error, unexpected ';', expecting identifier or "
1241 "cpp_header (which can also be used as an identifier)\n";
1242 CaptureStderr();
1243 // Notice the trailing dot(.) in the package name
1244 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p.; parcelable A; )", typenames_,
1245 GetLanguage(), &error));
1246 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1247 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1248}
1249
Devin Moore7b8d5c92020-03-17 14:14:08 -07001250TEST_P(AidlTest, ParsePositiveConstHexValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001251 AidlError error;
Devin Moore7b8d5c92020-03-17 14:14:08 -07001252 auto parse_result = Parse("p/IFoo.aidl",
1253 R"(package p;
Roshan Pius3b2203d2016-07-22 16:13:20 -07001254 interface IFoo {
1255 const int POSITIVE_HEX_VALUE = 0xf5;
1256 }
1257 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001258 typenames_, GetLanguage(), &error);
1259 EXPECT_NE(nullptr, parse_result);
1260 const AidlInterface* interface = parse_result->AsInterface();
Steven Moreland5557f1c2018-07-02 13:50:23 -07001261 ASSERT_NE(nullptr, interface);
Steven Moreland693640b2018-07-19 13:46:27 -07001262 const auto& cpp_constants = interface->GetConstantDeclarations();
1263 EXPECT_EQ((size_t)1, cpp_constants.size());
1264 EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
Will McVickerd7d18df2019-09-12 13:40:50 -07001265 EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
Steven Moreland860b1942018-08-16 14:59:28 -07001266 EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
Roshan Pius3b2203d2016-07-22 16:13:20 -07001267}
1268
Devin Moore7b8d5c92020-03-17 14:14:08 -07001269TEST_P(AidlTest, ParseNegativeConstHexValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001270 AidlError error;
Devin Moore7b8d5c92020-03-17 14:14:08 -07001271 auto parse_result = Parse("p/IFoo.aidl",
1272 R"(package p;
Roshan Pius3b2203d2016-07-22 16:13:20 -07001273 interface IFoo {
1274 const int NEGATIVE_HEX_VALUE = 0xffffffff;
1275 }
1276 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001277 typenames_, GetLanguage(), &error);
1278 ASSERT_NE(nullptr, parse_result);
1279 const AidlInterface* interface = parse_result->AsInterface();
Steven Moreland5557f1c2018-07-02 13:50:23 -07001280 ASSERT_NE(nullptr, interface);
Steven Moreland693640b2018-07-19 13:46:27 -07001281 const auto& cpp_constants = interface->GetConstantDeclarations();
1282 EXPECT_EQ((size_t)1, cpp_constants.size());
1283 EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
Will McVickerd7d18df2019-09-12 13:40:50 -07001284 EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
Steven Moreland860b1942018-08-16 14:59:28 -07001285 EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
Roshan Pius3b2203d2016-07-22 16:13:20 -07001286}
1287
Devin Moore7b8d5c92020-03-17 14:14:08 -07001288TEST_P(AidlTest, UnderstandsNestedParcelables) {
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001289 io_delegate_.SetFileContents(
1290 "p/Outer.aidl",
1291 "package p; parcelable Outer.Inner cpp_header \"baz/header\";");
Jiyong Park8c380532018-08-30 14:55:26 +09001292 import_paths_.emplace("");
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001293 const string input_path = "p/IFoo.aidl";
1294 const string input = "package p; import p.Outer; interface IFoo"
1295 " { Outer.Inner get(); }";
1296
Devin Moore7b8d5c92020-03-17 14:14:08 -07001297 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1298 EXPECT_NE(nullptr, parse_result);
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001299
Steven Morelandcb1bcd72020-04-29 16:30:35 -07001300 EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001301 // C++ uses "::" instead of "." to refer to a inner class.
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001302 AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", false, nullptr, "");
1303 EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001304}
1305
Devin Moore7b8d5c92020-03-17 14:14:08 -07001306TEST_P(AidlTest, UnderstandsNativeParcelables) {
Christopher Wiley9078d722015-11-17 10:23:49 -08001307 io_delegate_.SetFileContents(
1308 "p/Bar.aidl",
Casey Dahlincd639212015-12-15 12:51:04 -08001309 "package p; parcelable Bar cpp_header \"baz/header\";");
Jiyong Park8c380532018-08-30 14:55:26 +09001310 import_paths_.emplace("");
Christopher Wiley9078d722015-11-17 10:23:49 -08001311 const string input_path = "p/IFoo.aidl";
1312 const string input = "package p; import p.Bar; interface IFoo { }";
Devin Moore7b8d5c92020-03-17 14:14:08 -07001313 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1314 EXPECT_NE(nullptr, parse_result);
Steven Morelandcb1bcd72020-04-29 16:30:35 -07001315 EXPECT_TRUE(typenames_.ResolveTypename("p.Bar").is_resolved);
Devin Moore7b8d5c92020-03-17 14:14:08 -07001316 AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, "");
1317 native_type.Resolve(typenames_);
1318
1319 EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type, typenames_));
1320 // C++ understands C++ specific stuff
1321 EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
1322 set<string> headers;
Devin Moore2f2077a2020-08-28 11:27:53 -07001323 cpp::AddHeaders(native_type, typenames_, &headers);
Devin Moore7b8d5c92020-03-17 14:14:08 -07001324 EXPECT_EQ(1u, headers.size());
1325 EXPECT_EQ(1u, headers.count("baz/header"));
Christopher Wiley9078d722015-11-17 10:23:49 -08001326}
1327
Christopher Wileyf8136192016-04-12 14:19:35 -07001328TEST_F(AidlTest, WritesCorrectDependencyFile) {
1329 // While the in tree build system always gives us an output file name,
1330 // other android tools take advantage of our ability to infer the intended
1331 // file name. This test makes sure we handle this correctly.
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001332 vector<string> args = {
1333 "aidl",
1334 "-d dep/file/path",
1335 "-o place/for/output",
1336 "p/IFoo.aidl"};
1337 Options options = Options::From(args);
1338 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
Jiyong Parkb034bf02018-07-30 17:44:33 +09001339 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Christopher Wileyf8136192016-04-12 14:19:35 -07001340 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001341 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Christopher Wileyf8136192016-04-12 14:19:35 -07001342 EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
1343}
1344
Dan Willemsen93298ee2016-11-10 23:55:55 -08001345TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
1346 // While the in tree build system always gives us an output file name,
1347 // other android tools take advantage of our ability to infer the intended
1348 // file name. This test makes sure we handle this correctly.
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001349 vector<string> args = {
1350 "aidl",
1351 "-d dep/file/path",
1352 "--ninja",
1353 "-o place/for/output",
1354 "p/IFoo.aidl"};
1355 Options options = Options::From(args);
1356 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
Jiyong Parkb034bf02018-07-30 17:44:33 +09001357 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Dan Willemsen93298ee2016-11-10 23:55:55 -08001358 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001359 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Dan Willemsen93298ee2016-11-10 23:55:55 -08001360 EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
1361}
1362
Jiyong Parkdf202122019-09-30 20:48:35 +09001363TEST_F(AidlTest, WritesTrivialDependencyFileForParcelableDeclaration) {
Christopher Wileyb1bbdf82016-04-21 11:43:45 -07001364 // The SDK uses aidl to decide whether a .aidl file is a parcelable. It does
1365 // this by calling aidl with every .aidl file it finds, then parsing the
1366 // generated dependency files. Those that reference .java output files are
1367 // for interfaces and those that do not are parcelables. However, for both
1368 // parcelables and interfaces, we *must* generate a non-empty dependency file.
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001369 vector<string> args = {
1370 "aidl",
1371 "-o place/for/output",
1372 "-d dep/file/path",
1373 "p/Foo.aidl"};
1374 Options options = Options::From(args);
1375 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
Jiyong Parkb034bf02018-07-30 17:44:33 +09001376 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Christopher Wileyb1bbdf82016-04-21 11:43:45 -07001377 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001378 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Jiyong Parkdf202122019-09-30 20:48:35 +09001379 EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDeclarationDepFileContents);
1380}
1381
1382TEST_F(AidlTest, WritesDependencyFileForStructuredParcelable) {
1383 vector<string> args = {
1384 "aidl",
1385 "--structured",
1386 "-o place/for/output",
1387 "-d dep/file/path",
1388 "p/Foo.aidl"};
1389 Options options = Options::From(args);
1390 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo {int a;}");
1391 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1392 string actual_dep_file_contents;
1393 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1394 EXPECT_EQ(actual_dep_file_contents, kExpectedStructuredParcelableDepFileContents);
Christopher Wileyb1bbdf82016-04-21 11:43:45 -07001395}
1396
Jiyong Park9ca5c7e2019-10-17 15:01:14 +09001397TEST_F(AidlTest, NoJavaOutputForParcelableDeclaration) {
1398 vector<string> args = {
1399 "aidl",
1400 "--lang=java",
1401 "-o place/for/output",
1402 "p/Foo.aidl"};
1403 Options options = Options::From(args);
1404 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
1405 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1406 string output_file_contents;
1407 EXPECT_FALSE(io_delegate_.GetWrittenContents(options.OutputFile(), &output_file_contents));
1408}
1409
Devin Moore21b26772020-08-26 16:37:56 -07001410TEST_P(AidlTest, RejectsListArray) {
Devin Moore6a01ca12020-08-28 10:24:19 -07001411 const string expected_stderr = "ERROR: a/Foo.aidl:2.1-7: List[] is not supported.\n";
Devin Moore21b26772020-08-26 16:37:56 -07001412 const string list_array_parcelable =
1413 "package a; parcelable Foo {\n"
1414 " List[] lists; }";
1415 CaptureStderr();
1416 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", list_array_parcelable, typenames_, GetLanguage()));
1417 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1418}
1419
Jiyong Parkf8d53612020-05-04 14:06:13 +09001420TEST_P(AidlTest, RejectsPrimitiveListInStableAidl) {
1421 AidlError error;
1422 string expected_stderr =
1423 "ERROR: a/IFoo.aidl:2.7-11: "
1424 "Encountered an untyped List or Map. The use of untyped List/Map is "
1425 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
1426 "the receiving side. Consider switching to an array or a generic List/Map.\n";
1427 if (GetLanguage() != Options::Language::JAVA) {
1428 expected_stderr =
1429 "ERROR: a/IFoo.aidl:2.1-7: "
1430 "Currently, only the Java backend supports non-generic List.\n";
1431 }
1432
1433 const string primitive_interface =
1434 "package a; interface IFoo {\n"
1435 " List foo(); }";
1436 CaptureStderr();
Jiyong Park40782d02020-07-24 19:17:43 +09001437 AidlTypenames tn1;
1438 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_interface, tn1, GetLanguage(), &error,
Jiyong Parkf8d53612020-05-04 14:06:13 +09001439 {"--structured"}));
1440 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkf8d53612020-05-04 14:06:13 +09001441
1442 string primitive_parcelable =
1443 "package a; parcelable IFoo {\n"
1444 " List foo;}";
1445 CaptureStderr();
Jiyong Park40782d02020-07-24 19:17:43 +09001446 AidlTypenames tn2;
1447 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_parcelable, tn2, GetLanguage(), &error,
Jiyong Parkf8d53612020-05-04 14:06:13 +09001448 {"--structured"}));
1449 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1450}
1451
Jeongik Cha225519b2020-08-29 01:55:32 +09001452TEST_P(AidlTest, ExtensionTest) {
1453 CaptureStderr();
Jeongik Cha649e8a72020-03-27 17:47:40 +09001454 string extendable_parcelable =
1455 "package a; parcelable Data {\n"
1456 " ParcelableHolder extension;\n"
1457 " ParcelableHolder extension2;\n"
1458 "}";
Jeongik Cha8f02a532020-10-14 00:16:28 +09001459 if (GetLanguage() == Options::Language::RUST) {
Jeongik Cha225519b2020-08-29 01:55:32 +09001460 EXPECT_EQ(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1461 EXPECT_EQ(
Jeongik Cha8f02a532020-10-14 00:16:28 +09001462 "ERROR: a/Data.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
Jeongik Cha225519b2020-08-29 01:55:32 +09001463 "yet.\n",
1464 GetCapturedStderr());
1465 } else {
1466 EXPECT_NE(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1467 EXPECT_EQ("", GetCapturedStderr());
1468 }
1469}
1470TEST_P(AidlTest, ParcelableHolderAsReturnType) {
1471 CaptureStderr();
Jeongik Cha649e8a72020-03-27 17:47:40 +09001472 string parcelableholder_return_interface =
1473 "package a; interface IFoo {\n"
1474 " ParcelableHolder foo();\n"
1475 "}";
Jeongik Cha225519b2020-08-29 01:55:32 +09001476 EXPECT_EQ(nullptr,
1477 Parse("a/IFoo.aidl", parcelableholder_return_interface, typenames_, GetLanguage()));
Jeongik Cha649e8a72020-03-27 17:47:40 +09001478
Jeongik Cha8f02a532020-10-14 00:16:28 +09001479 if (GetLanguage() == Options::Language::RUST) {
Jeongik Cha225519b2020-08-29 01:55:32 +09001480 EXPECT_EQ(
Steven Morelandebc3c5d2020-09-30 23:40:33 +00001481 "ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n"
Jeongik Cha8f02a532020-10-14 00:16:28 +09001482 "ERROR: a/IFoo.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
Jeongik Cha225519b2020-08-29 01:55:32 +09001483 "yet.\n",
1484 GetCapturedStderr());
1485 return;
1486 }
1487 EXPECT_EQ("ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n",
1488 GetCapturedStderr());
1489}
1490
1491TEST_P(AidlTest, ParcelableHolderAsArgumentType) {
1492 CaptureStderr();
Jeongik Cha649e8a72020-03-27 17:47:40 +09001493 string extendable_parcelable_arg_interface =
1494 "package a; interface IFoo {\n"
1495 " void foo(in ParcelableHolder ph);\n"
1496 "}";
Jeongik Cha225519b2020-08-29 01:55:32 +09001497 EXPECT_EQ(nullptr,
1498 Parse("a/IFoo.aidl", extendable_parcelable_arg_interface, typenames_, GetLanguage()));
1499
Jeongik Cha8f02a532020-10-14 00:16:28 +09001500 if (GetLanguage() == Options::Language::RUST) {
Jeongik Cha225519b2020-08-29 01:55:32 +09001501 EXPECT_EQ(
Steven Morelandebc3c5d2020-09-30 23:40:33 +00001502 "ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n"
Jeongik Cha8f02a532020-10-14 00:16:28 +09001503 "ERROR: a/IFoo.aidl:2.14-31: The Rust backend does not support ParcelableHolder "
Jeongik Cha225519b2020-08-29 01:55:32 +09001504 "yet.\n",
1505 GetCapturedStderr());
1506 return;
1507 }
1508 EXPECT_EQ("ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n",
1509 GetCapturedStderr());
Jeongik Cha649e8a72020-03-27 17:47:40 +09001510}
1511
Jeongik Chaf6ec8982020-10-15 00:10:30 +09001512TEST_P(AidlTest, RejectNullableParcelableHolderField) {
1513 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { @nullable ParcelableHolder ext; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09001514 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jeongik Chaf6ec8982020-10-15 00:10:30 +09001515 const string expected_stderr = "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n";
1516 CaptureStderr();
1517 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1518 if (GetLanguage() == Options::Language::RUST) {
1519 EXPECT_EQ(
1520 "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n"
1521 "ERROR: Foo.aidl:1.27-44: The Rust backend does not support ParcelableHolder "
1522 "yet.\n",
1523 GetCapturedStderr());
1524 return;
1525 }
1526 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1527}
1528
Jooyung Han3f347ca2020-12-01 12:41:50 +09001529TEST_P(AidlTest, ParcelablesWithConstants) {
1530 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { const int BIT = 0x1 << 3; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09001531 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jooyung Han3f347ca2020-12-01 12:41:50 +09001532 CaptureStderr();
1533 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1534 EXPECT_EQ("", GetCapturedStderr());
1535}
1536
1537TEST_P(AidlTest, UnionWithConstants) {
1538 io_delegate_.SetFileContents("Foo.aidl", "union Foo { const int BIT = 0x1 << 3; int n; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09001539 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jooyung Han3f347ca2020-12-01 12:41:50 +09001540 CaptureStderr();
1541 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1542 EXPECT_EQ("", GetCapturedStderr());
1543}
1544
Jooyung Han633eab62021-01-07 14:12:40 +09001545TEST_F(AidlTest, ConstantsWithAnnotations) {
1546 io_delegate_.SetFileContents("IFoo.aidl",
1547 "interface IFoo {\n"
1548 " @JavaPassthrough(annotation=\"@Foo\")\n"
1549 " const @JavaPassthrough(annotation=\"@Bar\") int FOO = 0;\n"
1550 "}");
1551 Options options = Options::From("aidl IFoo.aidl --lang=java -o out");
1552 CaptureStderr();
1553 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1554 EXPECT_EQ("", GetCapturedStderr());
1555 string code;
1556 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/IFoo.java", &code));
1557 EXPECT_THAT(code, HasSubstr("@Foo\n"));
1558 EXPECT_THAT(code, HasSubstr("@Bar\n"));
1559}
1560
Jiyong Park02da7422018-07-16 16:00:26 +09001561TEST_F(AidlTest, ApiDump) {
1562 io_delegate_.SetFileContents(
1563 "foo/bar/IFoo.aidl",
1564 "package foo.bar;\n"
1565 "import foo.bar.Data;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001566 "// comment @hide\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001567 "interface IFoo {\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001568 " /* @hide */\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001569 " int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
1570 " int foo2(@utf8InCpp String x, inout List<String> y);\n"
1571 " IFoo foo3(IFoo foo);\n"
1572 " Data getData();\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001573 " // @hide\n"
Jiyong Parka428d212018-08-29 22:26:30 +09001574 " const int A = 1;\n"
1575 " const String STR = \"Hello\";\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001576 "}\n");
1577 io_delegate_.SetFileContents("foo/bar/Data.aidl",
1578 "package foo.bar;\n"
1579 "import foo.bar.IFoo;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001580 "/* @hide*/\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001581 "parcelable Data {\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001582 " // @hide\n"
Jiyong Parka468e2a2018-08-29 21:25:18 +09001583 " int x = 10;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001584 " // @hide\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001585 " int y;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001586 " /*@hide2*/\n"
Jooyung Han55f96ad2020-12-13 10:08:33 +09001587 " IFoo foo;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001588 " // It should be @hide property\n"
Jeongik Cha3271ffa2018-12-04 15:19:20 +09001589 " @nullable String[] c;\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001590 "}\n");
1591 io_delegate_.SetFileContents("api.aidl", "");
Jiyong Park633246c2019-11-25 10:50:05 +09001592 vector<string> args = {"aidl", "--dumpapi", "--out=dump", "--include=.",
1593 "foo/bar/IFoo.aidl", "foo/bar/Data.aidl"};
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001594 Options options = Options::From(args);
Jiyong Park02da7422018-07-16 16:00:26 +09001595 bool result = dump_api(options, io_delegate_);
1596 ASSERT_TRUE(result);
1597 string actual;
Jiyong Parke59c3682018-09-11 23:10:25 +09001598 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
Paul Trautrimb01451d2020-02-27 13:10:16 +09001599 EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
Jeongik Cha997281d2020-01-16 15:23:59 +09001600/* @hide */
Jiyong Parke59c3682018-09-11 23:10:25 +09001601interface IFoo {
Jeongik Cha997281d2020-01-16 15:23:59 +09001602 /* @hide */
Jiyong Parke59c3682018-09-11 23:10:25 +09001603 int foo(out int[] a, String b, boolean c, inout List<String> d);
1604 int foo2(@utf8InCpp String x, inout List<String> y);
1605 foo.bar.IFoo foo3(foo.bar.IFoo foo);
1606 foo.bar.Data getData();
Jeongik Cha997281d2020-01-16 15:23:59 +09001607 /* @hide */
Jiyong Parke59c3682018-09-11 23:10:25 +09001608 const int A = 1;
1609 const String STR = "Hello";
1610}
Paul Trautrimb01451d2020-02-27 13:10:16 +09001611)"));
Jiyong Park02da7422018-07-16 16:00:26 +09001612
Jiyong Parke59c3682018-09-11 23:10:25 +09001613 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
Paul Trautrimb01451d2020-02-27 13:10:16 +09001614 EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
Jeongik Cha997281d2020-01-16 15:23:59 +09001615/* @hide */
Jiyong Parke59c3682018-09-11 23:10:25 +09001616parcelable Data {
Jeongik Cha997281d2020-01-16 15:23:59 +09001617 /* @hide */
Jiyong Parke59c3682018-09-11 23:10:25 +09001618 int x = 10;
Jeongik Cha997281d2020-01-16 15:23:59 +09001619 /* @hide */
Jiyong Parke59c3682018-09-11 23:10:25 +09001620 int y;
1621 foo.bar.IFoo foo;
Jeongik Cha997281d2020-01-16 15:23:59 +09001622 /* @hide */
Jeongik Cha3271ffa2018-12-04 15:19:20 +09001623 @nullable String[] c;
Jiyong Park02da7422018-07-16 16:00:26 +09001624}
Paul Trautrimb01451d2020-02-27 13:10:16 +09001625)"));
Jiyong Park02da7422018-07-16 16:00:26 +09001626}
1627
Jiyong Parked65bf42018-08-28 15:43:27 +09001628TEST_F(AidlTest, ApiDumpWithManualIds) {
1629 io_delegate_.SetFileContents(
1630 "foo/bar/IFoo.aidl",
1631 "package foo.bar;\n"
1632 "interface IFoo {\n"
1633 " int foo() = 1;\n"
1634 " int bar() = 2;\n"
1635 " int baz() = 10;\n"
1636 "}\n");
1637
Jiyong Parke59c3682018-09-11 23:10:25 +09001638 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
Jiyong Parked65bf42018-08-28 15:43:27 +09001639 Options options = Options::From(args);
1640 bool result = dump_api(options, io_delegate_);
1641 ASSERT_TRUE(result);
1642 string actual;
Jiyong Parke59c3682018-09-11 23:10:25 +09001643 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
Paul Trautrimb01451d2020-02-27 13:10:16 +09001644 EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
Jiyong Parke59c3682018-09-11 23:10:25 +09001645interface IFoo {
1646 int foo() = 1;
1647 int bar() = 2;
1648 int baz() = 10;
Jiyong Parked65bf42018-08-28 15:43:27 +09001649}
Paul Trautrimb01451d2020-02-27 13:10:16 +09001650)"));
Jiyong Parked65bf42018-08-28 15:43:27 +09001651}
1652
1653TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001654 const string expected_stderr =
1655 "ERROR: foo/bar/IFoo.aidl:4.8-12: You must either assign id's to all methods or to none of "
1656 "them.\n";
Jiyong Parked65bf42018-08-28 15:43:27 +09001657 io_delegate_.SetFileContents(
1658 "foo/bar/IFoo.aidl",
1659 "package foo.bar;\n"
1660 "interface IFoo {\n"
1661 " int foo() = 1;\n"
1662 " int bar();\n"
1663 " int baz() = 10;\n"
1664 "}\n");
1665
Jiyong Parke59c3682018-09-11 23:10:25 +09001666 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
Jiyong Parked65bf42018-08-28 15:43:27 +09001667 Options options = Options::From(args);
Devin Moore097a3ab2020-03-11 16:08:44 -07001668 CaptureStderr();
Jiyong Parked65bf42018-08-28 15:43:27 +09001669 EXPECT_FALSE(dump_api(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001670 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parked65bf42018-08-28 15:43:27 +09001671}
1672
Jooyung Han965e31d2020-11-27 12:30:16 +09001673TEST_F(AidlTest, ApiDumpConstWithAnnotation) {
1674 io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
1675 "package foo.bar;\n"
1676 "interface IFoo {\n"
1677 " @utf8InCpp String foo();\n"
1678 " const @utf8InCpp String bar = \"bar\";\n"
1679 "}\n");
1680
1681 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1682 Options options = Options::From(args);
1683 CaptureStderr();
1684 EXPECT_TRUE(dump_api(options, io_delegate_));
1685 EXPECT_EQ("", GetCapturedStderr());
1686 string actual;
1687 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
Jooyung Han965e31d2020-11-27 12:30:16 +09001688 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1689interface IFoo {
1690 @utf8InCpp String foo();
Jooyung Hanb3ca6302020-11-27 14:13:27 +09001691 const @utf8InCpp String bar = "bar";
Jooyung Han965e31d2020-11-27 12:30:16 +09001692}
1693)"),
1694 actual);
1695}
1696
Jooyung Hanfdaae1d2020-12-14 13:16:15 +09001697TEST_F(AidlTest, ApiDumpWithEnums) {
1698 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1699 "package foo.bar;\n"
1700 "enum Enum {\n"
1701 " FOO,\n"
1702 " BAR = FOO + 1,\n"
1703 "}\n");
1704
1705 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Enum.aidl"};
1706 Options options = Options::From(args);
1707 CaptureStderr();
1708 EXPECT_TRUE(dump_api(options, io_delegate_));
1709 EXPECT_EQ("", GetCapturedStderr());
1710 string actual;
1711 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
1712 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1713 "enum Enum {\n"
1714 " FOO = 0,\n"
1715 " BAR = 1,\n"
1716 "}\n"),
1717 actual);
1718}
1719
1720TEST_F(AidlTest, ApiDumpWithEnumDefaultValues) {
1721 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1722 "package foo.bar;\n"
1723 "enum Enum {\n"
1724 " FOO,\n"
1725 "}\n");
1726 io_delegate_.SetFileContents("foo/bar/Foo.aidl",
1727 "package foo.bar;\n"
1728 "import foo.bar.Enum;\n"
1729 "parcelable Foo {\n"
1730 " Enum e = Enum.FOO;\n"
1731 "}\n");
1732
1733 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
1734 Options options = Options::From(args);
1735 CaptureStderr();
1736 EXPECT_TRUE(dump_api(options, io_delegate_));
1737 EXPECT_EQ("", GetCapturedStderr());
1738 string actual;
1739 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
1740 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1741 "parcelable Foo {\n"
1742 " foo.bar.Enum e = foo.bar.Enum.FOO;\n"
1743 "}\n"),
1744 actual);
1745}
1746
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001747TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001748 const string expected_list_stderr =
Steven Morelandebc3c5d2020-09-30 23:40:33 +00001749 "ERROR: p/IFoo.aidl:1.37-41: List can only have one type parameter, but got: "
1750 "'List<String,String>'\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07001751 const string expected_map_stderr =
1752 "ERROR: p/IFoo.aidl:1.37-40: Map must have 0 or 2 type parameters, but got 'Map<String>'\n";
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001753 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1754 io_delegate_.SetFileContents(options.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001755 "package p; interface IFoo {"
1756 "void foo(List<String, String> a);}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001757 CaptureStderr();
Jiyong Parkb034bf02018-07-30 17:44:33 +09001758 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001759 EXPECT_EQ(expected_list_stderr, GetCapturedStderr());
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001760
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001761 io_delegate_.SetFileContents(options.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001762 "package p; interface IFoo {"
1763 "void foo(Map<String> a);}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001764 CaptureStderr();
Jiyong Parkb034bf02018-07-30 17:44:33 +09001765 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001766 EXPECT_EQ(expected_map_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09001767}
1768
Jeongik Chae48d9942020-01-02 17:39:00 +09001769TEST_F(AidlTest, CheckTypeParameterInMapType) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001770 const string expected_stderr =
1771 "ERROR: p/IFoo.aidl:1.28-31: The type of key in map must be String, but it is 'p.Bar'\n";
Jeongik Chae48d9942020-01-02 17:39:00 +09001772 Options options = Options::From("aidl -I p p/IFoo.aidl");
1773 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar { String s; }");
1774
1775 io_delegate_.SetFileContents("p/IFoo.aidl",
1776 "package p; interface IFoo {"
1777 "Map<String, Bar> foo();}");
1778 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1779
1780 io_delegate_.SetFileContents("p/IFoo.aidl",
1781 "package p; interface IFoo {"
1782 "Map<Bar, Bar> foo();}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001783 CaptureStderr();
Jeongik Chae48d9942020-01-02 17:39:00 +09001784 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001785 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jeongik Chae48d9942020-01-02 17:39:00 +09001786
1787 io_delegate_.SetFileContents("p/IFoo.aidl",
1788 "package p; interface IFoo {"
1789 "Map<String, String> foo();}");
1790 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1791
1792 io_delegate_.SetFileContents("p/IFoo.aidl",
1793 "package p; interface IFoo {"
1794 "Map<String, ParcelFileDescriptor> foo();}");
1795 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1796}
1797
Jeongik Chadf76dc72019-11-28 00:08:47 +09001798TEST_F(AidlTest, WrongGenericType) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001799 const string expected_stderr = "ERROR: p/IFoo.aidl:1.28-34: String is not a generic type.\n";
Jeongik Chadf76dc72019-11-28 00:08:47 +09001800 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1801 io_delegate_.SetFileContents(options.InputFiles().front(),
1802 "package p; interface IFoo {"
1803 "String<String> foo(); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07001804 CaptureStderr();
Jeongik Chadf76dc72019-11-28 00:08:47 +09001805 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001806 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jeongik Chadf76dc72019-11-28 00:08:47 +09001807}
1808
1809TEST_F(AidlTest, UserDefinedUnstructuredGenericParcelableType) {
1810 Options optionsForParcelable = Options::From("aidl -I p p/Bar.aidl");
1811 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, T>;");
Devin Moore097a3ab2020-03-11 16:08:44 -07001812 CaptureStderr();
Jeongik Chadf76dc72019-11-28 00:08:47 +09001813 EXPECT_NE(0, ::android::aidl::compile_aidl(optionsForParcelable, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001814 EXPECT_EQ("ERROR: p/Bar.aidl:1.22-26: Every type parameter should be unique.\n",
1815 GetCapturedStderr());
Jeongik Chadf76dc72019-11-28 00:08:47 +09001816
1817 Options options = Options::From("aidl -I p p/IFoo.aidl");
1818 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar;");
1819 io_delegate_.SetFileContents("p/IFoo.aidl",
1820 "package p; interface IFoo {"
1821 "Bar<String, String> foo();}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001822 CaptureStderr();
Jeongik Chadf76dc72019-11-28 00:08:47 +09001823 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001824 EXPECT_EQ("ERROR: p/IFoo.aidl:1.28-31: p.Bar is not a generic type.\n", GetCapturedStderr());
Jeongik Chadf76dc72019-11-28 00:08:47 +09001825 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T>;");
Devin Moore097a3ab2020-03-11 16:08:44 -07001826 CaptureStderr();
Jeongik Chadf76dc72019-11-28 00:08:47 +09001827 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001828 EXPECT_EQ("ERROR: p/IFoo.aidl:1.28-31: p.Bar must have 1 type parameters, but got 2\n",
1829 GetCapturedStderr());
Jeongik Chadf76dc72019-11-28 00:08:47 +09001830 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, V>;");
1831 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1832 io_delegate_.SetFileContents("p/IFoo.aidl",
1833 "package p; interface IFoo {"
1834 "Bar<String, ParcelFileDescriptor> foo();}");
1835 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jeongik Chae74c86d2019-12-12 16:54:03 +09001836
1837 io_delegate_.SetFileContents("p/IFoo.aidl",
1838 "package p; interface IFoo {"
1839 "Bar<int, long> foo();}");
1840
1841 io_delegate_.SetFileContents("p/IFoo.aidl",
1842 "package p; interface IFoo {"
1843 "Bar<int[], long[]> foo();}");
1844
1845 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jeongik Chadf76dc72019-11-28 00:08:47 +09001846}
1847
Jeongik Cha0e426012019-07-29 15:57:02 +09001848TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
1849 std::vector<std::string> rawOptions{"aidl --lang=java -o out foo/bar/Foo.aidl",
Andrei Homescub62afd92020-05-11 19:24:59 -07001850 "aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl",
1851 "aidl --lang=rust -o out foo/bar/Foo.aidl"};
Devin Moore5de18ed2020-04-02 13:52:29 -07001852 for (const auto& rawOption : rawOptions) {
1853 string expected_stderr =
1854 "ERROR: foo/bar/Foo.aidl:3.1-10: You must declare only one type per file.\n";
Jeongik Cha0e426012019-07-29 15:57:02 +09001855 Options options = Options::From(rawOption);
1856 io_delegate_.SetFileContents(options.InputFiles().front(),
1857 "package foo.bar;\n"
1858 "interface IFoo1 { int foo(); }\n"
1859 "interface IFoo2 { int foo(); }\n"
1860 "parcelable Data1 { int a; int b;}\n"
1861 "parcelable Data2 { int a; int b;}\n");
Devin Moore097a3ab2020-03-11 16:08:44 -07001862 CaptureStderr();
Jeongik Cha0e426012019-07-29 15:57:02 +09001863 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001864 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09001865
Jeongik Cha0e426012019-07-29 15:57:02 +09001866 io_delegate_.SetFileContents(options.InputFiles().front(),
1867 "package foo.bar;\n"
1868 "interface IFoo1 { int foo(); }\n"
1869 "interface IFoo2 { int foo(); }\n");
Devin Moore097a3ab2020-03-11 16:08:44 -07001870 CaptureStderr();
Jeongik Cha0e426012019-07-29 15:57:02 +09001871 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001872 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09001873
Devin Moore5de18ed2020-04-02 13:52:29 -07001874 expected_stderr = "ERROR: foo/bar/Foo.aidl:3.11-17: You must declare only one type per file.\n";
Jeongik Cha0e426012019-07-29 15:57:02 +09001875 io_delegate_.SetFileContents(options.InputFiles().front(),
1876 "package foo.bar;\n"
1877 "parcelable Data1 { int a; int b;}\n"
1878 "parcelable Data2 { int a; int b;}\n");
Devin Moore097a3ab2020-03-11 16:08:44 -07001879 CaptureStderr();
Jeongik Cha0e426012019-07-29 15:57:02 +09001880 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001881 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09001882 }
1883}
1884
Devin Moorebdba2a82020-03-31 15:19:02 -07001885TEST_P(AidlTest, FailParseOnEmptyFile) {
1886 const string contents = "";
1887 const string expected_stderr = "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected $end\n";
1888 CaptureStderr();
1889 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", contents, typenames_, GetLanguage()));
1890 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1891}
1892
Jiyong Parkb034bf02018-07-30 17:44:33 +09001893TEST_F(AidlTest, MultipleInputFiles) {
1894 Options options = Options::From(
Jiyong Park633246c2019-11-25 10:50:05 +09001895 "aidl --lang=java -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
Jiyong Parkb034bf02018-07-30 17:44:33 +09001896
1897 io_delegate_.SetFileContents(options.InputFiles().at(0),
1898 "package foo.bar;\n"
1899 "import foo.bar.Data;\n"
1900 "interface IFoo { Data getData(); }\n");
1901
1902 io_delegate_.SetFileContents(options.InputFiles().at(1),
1903 "package foo.bar;\n"
1904 "import foo.bar.IFoo;\n"
1905 "parcelable Data { IFoo foo; }\n");
1906
1907 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1908
1909 string content;
1910 for (const auto file : {
1911 "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
1912 content.clear();
1913 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1914 EXPECT_FALSE(content.empty());
1915 }
1916}
1917
1918TEST_F(AidlTest, MultipleInputFilesCpp) {
1919 Options options = Options::From("aidl --lang=cpp -o out -h out/include "
Jiyong Park633246c2019-11-25 10:50:05 +09001920 "-I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
Jiyong Parkb034bf02018-07-30 17:44:33 +09001921
1922 io_delegate_.SetFileContents(options.InputFiles().at(0),
1923 "package foo.bar;\n"
1924 "import foo.bar.Data;\n"
1925 "interface IFoo { Data getData(); }\n");
1926
1927 io_delegate_.SetFileContents(options.InputFiles().at(1),
1928 "package foo.bar;\n"
1929 "import foo.bar.IFoo;\n"
1930 "parcelable Data { IFoo foo; }\n");
1931
1932 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1933
1934 string content;
1935 for (const auto file : {
Jiyong Parkb03551f2018-08-06 19:20:51 +09001936 "out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp",
Jiyong Parkb034bf02018-07-30 17:44:33 +09001937 "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
1938 "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
1939 "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
1940 content.clear();
1941 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1942 EXPECT_FALSE(content.empty());
1943 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001944}
1945
Andrei Homescub62afd92020-05-11 19:24:59 -07001946TEST_F(AidlTest, MultipleInputFilesRust) {
1947 Options options =
1948 Options::From("aidl --lang=rust -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
1949
1950 io_delegate_.SetFileContents(options.InputFiles().at(0),
1951 "package foo.bar;\n"
1952 "import foo.bar.Data;\n"
1953 "interface IFoo { Data getData(); }\n");
1954
1955 io_delegate_.SetFileContents(options.InputFiles().at(1),
1956 "package foo.bar;\n"
1957 "import foo.bar.IFoo;\n"
1958 "parcelable Data { IFoo foo; }\n");
1959
1960 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1961
1962 string content;
1963 for (const auto file : {"out/foo/bar/IFoo.rs", "out/foo/bar/Data.rs"}) {
1964 content.clear();
1965 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1966 EXPECT_FALSE(content.empty());
1967 }
1968}
1969
Devin Moore097a3ab2020-03-11 16:08:44 -07001970TEST_F(AidlTest, ConflictWithMetaTransactionGetVersion) {
1971 const string expected_stderr =
1972 "ERROR: p/IFoo.aidl:1.31-51: method getInterfaceVersion() is reserved for internal use.\n";
Jiyong Park309668e2018-07-28 16:55:44 +09001973 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
1974 // int getInterfaceVersion() is one of the meta transactions
1975 io_delegate_.SetFileContents(options.InputFiles().front(),
1976 "package p; interface IFoo {"
1977 "int getInterfaceVersion(); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07001978 CaptureStderr();
Jiyong Parkb034bf02018-07-30 17:44:33 +09001979 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001980 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1981}
Jiyong Park309668e2018-07-28 16:55:44 +09001982
Devin Moore097a3ab2020-03-11 16:08:44 -07001983TEST_F(AidlTest, ConflictWithSimilarMetaTransaction) {
1984 // boolean getInterfaceVersion() is not a meta transaction, but should be
1985 // prevented because return type is not part of a method signature
1986 const string expected_stderr =
1987 "ERROR: p/IFoo.aidl:1.35-55: method getInterfaceVersion() is reserved for internal use.\n";
1988 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
Jiyong Park309668e2018-07-28 16:55:44 +09001989 io_delegate_.SetFileContents(options.InputFiles().front(),
1990 "package p; interface IFoo {"
1991 "boolean getInterfaceVersion(); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07001992 CaptureStderr();
Jiyong Parkb034bf02018-07-30 17:44:33 +09001993 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001994 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1995}
Jiyong Park309668e2018-07-28 16:55:44 +09001996
Devin Moore097a3ab2020-03-11 16:08:44 -07001997TEST_F(AidlTest, ConflictWithMetaTransactionGetName) {
Jiyong Park309668e2018-07-28 16:55:44 +09001998 // this is another reserved name
Devin Moore097a3ab2020-03-11 16:08:44 -07001999 const string expected_stderr =
2000 "ERROR: p/IFoo.aidl:1.34-53: method getTransactionName(int) is reserved for internal use.\n";
2001 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
Jiyong Park309668e2018-07-28 16:55:44 +09002002 io_delegate_.SetFileContents(options.InputFiles().front(),
2003 "package p; interface IFoo {"
2004 "String getTransactionName(int code); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002005 CaptureStderr();
Jiyong Parkb034bf02018-07-30 17:44:33 +09002006 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002007 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park309668e2018-07-28 16:55:44 +09002008
2009 // this is not a meta interface method as it differs type arguments
2010 io_delegate_.SetFileContents(options.InputFiles().front(),
2011 "package p; interface IFoo {"
2012 "String getTransactionName(); }");
Jiyong Parkb034bf02018-07-30 17:44:33 +09002013 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jiyong Park309668e2018-07-28 16:55:44 +09002014}
2015
Daniel Norman85aed542019-08-21 12:01:14 -07002016TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
Jeongik Cha3271ffa2018-12-04 15:19:20 +09002017 Options options = Options::From("aidl --checkapi old new");
2018 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2019 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
2020 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2021 "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
2022
2023 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2024}
2025
Jiyong Park3656c3c2018-08-01 20:02:01 +09002026TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002027 Options options = Options::From("aidl --checkapi old new");
2028 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
2029 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
Jiyong Park3656c3c2018-08-01 20:02:01 +09002030
2031 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2032}
2033
Jooyung Hanfdaae1d2020-12-14 13:16:15 +09002034TEST_F(AidlTest, CheckApi_EnumFieldsWithDefaultValues) {
2035 Options options = Options::From("aidl --checkapi old new");
2036 const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
2037 const string enum_definition = "package p; enum Enum { FOO }";
2038 io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
2039 io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
2040 io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
2041 io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
2042
2043 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2044}
2045
Daniel Norman85aed542019-08-21 12:01:14 -07002046class AidlTestCompatibleChanges : public AidlTest {
2047 protected:
2048 Options options_ = Options::From("aidl --checkapi old new");
2049};
2050
2051TEST_F(AidlTestCompatibleChanges, NewType) {
2052 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2053 "package p;"
2054 "interface IFoo {"
2055 " void foo(int a);"
2056 "}");
2057 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2058 "package p;"
2059 "interface IFoo {"
2060 " void foo(int a);"
2061 "}");
2062 io_delegate_.SetFileContents("new/p/IBar.aidl",
2063 "package p;"
2064 "interface IBar {"
2065 " void bar();"
2066 "}");
2067 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2068}
2069
2070TEST_F(AidlTestCompatibleChanges, NewMethod) {
2071 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2072 "package p;"
2073 "interface IFoo {"
2074 " void foo(int a);"
2075 "}");
2076 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2077 "package p;"
2078 "interface IFoo {"
2079 " void foo(int a);"
2080 " void bar();"
Jiyong Parkf8d53612020-05-04 14:06:13 +09002081 " void baz(in List<IFoo> arg);"
Daniel Norman85aed542019-08-21 12:01:14 -07002082 "}");
2083 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2084}
2085
2086TEST_F(AidlTestCompatibleChanges, NewField) {
2087 io_delegate_.SetFileContents("old/p/Data.aidl",
2088 "package p;"
2089 "parcelable Data {"
2090 " int foo;"
2091 "}");
2092 io_delegate_.SetFileContents("new/p/Data.aidl",
2093 "package p;"
2094 "parcelable Data {"
2095 " int foo;"
Steven Moreland370ed342020-04-28 18:14:39 -07002096 " int bar = 0;"
Jiyong Parkf8d53612020-05-04 14:06:13 +09002097 " @nullable List<Data> list;"
Daniel Norman85aed542019-08-21 12:01:14 -07002098 "}");
2099 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2100}
2101
2102TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
2103 io_delegate_.SetFileContents("old/p/Enum.aidl",
2104 "package p;"
2105 "enum Enum {"
2106 " FOO = 1,"
2107 "}");
2108 io_delegate_.SetFileContents("new/p/Enum.aidl",
2109 "package p;"
2110 "enum Enum {"
2111 " FOO = 1,"
2112 " BAR = 2,"
2113 "}");
2114 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2115}
2116
2117TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
2118 io_delegate_.SetFileContents("old/p/Enum.aidl",
2119 "package p;"
2120 "enum Enum {"
2121 " FOO = 1,"
2122 " BAR = 2,"
2123 "}");
2124 io_delegate_.SetFileContents("new/p/Enum.aidl",
2125 "package p;"
2126 "enum Enum {"
2127 " BAR = 2,"
2128 " FOO = 1,"
2129 "}");
2130 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2131}
2132
Jooyung Hanb5c55cd2020-10-22 07:59:01 +09002133TEST_F(AidlTestCompatibleChanges, NewUnionField) {
2134 io_delegate_.SetFileContents("old/p/Union.aidl",
2135 "package p;"
2136 "union Union {"
2137 " String foo;"
2138 "}");
2139 io_delegate_.SetFileContents("new/p/Union.aidl",
2140 "package p;"
2141 "union Union {"
2142 " String foo;"
2143 " int num;"
2144 "}");
2145 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2146}
2147
Daniel Norman85aed542019-08-21 12:01:14 -07002148TEST_F(AidlTestCompatibleChanges, NewPackage) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002149 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2150 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002151 "interface IFoo {"
2152 " void foo(int a);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002153 "}");
2154 io_delegate_.SetFileContents("old/p/Data.aidl",
2155 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002156 "parcelable Data {"
2157 " int foo;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002158 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002159 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2160 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002161 "interface IFoo {"
2162 " void foo(int a);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002163 "}");
2164 io_delegate_.SetFileContents("new/p/Data.aidl",
2165 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002166 "parcelable Data {"
2167 " int foo;"
Jiyong Parke59c3682018-09-11 23:10:25 +09002168 "}");
2169 io_delegate_.SetFileContents("new/q/IFoo.aidl",
2170 "package q;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002171 "interface IFoo {"
Jiyong Parke59c3682018-09-11 23:10:25 +09002172 " void foo(int a);"
2173 "}");
2174 io_delegate_.SetFileContents("new/q/Data.aidl",
2175 "package q;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002176 "parcelable Data {"
2177 " int foo;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002178 "}");
Daniel Norman85aed542019-08-21 12:01:14 -07002179 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2180}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002181
Daniel Norman85aed542019-08-21 12:01:14 -07002182TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
2183 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2184 "package p;"
2185 "interface IFoo {"
2186 " void foo(int a);"
2187 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002188 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2189 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002190 "interface IFoo {"
2191 " void foo(int b);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002192 "}");
Daniel Norman85aed542019-08-21 12:01:14 -07002193 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2194}
Jiyong Parke59c3682018-09-11 23:10:25 +09002195
Daniel Norman85aed542019-08-21 12:01:14 -07002196TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002197 io_delegate_.SetFileContents("old/p/I.aidl",
2198 "package p; interface I {"
2199 "const int A = 1; }");
2200 io_delegate_.SetFileContents("new/p/I.aidl",
2201 "package p ; interface I {"
2202 "const int A = 1; const int B = 2;}");
Daniel Norman85aed542019-08-21 12:01:14 -07002203 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2204}
Jiyong Parka428d212018-08-29 22:26:30 +09002205
Daniel Norman85aed542019-08-21 12:01:14 -07002206TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002207 io_delegate_.SetFileContents("old/p/I.aidl",
2208 "package p; interface I {"
2209 "const int A = 1; const int B = 2;}");
2210 io_delegate_.SetFileContents("new/p/I.aidl",
2211 "package p ; interface I {"
2212 "const int B = 2; const int A = 1;}");
Daniel Norman85aed542019-08-21 12:01:14 -07002213 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
Jiyong Park3656c3c2018-08-01 20:02:01 +09002214}
2215
Jooyung Han69ea4ba2020-10-29 15:33:37 +09002216TEST_F(AidlTestCompatibleChanges, ReorderedAnnatations) {
2217 io_delegate_.SetFileContents("old/p/Foo.aidl",
2218 "package p;"
2219 "@JavaPassthrough(annotation=\"Alice\")"
2220 "@JavaPassthrough(annotation=\"Bob\")"
2221 "parcelable Foo {}");
2222 io_delegate_.SetFileContents("new/p/Foo.aidl",
2223 "package p;"
2224 "@JavaPassthrough(annotation=\"Bob\")"
2225 "@JavaPassthrough(annotation=\"Alice\")"
2226 "parcelable Foo {}");
2227 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2228}
2229
Jooyung Han00073272020-11-27 14:20:20 +09002230TEST_F(AidlTestCompatibleChanges, OkayToDeprecate) {
2231 io_delegate_.SetFileContents("old/p/Foo.aidl",
2232 "package p;"
2233 "parcelable Foo {}");
2234 io_delegate_.SetFileContents("new/p/Foo.aidl",
2235 "package p;"
2236 "@JavaPassthrough(annotation=\"@Deprecated\")"
2237 "parcelable Foo {}");
2238 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2239}
2240
Jooyung Han636fd2f2020-10-22 11:33:45 +09002241TEST_F(AidlTestCompatibleChanges, NewFieldOfNewType) {
2242 io_delegate_.SetFileContents("old/p/Data.aidl",
2243 "package p;"
2244 "parcelable Data {"
2245 " int num;"
2246 "}");
2247 io_delegate_.SetFileContents(
2248 "new/p/Data.aidl",
2249 "package p;"
2250 "parcelable Data {"
2251 " int num;"
2252 " p.Enum e;" // this is considered as valid since 0(enum default) is valid for "Enum" type
2253 "}");
2254 io_delegate_.SetFileContents("new/p/Enum.aidl",
2255 "package p;"
2256 "enum Enum {"
2257 " FOO = 0,"
2258 " BAR = 1,"
2259 "}");
2260 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2261}
2262
Daniel Norman85aed542019-08-21 12:01:14 -07002263class AidlTestIncompatibleChanges : public AidlTest {
2264 protected:
2265 Options options_ = Options::From("aidl --checkapi old new");
2266};
2267
2268TEST_F(AidlTestIncompatibleChanges, RemovedType) {
Jiyong Park0cf03b12020-07-22 19:36:34 +09002269 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002270 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2271 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002272 "interface IFoo {"
2273 " void foo(in String[] str);"
2274 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002275 "}");
Devin Moored131d5e2020-03-31 10:39:10 -07002276 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002277 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moored131d5e2020-03-31 10:39:10 -07002278 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002279}
2280
2281TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002282 const string expected_stderr =
2283 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002284 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2285 "package p;"
2286 "interface IFoo {"
2287 " void foo(in String[] str);"
2288 " void bar(@utf8InCpp String str);"
2289 "}");
2290 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2291 "package p;"
2292 "interface IFoo {"
2293 " void foo(in String[] str);"
2294 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002295 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002296 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002297 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002298}
2299
Jiyong Parkf8d53612020-05-04 14:06:13 +09002300TEST_F(AidlTestIncompatibleChanges, UntypedListInInterface) {
2301 const string expected_stderr =
2302 "ERROR: new/p/IFoo.aidl:1.61-65: "
2303 "Encountered an untyped List or Map. The use of untyped List/Map is "
2304 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2305 "the receiving side. Consider switching to an array or a generic List/Map.\n"
2306 "ERROR: new/p/IFoo.aidl: Failed to read.\n";
2307 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2308 "package p;"
2309 "interface IFoo {"
2310 " void foo(in String[] str);"
2311 "}");
2312 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2313 "package p;"
2314 "interface IFoo {"
2315 " void foo(in String[] str);"
2316 " void bar(in List arg);"
2317 "}");
2318 CaptureStderr();
2319 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2320 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2321}
2322
2323TEST_F(AidlTestCompatibleChanges, UntypedListInParcelable) {
2324 const string expected_stderr =
2325 "ERROR: new/p/Data.aidl:1.54-59: "
2326 "Encountered an untyped List or Map. The use of untyped List/Map is "
2327 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2328 "the receiving side. Consider switching to an array or a generic List/Map.\n"
2329 "ERROR: new/p/Data.aidl: Failed to read.\n";
2330 io_delegate_.SetFileContents("old/p/Data.aidl",
2331 "package p;"
2332 "parcelable Data {"
2333 " int foo;"
2334 "}");
2335 io_delegate_.SetFileContents("new/p/Data.aidl",
2336 "package p;"
2337 "parcelable Data {"
2338 " int foo;"
2339 " @nullable List list;"
2340 "}");
2341 CaptureStderr();
2342 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2343 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2344}
2345
Daniel Norman85aed542019-08-21 12:01:14 -07002346TEST_F(AidlTestIncompatibleChanges, RemovedField) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002347 const string expected_stderr =
2348 "ERROR: new/p/Data.aidl:1.21-26: Number of fields in p.Data is reduced from 2 to 1.\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002349 io_delegate_.SetFileContents("old/p/Data.aidl",
2350 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002351 "parcelable Data {"
2352 " int foo;"
2353 " int bar;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002354 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002355 io_delegate_.SetFileContents("new/p/Data.aidl",
2356 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002357 "parcelable Data {"
2358 " int foo;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002359 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002360 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002361 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002362 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002363}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002364
Jooyung Hanb5c55cd2020-10-22 07:59:01 +09002365TEST_F(AidlTestIncompatibleChanges, NewFieldWithNoDefault) {
2366 const string expected_stderr =
2367 "ERROR: new/p/Data.aidl:1.46-50: Field 'str' does not have a useful default in some "
2368 "backends. Please either provide a default value for this field or mark the field as "
2369 "@nullable. This value or a null value will be used automatically when an old version of "
2370 "this parcelable is sent to a process which understands a new version of this parcelable. In "
2371 "order to make sure your code continues to be backwards compatible, make sure the default or "
2372 "null value does not cause a semantic change to this parcelable.\n";
2373 io_delegate_.SetFileContents("old/p/Data.aidl",
2374 "package p;"
2375 "parcelable Data {"
2376 " int num;"
2377 "}");
2378 io_delegate_.SetFileContents("new/p/Data.aidl",
2379 "package p;"
2380 "parcelable Data {"
2381 " int num;"
2382 " String str;"
2383 "}");
2384 CaptureStderr();
2385 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2386 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2387}
2388
Jooyung Han636fd2f2020-10-22 11:33:45 +09002389TEST_F(AidlTestIncompatibleChanges, NewFieldWithNonZeroEnum) {
2390 const string expected_stderr =
2391 "ERROR: new/p/Data.aidl:1.46-48: Field 'e' of enum 'Enum' can't be initialized as '0'. "
2392 "Please make sure 'Enum' has '0' as a valid value.\n";
2393 io_delegate_.SetFileContents("old/p/Data.aidl",
2394 "package p;"
2395 "parcelable Data {"
2396 " int num;"
2397 "}");
2398 io_delegate_.SetFileContents("new/p/Data.aidl",
2399 "package p;"
2400 "parcelable Data {"
2401 " int num;"
2402 " p.Enum e;"
2403 "}");
2404 io_delegate_.SetFileContents("new/p/Enum.aidl",
2405 "package p;"
2406 "enum Enum {"
2407 " FOO = 1,"
2408 " BAR = 2,"
2409 "}");
2410 CaptureStderr();
2411 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2412 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2413}
2414
Daniel Norman85aed542019-08-21 12:01:14 -07002415TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002416 const string expected_stderr =
2417 "ERROR: new/p/Enum.aidl:1.15-20: Removed enumerator from p.Enum: FOO\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002418 io_delegate_.SetFileContents("old/p/Enum.aidl",
2419 "package p;"
2420 "enum Enum {"
2421 " FOO = 1,"
2422 " BAR = 2,"
2423 "}");
2424 io_delegate_.SetFileContents("new/p/Enum.aidl",
2425 "package p;"
2426 "enum Enum {"
2427 " BAR = 2,"
2428 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002429 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002430 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002431 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002432}
2433
Jooyung Hanb5c55cd2020-10-22 07:59:01 +09002434TEST_F(AidlTestIncompatibleChanges, RemovedUnionField) {
2435 const string expected_stderr =
2436 "ERROR: new/p/Union.aidl:1.16-22: Number of fields in p.Union is reduced from 2 to 1.\n";
2437 io_delegate_.SetFileContents("old/p/Union.aidl",
2438 "package p;"
2439 "union Union {"
2440 " String str;"
2441 " int num;"
2442 "}");
2443 io_delegate_.SetFileContents("new/p/Union.aidl",
2444 "package p;"
2445 "union Union {"
2446 " String str;"
2447 "}");
2448 CaptureStderr();
2449 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2450 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2451}
2452
Daniel Norman85aed542019-08-21 12:01:14 -07002453TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002454 const string expected_stderr =
2455 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002456 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2457 "package p;"
2458 "interface IFoo {"
2459 " void foo(in String[] str);"
2460 " void bar(@utf8InCpp String str);"
2461 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002462 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2463 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002464 "interface IFoo {"
2465 " void foo(in String[] str);"
2466 " void bar2(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002467 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002468 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002469 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002470 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002471}
2472
Daniel Norman85aed542019-08-21 12:01:14 -07002473TEST_F(AidlTestIncompatibleChanges, RenamedType) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002474 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002475 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2476 "package p;"
2477 "interface IFoo {"
2478 " void foo(in String[] str);"
2479 " void bar(@utf8InCpp String str);"
2480 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002481 io_delegate_.SetFileContents("new/p/IFoo2.aidl",
2482 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002483 "interface IFoo2 {"
2484 " void foo(in String[] str);"
2485 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002486 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002487 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002488 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002489 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002490}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002491
Daniel Norman85aed542019-08-21 12:01:14 -07002492TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002493 const string expected_stderr =
2494 "ERROR: new/p/Enum.aidl:1.15-20: Changed enumerator value: p.Enum::FOO from 1 to 3.\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002495 io_delegate_.SetFileContents("old/p/Enum.aidl",
2496 "package p;"
2497 "enum Enum {"
2498 " FOO = 1,"
2499 " BAR = 2,"
2500 "}");
2501 io_delegate_.SetFileContents("new/p/Enum.aidl",
2502 "package p;"
2503 "enum Enum {"
2504 " FOO = 3,"
2505 " BAR = 2,"
2506 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002507 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002508 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002509 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002510}
2511
2512TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002513 const string expected_stderr =
2514 "ERROR: new/p/IFoo.aidl:1.67-71: Transaction ID changed: p.IFoo.foo(String[]) is changed "
2515 "from 0 to 1.\n"
2516 "ERROR: new/p/IFoo.aidl:1.33-37: Transaction ID changed: p.IFoo.bar(String) is changed from "
2517 "1 to 0.\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002518 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2519 "package p;"
2520 "interface IFoo {"
2521 " void foo(in String[] str);"
2522 " void bar(@utf8InCpp String str);"
2523 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002524 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2525 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002526 "interface IFoo {"
2527 " void bar(@utf8InCpp String str);"
2528 " void foo(in String[] str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002529 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002530 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002531 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002532 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002533}
2534
2535TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002536 const string expected_stderr =
Jiyong Parkb07d9932020-05-15 12:56:54 +09002537 "ERROR: new/p/Data.aidl:1.33-37: Reordered bar from 1 to 0.\n"
2538 "ERROR: new/p/Data.aidl:1.43-47: Reordered foo from 0 to 1.\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002539 io_delegate_.SetFileContents("old/p/Data.aidl",
Jiyong Parke59c3682018-09-11 23:10:25 +09002540 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002541 "parcelable Data {"
2542 " int foo;"
2543 " int bar;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002544 "}");
Daniel Norman85aed542019-08-21 12:01:14 -07002545 io_delegate_.SetFileContents("new/p/Data.aidl",
2546 "package p;"
2547 "parcelable Data {"
2548 " int bar;"
2549 " int foo;"
2550 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002551 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002552 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002553 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002554}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002555
Daniel Norman85aed542019-08-21 12:01:14 -07002556TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
Devin Mooreeccdb902020-03-24 16:22:40 -07002557 const string expected_stderr = "ERROR: new/p/IFoo.aidl:1.33-37: Direction changed: in to out.\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002558 io_delegate_.SetFileContents("old/p/IFoo.aidl",
Jiyong Parke59c3682018-09-11 23:10:25 +09002559 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002560 "interface IFoo {"
2561 " void foo(in String[] str);"
2562 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002563 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002564 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2565 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002566 "interface IFoo {"
2567 " void foo(out String[] str);"
2568 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002569 "}");
Devin Mooreeccdb902020-03-24 16:22:40 -07002570 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002571 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Mooreeccdb902020-03-24 16:22:40 -07002572 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002573}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002574
Daniel Norman85aed542019-08-21 12:01:14 -07002575TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002576 const string expected_stderr =
2577 "ERROR: new/p/IFoo.aidl:1.51-58: Changed annotations: (empty) to @utf8InCpp\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002578 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2579 "package p;"
2580 "interface IFoo {"
2581 " void foo(in String[] str);"
2582 " void bar(@utf8InCpp String str);"
2583 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002584 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2585 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002586 "interface IFoo {"
Jiyong Parke59c3682018-09-11 23:10:25 +09002587 " void foo(in @utf8InCpp String[] str);"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002588 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002589 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002590 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002591 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002592 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002593}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002594
Daniel Norman85aed542019-08-21 12:01:14 -07002595TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002596 const string expected_stderr =
2597 "ERROR: new/p/IFoo.aidl:1.66-72: Changed annotations: @utf8InCpp to (empty)\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002598 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2599 "package p;"
2600 "interface IFoo {"
2601 " void foo(in String[] str);"
2602 " void bar(@utf8InCpp String str);"
2603 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002604 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2605 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002606 "interface IFoo {"
Jiyong Parke59c3682018-09-11 23:10:25 +09002607 " void foo(in String[] str);"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002608 " void bar(String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002609 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002610 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002611 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002612 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002613}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002614
Jooyung Han60b2fde2020-10-29 15:12:40 +09002615TEST_F(AidlTestIncompatibleChanges, ChangedBackingTypeOfEnum) {
2616 const string expected_stderr =
2617 "ERROR: new/p/Foo.aidl:1.11-32: Type changed: byte to long.\n"
2618 "ERROR: new/p/Foo.aidl:1.36-40: Changed backing types.\n";
2619 io_delegate_.SetFileContents("old/p/Foo.aidl",
2620 "package p;"
2621 "@Backing(type=\"byte\")"
2622 "enum Foo {"
2623 " FOO, BAR,"
2624 "}");
2625 io_delegate_.SetFileContents("new/p/Foo.aidl",
2626 "package p;"
2627 "@Backing(type=\"long\")"
2628 "enum Foo {"
2629 " FOO, BAR,"
2630 "}");
2631 CaptureStderr();
2632 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2633 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2634}
2635
Jooyung Han69ea4ba2020-10-29 15:33:37 +09002636TEST_F(AidlTestIncompatibleChanges, ChangedAnnatationParams) {
2637 const string expected_stderr =
2638 "ERROR: new/p/Foo.aidl:1.55-59: Changed annotations: @JavaPassthrough(annotation=\"Alice\") "
2639 "to @JavaPassthrough(annotation=\"Bob\")\n";
2640 io_delegate_.SetFileContents("old/p/Foo.aidl",
2641 "package p;"
2642 "@JavaPassthrough(annotation=\"Alice\")"
2643 "parcelable Foo {}");
2644 io_delegate_.SetFileContents("new/p/Foo.aidl",
2645 "package p;"
2646 "@JavaPassthrough(annotation=\"Bob\")"
2647 "parcelable Foo {}");
2648
2649 CaptureStderr();
2650 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2651 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2652}
2653
Devin Mooredb7ac512020-08-07 11:17:36 -07002654TEST_F(AidlTestIncompatibleChanges, AddedParcelableAnnotation) {
2655 const string expected_stderr =
2656 "ERROR: new/p/Foo.aidl:1.47-51: Changed annotations: (empty) to @JavaOnlyStableParcelable\n";
2657 io_delegate_.SetFileContents("old/p/Foo.aidl",
2658 "package p;"
2659 "parcelable Foo {"
2660 " int A;"
2661 "}");
2662 io_delegate_.SetFileContents("new/p/Foo.aidl",
2663 "package p;"
2664 "@JavaOnlyStableParcelable parcelable Foo {"
2665 " int A;"
2666 "}");
2667 CaptureStderr();
2668 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2669 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2670}
2671
2672TEST_F(AidlTestIncompatibleChanges, RemovedParcelableAnnotation) {
2673 const string expected_stderr =
2674 "ERROR: new/p/Foo.aidl:1.21-25: Changed annotations: @JavaOnlyStableParcelable to (empty)\n";
2675 io_delegate_.SetFileContents("old/p/Foo.aidl",
2676 "package p;"
2677 "@JavaOnlyStableParcelable parcelable Foo {"
2678 " int A;"
2679 "}");
2680 io_delegate_.SetFileContents("new/p/Foo.aidl",
2681 "package p;"
2682 "parcelable Foo {"
2683 " int A;"
2684 "}");
2685 CaptureStderr();
2686 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2687 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2688}
2689
Daniel Norman85aed542019-08-21 12:01:14 -07002690TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002691 const string expected_stderr = "ERROR: old/q/IFoo.aidl:1.11-21: Removed type: q.IFoo\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002692 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
2693 io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002694 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002695 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002696 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002697 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002698}
Jiyong Parka468e2a2018-08-29 21:25:18 +09002699
Daniel Norman85aed542019-08-21 12:01:14 -07002700TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
Steven Moreland370ed342020-04-28 18:14:39 -07002701 const string expected_stderr = "ERROR: new/p/D.aidl:1.30-32: Changed default value: 1 to 2.\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002702 io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
2703 io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002704 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002705 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002706 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002707}
Jiyong Parka428d212018-08-29 22:26:30 +09002708
Daniel Norman85aed542019-08-21 12:01:14 -07002709TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002710 const string expected_stderr =
2711 "ERROR: old/p/I.aidl:1.51-53: Removed constant declaration: p.I.B\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002712 io_delegate_.SetFileContents("old/p/I.aidl",
2713 "package p; interface I {"
2714 "const int A = 1; const int B = 2;}");
2715 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002716 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002717 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002718 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002719}
Jiyong Parka428d212018-08-29 22:26:30 +09002720
Daniel Norman85aed542019-08-21 12:01:14 -07002721TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002722 const string expected_stderr =
2723 "ERROR: new/p/I.aidl:1.11-21: Changed constant value: p.I.A from 1 to 2.\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002724 io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
2725 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002726 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002727 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002728 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3c35e392018-08-30 13:10:30 +09002729}
2730
Devin Moorec7e47a32020-08-07 10:55:25 -07002731TEST_F(AidlTestIncompatibleChanges, FixedSizeAddedField) {
2732 const string expected_stderr =
2733 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is changed from 1 to 2. "
2734 "This is an incompatible change for FixedSize types.\n";
2735 io_delegate_.SetFileContents("old/p/Foo.aidl",
2736 "package p; @FixedSize parcelable Foo { int A = 1; }");
2737 io_delegate_.SetFileContents("new/p/Foo.aidl",
2738 "package p; @FixedSize parcelable Foo { int A = 1; int B = 2; }");
2739 CaptureStderr();
2740 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2741 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2742}
2743
2744TEST_F(AidlTestIncompatibleChanges, FixedSizeRemovedField) {
2745 const string expected_stderr =
2746 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
2747 io_delegate_.SetFileContents("old/p/Foo.aidl",
2748 "package p; @FixedSize parcelable Foo { int A = 1; int B = 1; }");
2749 io_delegate_.SetFileContents("new/p/Foo.aidl",
2750 "package p; @FixedSize parcelable Foo { int A = 1; }");
2751 CaptureStderr();
2752 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2753 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2754}
2755
2756TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize) {
2757 const string expected_stderr =
2758 "ERROR: Foo.aidl:1.36-38: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2759 "a.\n"
2760 "ERROR: Foo.aidl:1.44-46: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2761 "b.\n"
2762 "ERROR: Foo.aidl:1.55-57: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2763 "c.\n"
2764 "ERROR: Foo.aidl:1.80-82: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2765 "d.\n"
2766 "ERROR: Foo.aidl:1.92-94: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2767 "e.\n"
2768 "ERROR: Foo.aidl:1.109-111: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2769 "f.\n";
2770
2771 io_delegate_.SetFileContents("Foo.aidl",
2772 "@FixedSize parcelable Foo { "
2773 " int[] a;"
2774 " Bar b;"
2775 " String c;"
2776 " ParcelFileDescriptor d;"
2777 " IBinder e;"
2778 " List<String> f;"
Steven Moreland265f3d42020-09-24 19:06:54 +00002779 " int isFixedSize;"
Devin Moorec7e47a32020-08-07 10:55:25 -07002780 "}");
2781 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09002782 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
Devin Moorec7e47a32020-08-07 10:55:25 -07002783
2784 CaptureStderr();
2785 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2786 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2787}
2788
2789TEST_P(AidlTest, AcceptFixedSizeFromFixedSize) {
2790 const string expected_stderr = "";
2791
2792 io_delegate_.SetFileContents("Foo.aidl", "@FixedSize parcelable Foo { int a; Bar b; }");
2793 io_delegate_.SetFileContents("Bar.aidl", "@FixedSize parcelable Bar { Val c; }");
2794 io_delegate_.SetFileContents("Val.aidl", "enum Val { A, B, }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09002795 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
Devin Moorec7e47a32020-08-07 10:55:25 -07002796
2797 CaptureStderr();
2798 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2799 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2800}
2801
Jiyong Park8c380532018-08-30 14:55:26 +09002802TEST_F(AidlTest, RejectAmbiguousImports) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002803 const string expected_stderr =
2804 "ERROR: p/IFoo.aidl: Duplicate files found for q.IBar from:\n"
2805 "dir1/q/IBar.aidl\n"
2806 "dir2/q/IBar.aidl\n"
Devin Moore5de18ed2020-04-02 13:52:29 -07002807 "ERROR: p/IFoo.aidl: Couldn't find import for class q.IBar\n";
Jiyong Park8c380532018-08-30 14:55:26 +09002808 Options options = Options::From("aidl --lang=java -o out -I dir1 -I dir2 p/IFoo.aidl");
2809 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
2810 io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
2811 io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
2812
Devin Moore097a3ab2020-03-11 16:08:44 -07002813 CaptureStderr();
Jiyong Park8c380532018-08-30 14:55:26 +09002814 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002815 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park8c380532018-08-30 14:55:26 +09002816}
2817
Jiyong Parked65bf42018-08-28 15:43:27 +09002818TEST_F(AidlTest, HandleManualIdAssignments) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002819 const string expected_stderr =
2820 "ERROR: new/p/IFoo.aidl:1.32-36: Transaction ID changed: p.IFoo.foo() is changed from 10 to "
2821 "11.\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002822 Options options = Options::From("aidl --checkapi old new");
2823 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
2824 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
Jiyong Parked65bf42018-08-28 15:43:27 +09002825
2826 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2827
Jiyong Parke59c3682018-09-11 23:10:25 +09002828 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002829 CaptureStderr();
Jiyong Parked65bf42018-08-28 15:43:27 +09002830 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002831 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parked65bf42018-08-28 15:43:27 +09002832}
2833
Jiyong Parke05195e2018-10-08 18:24:23 +09002834TEST_F(AidlTest, ParcelFileDescriptorIsBuiltinType) {
2835 Options javaOptions = Options::From("aidl --lang=java -o out p/IFoo.aidl");
2836 Options cppOptions = Options::From("aidl --lang=cpp -h out -o out p/IFoo.aidl");
Andrei Homescub62afd92020-05-11 19:24:59 -07002837 Options rustOptions = Options::From("aidl --lang=rust -o out p/IFoo.aidl");
Jiyong Parke05195e2018-10-08 18:24:23 +09002838
2839 // use without import
2840 io_delegate_.SetFileContents("p/IFoo.aidl",
2841 "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
2842 EXPECT_EQ(0, ::android::aidl::compile_aidl(javaOptions, io_delegate_));
2843 EXPECT_EQ(0, ::android::aidl::compile_aidl(cppOptions, io_delegate_));
Andrei Homescub62afd92020-05-11 19:24:59 -07002844 EXPECT_EQ(0, ::android::aidl::compile_aidl(rustOptions, io_delegate_));
Jiyong Parke05195e2018-10-08 18:24:23 +09002845
Devin Moore7b8d5c92020-03-17 14:14:08 -07002846 // use without import but with full name
Jiyong Parke05195e2018-10-08 18:24:23 +09002847 io_delegate_.SetFileContents(
2848 "p/IFoo.aidl",
2849 "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
2850 EXPECT_EQ(0, ::android::aidl::compile_aidl(javaOptions, io_delegate_));
2851 EXPECT_EQ(0, ::android::aidl::compile_aidl(cppOptions, io_delegate_));
Andrei Homescub62afd92020-05-11 19:24:59 -07002852 EXPECT_EQ(0, ::android::aidl::compile_aidl(rustOptions, io_delegate_));
Jiyong Parke05195e2018-10-08 18:24:23 +09002853
2854 // use with import (as before)
2855 io_delegate_.SetFileContents("p/IFoo.aidl",
2856 "package p;"
2857 "import android.os.ParcelFileDescriptor;"
2858 "interface IFoo{"
2859 " void foo(in ParcelFileDescriptor fd);"
2860 "}");
2861 EXPECT_EQ(0, ::android::aidl::compile_aidl(javaOptions, io_delegate_));
2862 EXPECT_EQ(0, ::android::aidl::compile_aidl(cppOptions, io_delegate_));
Andrei Homescub62afd92020-05-11 19:24:59 -07002863 EXPECT_EQ(0, ::android::aidl::compile_aidl(rustOptions, io_delegate_));
Jiyong Parke05195e2018-10-08 18:24:23 +09002864}
Jiyong Parked65bf42018-08-28 15:43:27 +09002865
Jiyong Park3633b722019-04-11 15:38:26 +09002866TEST_F(AidlTest, ManualIds) {
2867 Options options = Options::From("aidl --lang=java -o out IFoo.aidl");
2868 io_delegate_.SetFileContents("IFoo.aidl",
2869 "interface IFoo {\n"
2870 " void foo() = 0;\n"
2871 " void bar() = 1;\n"
2872 "}");
2873 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2874}
2875
2876TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
2877 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2878 io_delegate_.SetFileContents("IFoo.aidl",
2879 "interface IFoo {\n"
2880 " void foo() = 0;\n"
2881 " void bar() = 1;\n"
2882 "}");
2883 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2884}
2885
2886TEST_F(AidlTest, FailOnDuplicatedIds) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002887 const string expected_stderr =
2888 "ERROR: IFoo.aidl:3.7-11: Found duplicate method id (3) for method bar\n";
Jiyong Park3633b722019-04-11 15:38:26 +09002889 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2890 io_delegate_.SetFileContents("IFoo.aidl",
2891 "interface IFoo {\n"
2892 " void foo() = 3;\n"
2893 " void bar() = 3;\n"
2894 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002895 CaptureStderr();
Jiyong Park3633b722019-04-11 15:38:26 +09002896 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002897 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3633b722019-04-11 15:38:26 +09002898}
2899
2900TEST_F(AidlTest, FailOnOutOfRangeIds) {
2901 // 16777115 is kLastMetaMethodId + 1
Devin Moore097a3ab2020-03-11 16:08:44 -07002902 const string expected_stderr =
2903 "ERROR: IFoo.aidl:3.7-11: Found out of bounds id (16777115) for method bar. "
2904 "Value for id must be between 0 and 16777114 inclusive.\n";
Jiyong Park3633b722019-04-11 15:38:26 +09002905 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2906 io_delegate_.SetFileContents("IFoo.aidl",
2907 "interface IFoo {\n"
2908 " void foo() = 3;\n"
2909 " void bar() = 16777115;\n"
2910 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002911 CaptureStderr();
Jiyong Park3633b722019-04-11 15:38:26 +09002912 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002913 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3633b722019-04-11 15:38:26 +09002914}
2915
2916TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002917 const string expected_stderr =
2918 "ERROR: IFoo.aidl:3.7-11: You must either assign id's to all methods or to none of them.\n";
Jiyong Park3633b722019-04-11 15:38:26 +09002919 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2920 io_delegate_.SetFileContents("IFoo.aidl",
2921 "interface IFoo {\n"
2922 " void foo() = 3;\n"
2923 " void bar();\n"
2924 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002925 CaptureStderr();
Jiyong Park3633b722019-04-11 15:38:26 +09002926 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002927 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3633b722019-04-11 15:38:26 +09002928}
2929
Jiyong Parkc6816252019-07-08 08:12:28 +09002930TEST_F(AidlTest, AllowDuplicatedImportPaths) {
2931 Options options = Options::From("aidl --lang=java -I dir -I dir IFoo.aidl");
2932 io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
2933 io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
2934 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2935}
2936
2937TEST_F(AidlTest, FailOnAmbiguousImports) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002938 const string expected_stderr =
2939 "ERROR: IFoo.aidl: Duplicate files found for IBar from:\n"
2940 "dir/IBar.aidl\n"
2941 "dir2/IBar.aidl\n"
Devin Moore5de18ed2020-04-02 13:52:29 -07002942 "ERROR: IFoo.aidl: Couldn't find import for class IBar\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07002943
Jiyong Parkc6816252019-07-08 08:12:28 +09002944 Options options = Options::From("aidl --lang=java -I dir -I dir2 IFoo.aidl");
2945 io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
2946 io_delegate_.SetFileContents("dir2/IBar.aidl", "interface IBar{}");
2947 io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002948 CaptureStderr();
Jiyong Parkc6816252019-07-08 08:12:28 +09002949 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002950 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkc6816252019-07-08 08:12:28 +09002951}
2952
Jiyong Parkf1f5c802020-05-19 17:33:00 +09002953TEST_F(AidlTest, UnusedImportDoesNotContributeInclude) {
2954 io_delegate_.SetFileContents("a/b/IFoo.aidl",
2955 "package a.b;\n"
2956 "import a.b.IBar;\n"
2957 "import a.b.IQux;\n"
2958 "interface IFoo { IQux foo(); }\n");
2959 io_delegate_.SetFileContents("a/b/IBar.aidl", "package a.b; interface IBar { void foo(); }");
2960 io_delegate_.SetFileContents("a/b/IQux.aidl", "package a.b; interface IQux { void foo(); }");
2961
2962 Options options = Options::From("aidl --lang=ndk a/b/IFoo.aidl -I . -o out -h out/include");
2963 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2964
2965 string output;
2966 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/include/aidl/a/b/IFoo.h", &output));
2967 // IBar was imported but wasn't used. include is not expected.
2968 EXPECT_THAT(output, Not(testing::HasSubstr("#include <aidl/a/b/IBar.h>")));
2969 // IBar was imported and used. include is expected.
2970 EXPECT_THAT(output, (testing::HasSubstr("#include <aidl/a/b/IQux.h>")));
2971}
2972
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09002973TEST_F(AidlTest, ParseJavaPassthroughAnnotation) {
Jooyung Hane6bc5e12020-10-13 10:57:10 +09002974 io_delegate_.SetFileContents("a/IFoo.aidl", R"--(package a;
Jooyung Han4cde01d2020-10-13 11:10:47 +09002975 import a.MyEnum;
Jooyung Hane6bc5e12020-10-13 10:57:10 +09002976 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
2977 @JavaPassthrough(annotation="@com.android.AliceTwo")
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09002978 interface IFoo {
2979 @JavaPassthrough(annotation="@com.android.Bob")
Jooyung Han4cde01d2020-10-13 11:10:47 +09002980 void foo(@JavaPassthrough(annotation="@com.android.Cat") int x, MyEnum y);
Jiyong Park7c3b0e42020-08-04 16:08:32 +09002981 const @JavaPassthrough(annotation="@com.android.David") int A = 3;
Jooyung Hane6bc5e12020-10-13 10:57:10 +09002982 })--");
Jooyung Han4cde01d2020-10-13 11:10:47 +09002983 // JavaPassthrough should work with other types as well (e.g. enum)
2984 io_delegate_.SetFileContents("a/MyEnum.aidl", R"--(package a;
2985 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
2986 @JavaPassthrough(annotation="@com.android.AliceTwo")
2987 @Backing(type="byte")
2988 enum MyEnum {
2989 a, b, c
2990 })--");
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09002991
Jooyung Han4cde01d2020-10-13 11:10:47 +09002992 Options java_options = Options::From("aidl -I . --lang=java -o out a/IFoo.aidl a/MyEnum.aidl");
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09002993 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
2994
2995 string java_out;
2996 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &java_out));
Jooyung Hane6bc5e12020-10-13 10:57:10 +09002997 // type-decl-level annotations with newline at the end
2998 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
2999 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3000 // member-decl-level annotations with newline at the end
3001 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Bob\n"));
3002 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.David\n"));
3003 // inline annotations with space at the end
3004 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Cat "));
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003005
Jooyung Han4cde01d2020-10-13 11:10:47 +09003006 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/MyEnum.java", &java_out));
3007 // type-decl-level annotations with newline at the end
3008 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
3009 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3010
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003011 // Other backends shouldn't be bothered
Jooyung Han4cde01d2020-10-13 11:10:47 +09003012 Options cpp_options =
3013 Options::From("aidl -I . --lang=cpp -o out -h out a/IFoo.aidl a/MyEnum.aidl");
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003014 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
3015
Jooyung Han4cde01d2020-10-13 11:10:47 +09003016 Options ndk_options =
3017 Options::From("aidl -I . --lang=ndk -o out -h out a/IFoo.aidl a/MyEnum.aidl");
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003018 EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
Andrei Homescub62afd92020-05-11 19:24:59 -07003019
Jooyung Han4cde01d2020-10-13 11:10:47 +09003020 Options rust_options = Options::From("aidl -I . --lang=rust -o out a/IFoo.aidl a/MyEnum.aidl");
Andrei Homescub62afd92020-05-11 19:24:59 -07003021 EXPECT_EQ(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003022}
3023
Andrei Homescue61feb52020-08-18 15:44:24 -07003024TEST_F(AidlTest, ParseRustDerive) {
3025 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
3026 @RustDerive(Clone=true, Copy=false)
3027 parcelable Foo {
3028 int a;
3029 })");
3030
3031 Options rust_options = Options::From("aidl --lang=rust -o out a/Foo.aidl");
3032 EXPECT_EQ(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
3033
3034 string rust_out;
3035 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.rs", &rust_out));
3036 EXPECT_THAT(rust_out, testing::HasSubstr("#[derive(Debug, Clone)]"));
3037
3038 // Other backends shouldn't be bothered
3039 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
3040 EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
3041
3042 Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
3043 EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
3044
3045 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
3046 EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
3047}
3048
Jiyong Park56f73d72019-06-11 12:20:28 +09003049class AidlOutputPathTest : public AidlTest {
3050 protected:
3051 void SetUp() override {
3052 AidlTest::SetUp();
3053 io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
3054 }
3055
3056 void Test(const Options& options, const std::string expected_output_path) {
3057 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3058 // check the existence
3059 EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
3060 }
3061};
3062
3063TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
3064 // <out_dir> / <package_name> / <type_name>.java
3065 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
3066}
3067
3068TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
3069 // when output file is explicitly set, it is always respected. -o option is
3070 // ignored.
3071 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3072}
3073
3074TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
3075 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3076}
3077
3078TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
3079 // output is the same as the input file except for the suffix
3080 Test(Options::From("aidl sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
3081}
3082
Devin Moore7b8d5c92020-03-17 14:14:08 -07003083TEST_P(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003084 AidlError error;
3085 const string expected_stderr =
3086 "ERROR: p/IFoo.aidl:3.58-69: Invalid type specifier for an int64 literal: int\n";
3087 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003088 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3089 R"(package p;
3090 interface IFoo {
3091 const int int32_max_oob = 2147483650;
3092 }
3093 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003094 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003095 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3096 EXPECT_EQ(AidlError::BAD_TYPE, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003097}
3098
Devin Moore7b8d5c92020-03-17 14:14:08 -07003099TEST_P(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003100 AidlError error;
3101 const string expected_stderr =
3102 "ERROR: p/IFoo.aidl:3.58-60: Invalid type specifier for an int64 literal: int\n";
3103 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003104 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3105 R"(package p;
3106 interface IFoo {
3107 const int int32_min_oob = -2147483650;
3108 }
3109 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003110 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003111 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3112 EXPECT_EQ(AidlError::BAD_TYPE, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003113}
3114
Devin Moore7b8d5c92020-03-17 14:14:08 -07003115TEST_P(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003116 AidlError error;
3117 const string expected_stderr =
Devin Moore2a088902020-09-17 10:51:19 -07003118 "ERROR: p/IFoo.aidl:3.59-86: Could not parse integer: 21474836509999999999999999\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07003119 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003120 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3121 R"(package p;
3122 interface IFoo {
3123 const long int64_max_oob = 21474836509999999999999999;
3124 }
3125 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003126 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003127 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3128 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003129}
3130
Devin Moore7b8d5c92020-03-17 14:14:08 -07003131TEST_P(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003132 AidlError error;
3133 const string expected_stderr =
Devin Moore2a088902020-09-17 10:51:19 -07003134 "ERROR: p/IFoo.aidl:3.61-87: Could not parse integer: 21474836509999999999999999\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07003135 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003136 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3137 R"(package p;
3138 interface IFoo {
3139 const long int64_min_oob = -21474836509999999999999999;
3140 }
3141 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003142 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003143 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3144 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003145}
3146
Devin Moore7b8d5c92020-03-17 14:14:08 -07003147TEST_P(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003148 AidlError error;
Devin Mooredf93ebb2020-03-25 14:03:35 -07003149 const string expected_stderr =
Jooyung Han29813842020-12-08 01:28:03 +09003150 "ERROR: p/TestEnum.aidl:5.1-36: Invalid type specifier for an int32 literal: byte\n"
Devin Mooredf93ebb2020-03-25 14:03:35 -07003151 "ERROR: p/TestEnum.aidl:5.1-36: Enumerator type differs from enum backing type.\n";
3152 CaptureStderr();
Daniel Normanb28684e2019-10-17 15:31:39 -07003153 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3154 R"(package p;
3155 @Backing(type="byte")
3156 enum TestEnum {
3157 FOO = 127,
3158 BAR,
3159 }
3160 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003161 typenames_, GetLanguage(), &error));
Devin Mooredf93ebb2020-03-25 14:03:35 -07003162 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Devin Moore097a3ab2020-03-11 16:08:44 -07003163 EXPECT_EQ(AidlError::BAD_TYPE, error);
Daniel Normanb28684e2019-10-17 15:31:39 -07003164}
3165
Devin Mooredecaf292020-04-30 09:16:40 -07003166TEST_P(AidlTest, UnsupportedBackingAnnotationParam) {
3167 AidlError error;
3168 const string expected_stderr =
3169 "ERROR: p/TestEnum.aidl:2.1-51: Parameter foo not supported for annotation Backing. It must "
Devin Mooredecaf292020-04-30 09:16:40 -07003170 "be one of: type\n";
3171 CaptureStderr();
3172 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3173 R"(package p;
3174 @Backing(foo="byte")
3175 enum TestEnum {
3176 FOO = 1,
3177 BAR,
3178 }
3179 )",
3180 typenames_, GetLanguage(), &error));
3181 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3182 EXPECT_EQ(AidlError::BAD_TYPE, error);
3183}
3184
Jooyung Han5721a232020-12-24 04:34:55 +09003185TEST_P(AidlTest, BackingAnnotationRequireTypeParameter) {
3186 const string expected_stderr = "ERROR: Enum.aidl:1.1-9: Missing 'type' on @Backing.\n";
3187 CaptureStderr();
3188 EXPECT_EQ(nullptr, Parse("Enum.aidl", "@Backing enum Enum { FOO }", typenames_, GetLanguage()));
3189 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3190}
3191
Jooyung Han66813932020-10-23 13:24:44 +09003192TEST_F(AidlTest, SupportJavaOnlyImmutableAnnotation) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003193 io_delegate_.SetFileContents("Foo.aidl",
3194 "@JavaOnlyImmutable parcelable Foo { int a; Bar b; List<Bar> c; "
3195 "Map<String, Baz> d; Bar[] e; }");
3196 io_delegate_.SetFileContents("Bar.aidl", "@JavaOnlyImmutable parcelable Bar { String a; }");
3197 io_delegate_.SetFileContents("Baz.aidl",
3198 "@JavaOnlyImmutable @JavaOnlyStableParcelable parcelable Baz;");
Jeongik Cha36f76c32020-07-28 00:25:52 +09003199 Options options = Options::From("aidl --lang=java -I . Foo.aidl");
3200 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3201}
3202
Jooyung Han66813932020-10-23 13:24:44 +09003203TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableParcelable) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003204 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
Jeongik Cha36f76c32020-07-28 00:25:52 +09003205 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
Jooyung Hand4057c42020-10-23 13:28:22 +09003206 string expected_error =
Jooyung Han59af9cc2020-10-25 21:44:14 +09003207 "ERROR: Foo.aidl:1.40-44: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
3208 "named 'bar'.\n";
3209 CaptureStderr();
3210 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3211 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3212 EXPECT_EQ(expected_error, GetCapturedStderr());
3213}
3214
3215TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableUnion) {
3216 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable union Foo { Bar bar; }");
3217 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
3218 string expected_error =
3219 "ERROR: Foo.aidl:1.35-39: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
Jooyung Hand4057c42020-10-23 13:28:22 +09003220 "named 'bar'.\n";
3221 CaptureStderr();
Jeongik Cha36f76c32020-07-28 00:25:52 +09003222 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3223 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jooyung Hand4057c42020-10-23 13:28:22 +09003224 EXPECT_EQ(expected_error, GetCapturedStderr());
Jeongik Cha36f76c32020-07-28 00:25:52 +09003225}
3226
Jooyung Han66813932020-10-23 13:24:44 +09003227TEST_F(AidlTest, ImmutableParcelableCannotBeInOut) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003228 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
Jooyung Han15fd6c62020-10-23 13:54:46 +09003229 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(inout Foo foo); }");
3230 string expected_error =
3231 "ERROR: IBar.aidl:1.35-39: 'foo' can't be an inout parameter because @JavaOnlyImmutable can "
3232 "only be an in parameter.\n";
3233 CaptureStderr();
Jeongik Cha36f76c32020-07-28 00:25:52 +09003234 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
3235 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jooyung Han15fd6c62020-10-23 13:54:46 +09003236 EXPECT_EQ(expected_error, GetCapturedStderr());
Jeongik Cha36f76c32020-07-28 00:25:52 +09003237}
3238
Jooyung Han66813932020-10-23 13:24:44 +09003239TEST_F(AidlTest, ImmutableParcelableCannotBeOut) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003240 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
Jooyung Han15fd6c62020-10-23 13:54:46 +09003241 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(out Foo foo); }");
3242 string expected_error =
3243 "ERROR: IBar.aidl:1.33-37: 'foo' can't be an out parameter because @JavaOnlyImmutable can "
3244 "only be an in parameter.\n";
3245 CaptureStderr();
Jeongik Cha36f76c32020-07-28 00:25:52 +09003246 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
3247 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
Jooyung Han15fd6c62020-10-23 13:54:46 +09003248 EXPECT_EQ(expected_error, GetCapturedStderr());
Jeongik Cha36f76c32020-07-28 00:25:52 +09003249}
3250
Jooyung Han66813932020-10-23 13:24:44 +09003251TEST_F(AidlTest, ImmutableParcelableFieldNameRestriction) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003252 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; int A; }");
Jeongik Cha91180252020-07-31 15:43:11 +09003253 Options options = Options::From("aidl --lang=java Foo.aidl");
3254 const string expected_stderr =
Jooyung Han59af9cc2020-10-25 21:44:14 +09003255 "ERROR: Foo.aidl:1.47-49: 'Foo' has duplicate field name 'A' after capitalizing the first "
3256 "letter\n";
Jeongik Cha91180252020-07-31 15:43:11 +09003257 CaptureStderr();
3258 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3259 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3260}
Devin Moore53fc99c2020-08-12 08:07:52 -07003261
Jooyung Han1f14ab32020-10-14 13:48:29 +09003262const char kUnionExampleExpectedOutputCppHeader[] = R"(#pragma once
3263
3264#include <a/ByteEnum.h>
3265#include <binder/Parcel.h>
Jooyung Hand2fa0232020-10-19 02:51:41 +09003266#include <binder/ParcelFileDescriptor.h>
Jooyung Han1f14ab32020-10-14 13:48:29 +09003267#include <binder/Status.h>
Jooyung Handf39e192020-11-23 15:59:46 +09003268#include <cassert>
Jooyung Han74b1dd42020-11-01 22:17:16 +09003269#include <codecvt>
Jooyung Han1f14ab32020-10-14 13:48:29 +09003270#include <cstdint>
Jooyung Han74b1dd42020-11-01 22:17:16 +09003271#include <locale>
3272#include <sstream>
Jooyung Han3df81ae2020-10-17 17:59:59 +09003273#include <type_traits>
Jooyung Han1f14ab32020-10-14 13:48:29 +09003274#include <utility>
3275#include <variant>
3276#include <vector>
3277
Jooyung Handf39e192020-11-23 15:59:46 +09003278#ifndef __BIONIC__
3279#define __assert2(a,b,c,d) ((void)0)
3280#endif
3281
Jooyung Han1f14ab32020-10-14 13:48:29 +09003282namespace a {
3283
3284class Foo : public ::android::Parcelable {
3285public:
Jooyung Han97945de2020-10-15 16:41:38 +09003286 inline bool operator!=(const Foo& rhs) const {
3287 return _value != rhs._value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003288 }
Jooyung Han97945de2020-10-15 16:41:38 +09003289 inline bool operator<(const Foo& rhs) const {
3290 return _value < rhs._value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003291 }
Jooyung Han97945de2020-10-15 16:41:38 +09003292 inline bool operator<=(const Foo& rhs) const {
3293 return _value <= rhs._value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003294 }
Jooyung Han97945de2020-10-15 16:41:38 +09003295 inline bool operator==(const Foo& rhs) const {
3296 return _value == rhs._value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003297 }
Jooyung Han97945de2020-10-15 16:41:38 +09003298 inline bool operator>(const Foo& rhs) const {
3299 return _value > rhs._value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003300 }
Jooyung Han97945de2020-10-15 16:41:38 +09003301 inline bool operator>=(const Foo& rhs) const {
3302 return _value >= rhs._value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003303 }
Jooyung Han97945de2020-10-15 16:41:38 +09003304
Jooyung Han1f14ab32020-10-14 13:48:29 +09003305 enum Tag : int32_t {
Jooyung Han97945de2020-10-15 16:41:38 +09003306 ns = 0, // int[] ns;
3307 e, // a.ByteEnum e;
Jooyung Hand2fa0232020-10-19 02:51:41 +09003308 pfd, // ParcelFileDescriptor pfd;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003309 };
Jooyung Han97945de2020-10-15 16:41:38 +09003310
Jooyung Han1f14ab32020-10-14 13:48:29 +09003311 template<typename _Tp>
Jooyung Han97945de2020-10-15 16:41:38 +09003312 static constexpr bool _not_self = !std::is_same_v<std::remove_cv_t<std::remove_reference_t<_Tp>>, Foo>;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003313
3314 Foo() : _value(std::in_place_index<ns>, ::std::vector<int32_t>({42})) { }
Jooyung Han97945de2020-10-15 16:41:38 +09003315 Foo(const Foo&) = default;
3316 Foo(Foo&&) = default;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003317 Foo& operator=(const Foo&) = default;
3318 Foo& operator=(Foo&&) = default;
3319
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003320 template <typename _Tp, typename = std::enable_if_t<_not_self<_Tp>>>
3321 // NOLINTNEXTLINE(google-explicit-constructor)
Jooyung Han97945de2020-10-15 16:41:38 +09003322 constexpr Foo(_Tp&& _arg)
3323 : _value(std::forward<_Tp>(_arg)) {}
3324
3325 template <typename... _Tp>
3326 constexpr explicit Foo(_Tp&&... _args)
3327 : _value(std::forward<_Tp>(_args)...) {}
3328
3329 template <Tag _tag, typename... _Tp>
3330 static Foo make(_Tp&&... _args) {
3331 return Foo(std::in_place_index<_tag>, std::forward<_Tp>(_args)...);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003332 }
Jooyung Han97945de2020-10-15 16:41:38 +09003333
3334 template <Tag _tag, typename _Tp, typename... _Up>
3335 static Foo make(std::initializer_list<_Tp> _il, _Up&&... _args) {
3336 return Foo(std::in_place_index<_tag>, std::move(_il), std::forward<_Up>(_args)...);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003337 }
3338
3339 Tag getTag() const {
Jooyung Han97945de2020-10-15 16:41:38 +09003340 return static_cast<Tag>(_value.index());
Jooyung Han1f14ab32020-10-14 13:48:29 +09003341 }
3342
Jooyung Han97945de2020-10-15 16:41:38 +09003343 template <Tag _tag>
Jooyung Han1f14ab32020-10-14 13:48:29 +09003344 const auto& get() const {
Jooyung Handf39e192020-11-23 15:59:46 +09003345 if (getTag() != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }
Jooyung Han97945de2020-10-15 16:41:38 +09003346 return std::get<_tag>(_value);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003347 }
3348
Jooyung Han97945de2020-10-15 16:41:38 +09003349 template <Tag _tag>
Jooyung Han1f14ab32020-10-14 13:48:29 +09003350 auto& get() {
Jooyung Handf39e192020-11-23 15:59:46 +09003351 if (getTag() != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }
Jooyung Han97945de2020-10-15 16:41:38 +09003352 return std::get<_tag>(_value);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003353 }
3354
Jooyung Han97945de2020-10-15 16:41:38 +09003355 template <Tag _tag, typename... _Tp>
3356 void set(_Tp&&... _args) {
3357 _value.emplace<_tag>(std::forward<_Tp>(_args)...);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003358 }
3359
3360 ::android::status_t readFromParcel(const ::android::Parcel* _aidl_parcel) override final;
3361 ::android::status_t writeToParcel(::android::Parcel* _aidl_parcel) const override final;
3362 static const std::string& getParcelableDescriptor() {
3363 static const std::string DESCIPTOR = "a.Foo";
3364 return DESCIPTOR;
3365 }
Jooyung Hanb8e01b92020-11-01 16:49:13 +09003366 template <typename _T> class _has_toString {
3367 template <typename _U> static std::true_type __has_toString(decltype(&_U::toString));
3368 template <typename _U> static std::false_type __has_toString(...);
3369 public: enum { value = decltype(__has_toString<_T>(nullptr))::value };
3370 };
3371 template <typename _T> inline static std::string _call_toString(const _T& t) {
3372 if constexpr (_has_toString<_T>::value) return t.toString();
3373 return "{no toString() implemented}";
3374 }
Jooyung Han74b1dd42020-11-01 22:17:16 +09003375 inline std::string toString() const {
3376 std::ostringstream os;
3377 os << "Foo{";
3378 switch (getTag()) {
3379 case ns: os << "ns: " << [&](){ std::ostringstream o; o << "["; bool first = true; for (const auto& v: get<ns>()) { (void)v; if (first) first = false; else o << ", "; o << std::to_string(v); }; o << "]"; return o.str(); }(); break;
3380 case e: os << "e: " << a::toString(get<e>()); break;
3381 case pfd: os << "pfd: " << ""; break;
3382 }
3383 os << "}";
3384 return os.str();
3385 }
Jooyung Han1f14ab32020-10-14 13:48:29 +09003386private:
Jooyung Hand2fa0232020-10-19 02:51:41 +09003387 std::variant<::std::vector<int32_t>, ::a::ByteEnum, ::android::os::ParcelFileDescriptor> _value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003388}; // class Foo
3389
3390} // namespace a
3391)";
3392
3393const char kUnionExampleExpectedOutputCppSource[] = R"(#include <a/Foo.h>
3394
3395namespace a {
3396
3397::android::status_t Foo::readFromParcel(const ::android::Parcel* _aidl_parcel) {
3398 ::android::status_t _aidl_ret_status;
3399 int32_t _aidl_tag;
3400 if ((_aidl_ret_status = _aidl_parcel->readInt32(&_aidl_tag)) != ::android::OK) return _aidl_ret_status;
3401 switch (_aidl_tag) {
3402 case ns: {
3403 ::std::vector<int32_t> _aidl_value;
3404 if ((_aidl_ret_status = _aidl_parcel->readInt32Vector(&_aidl_value)) != ::android::OK) return _aidl_ret_status;
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003405 if constexpr (std::is_trivially_copyable_v<::std::vector<int32_t>>) {
3406 set<ns>(_aidl_value);
3407 } else {
3408 // NOLINTNEXTLINE(performance-move-const-arg)
3409 set<ns>(std::move(_aidl_value));
3410 }
Jooyung Han1f14ab32020-10-14 13:48:29 +09003411 return ::android::OK; }
3412 case e: {
3413 ::a::ByteEnum _aidl_value;
3414 if ((_aidl_ret_status = _aidl_parcel->readByte(reinterpret_cast<int8_t *>(&_aidl_value))) != ::android::OK) return _aidl_ret_status;
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003415 if constexpr (std::is_trivially_copyable_v<::a::ByteEnum>) {
3416 set<e>(_aidl_value);
3417 } else {
3418 // NOLINTNEXTLINE(performance-move-const-arg)
3419 set<e>(std::move(_aidl_value));
3420 }
Jooyung Han1f14ab32020-10-14 13:48:29 +09003421 return ::android::OK; }
Jooyung Hand2fa0232020-10-19 02:51:41 +09003422 case pfd: {
3423 ::android::os::ParcelFileDescriptor _aidl_value;
3424 if ((_aidl_ret_status = _aidl_parcel->readParcelable(&_aidl_value)) != ::android::OK) return _aidl_ret_status;
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003425 if constexpr (std::is_trivially_copyable_v<::android::os::ParcelFileDescriptor>) {
3426 set<pfd>(_aidl_value);
3427 } else {
3428 // NOLINTNEXTLINE(performance-move-const-arg)
3429 set<pfd>(std::move(_aidl_value));
3430 }
Jooyung Hand2fa0232020-10-19 02:51:41 +09003431 return ::android::OK; }
Jooyung Han1f14ab32020-10-14 13:48:29 +09003432 }
3433 return ::android::BAD_VALUE;
3434}
3435
3436::android::status_t Foo::writeToParcel(::android::Parcel* _aidl_parcel) const {
3437 ::android::status_t _aidl_ret_status = _aidl_parcel->writeInt32(getTag());
3438 if (_aidl_ret_status != ::android::OK) return _aidl_ret_status;
3439 switch (getTag()) {
3440 case ns: return _aidl_parcel->writeInt32Vector(get<ns>());
3441 case e: return _aidl_parcel->writeByte(static_cast<int8_t>(get<e>()));
Jooyung Hand2fa0232020-10-19 02:51:41 +09003442 case pfd: return _aidl_parcel->writeParcelable(get<pfd>());
Jooyung Han1f14ab32020-10-14 13:48:29 +09003443 }
Jooyung Handf39e192020-11-23 15:59:46 +09003444 __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "can't reach here");
Jooyung Han1f14ab32020-10-14 13:48:29 +09003445}
3446
3447} // namespace a
3448)";
3449
Jooyung Han6beac042020-10-17 21:59:43 +09003450const char kUnionExampleExpectedOutputNdkHeader[] = R"(#pragma once
3451#include <android/binder_interface_utils.h>
3452#include <android/binder_parcelable_utils.h>
Jooyung Han74b1dd42020-11-01 22:17:16 +09003453#include <codecvt>
3454#include <locale>
3455#include <sstream>
Jooyung Han6beac042020-10-17 21:59:43 +09003456
Jooyung Handf39e192020-11-23 15:59:46 +09003457#include <cassert>
Jooyung Han6beac042020-10-17 21:59:43 +09003458#include <type_traits>
3459#include <utility>
3460#include <variant>
3461#include <cstdint>
3462#include <memory>
3463#include <optional>
3464#include <string>
3465#include <vector>
3466#ifdef BINDER_STABILITY_SUPPORT
3467#include <android/binder_stability.h>
3468#endif // BINDER_STABILITY_SUPPORT
3469#include <aidl/a/ByteEnum.h>
Jooyung Handf39e192020-11-23 15:59:46 +09003470
3471#ifndef __BIONIC__
3472#define __assert2(a,b,c,d) ((void)0)
3473#endif
3474
Jooyung Han6beac042020-10-17 21:59:43 +09003475namespace aidl {
3476namespace a {
3477class Foo {
3478public:
3479 typedef std::false_type fixed_size;
3480 static const char* descriptor;
3481
3482 enum Tag : int32_t {
3483 ns = 0, // int[] ns;
3484 e, // a.ByteEnum e;
Jooyung Hand2fa0232020-10-19 02:51:41 +09003485 pfd, // ParcelFileDescriptor pfd;
Jooyung Han6beac042020-10-17 21:59:43 +09003486 };
3487
3488 template<typename _Tp>
3489 static constexpr bool _not_self = !std::is_same_v<std::remove_cv_t<std::remove_reference_t<_Tp>>, Foo>;
3490
3491 Foo() : _value(std::in_place_index<ns>, std::vector<int32_t>({42})) { }
3492 Foo(const Foo&) = default;
3493 Foo(Foo&&) = default;
3494 Foo& operator=(const Foo&) = default;
3495 Foo& operator=(Foo&&) = default;
3496
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003497 template <typename _Tp, typename = std::enable_if_t<_not_self<_Tp>>>
3498 // NOLINTNEXTLINE(google-explicit-constructor)
Jooyung Han6beac042020-10-17 21:59:43 +09003499 constexpr Foo(_Tp&& _arg)
3500 : _value(std::forward<_Tp>(_arg)) {}
3501
3502 template <typename... _Tp>
3503 constexpr explicit Foo(_Tp&&... _args)
3504 : _value(std::forward<_Tp>(_args)...) {}
3505
3506 template <Tag _tag, typename... _Tp>
3507 static Foo make(_Tp&&... _args) {
3508 return Foo(std::in_place_index<_tag>, std::forward<_Tp>(_args)...);
3509 }
3510
3511 template <Tag _tag, typename _Tp, typename... _Up>
3512 static Foo make(std::initializer_list<_Tp> _il, _Up&&... _args) {
3513 return Foo(std::in_place_index<_tag>, std::move(_il), std::forward<_Up>(_args)...);
3514 }
3515
3516 Tag getTag() const {
3517 return static_cast<Tag>(_value.index());
3518 }
3519
3520 template <Tag _tag>
3521 const auto& get() const {
Jooyung Handf39e192020-11-23 15:59:46 +09003522 if (getTag() != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }
Jooyung Han6beac042020-10-17 21:59:43 +09003523 return std::get<_tag>(_value);
3524 }
3525
3526 template <Tag _tag>
3527 auto& get() {
Jooyung Handf39e192020-11-23 15:59:46 +09003528 if (getTag() != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }
Jooyung Han6beac042020-10-17 21:59:43 +09003529 return std::get<_tag>(_value);
3530 }
3531
3532 template <Tag _tag, typename... _Tp>
3533 void set(_Tp&&... _args) {
3534 _value.emplace<_tag>(std::forward<_Tp>(_args)...);
3535 }
3536
3537 binder_status_t readFromParcel(const AParcel* _parcel);
3538 binder_status_t writeToParcel(AParcel* _parcel) const;
Steven Morelandf58804a2020-12-07 18:12:15 +00003539
3540 inline bool operator!=(const Foo& rhs) const {
3541 return _value != rhs._value;
3542 }
3543 inline bool operator<(const Foo& rhs) const {
3544 return _value < rhs._value;
3545 }
3546 inline bool operator<=(const Foo& rhs) const {
3547 return _value <= rhs._value;
3548 }
3549 inline bool operator==(const Foo& rhs) const {
3550 return _value == rhs._value;
3551 }
3552 inline bool operator>(const Foo& rhs) const {
3553 return _value > rhs._value;
3554 }
3555 inline bool operator>=(const Foo& rhs) const {
3556 return _value >= rhs._value;
3557 }
3558
Jooyung Han6beac042020-10-17 21:59:43 +09003559 static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::STABILITY_LOCAL;
Jooyung Hanb8e01b92020-11-01 16:49:13 +09003560 template <typename _T> class _has_toString {
3561 template <typename _U> static std::true_type __has_toString(decltype(&_U::toString));
3562 template <typename _U> static std::false_type __has_toString(...);
3563 public: enum { value = decltype(__has_toString<_T>(nullptr))::value };
3564 };
3565 template <typename _T> inline static std::string _call_toString(const _T& t) {
3566 if constexpr (_has_toString<_T>::value) return t.toString();
3567 return "{no toString() implemented}";
3568 }
Jooyung Han74b1dd42020-11-01 22:17:16 +09003569 inline std::string toString() const {
3570 std::ostringstream os;
3571 os << "Foo{";
3572 switch (getTag()) {
3573 case ns: os << "ns: " << [&](){ std::ostringstream o; o << "["; bool first = true; for (const auto& v: get<ns>()) { (void)v; if (first) first = false; else o << ", "; o << std::to_string(v); }; o << "]"; return o.str(); }(); break;
3574 case e: os << "e: " << a::toString(get<e>()); break;
3575 case pfd: os << "pfd: " << ""; break;
3576 }
3577 os << "}";
3578 return os.str();
3579 }
Jooyung Han6beac042020-10-17 21:59:43 +09003580private:
Jooyung Hand2fa0232020-10-19 02:51:41 +09003581 std::variant<std::vector<int32_t>, ::aidl::a::ByteEnum, ::ndk::ScopedFileDescriptor> _value;
Jooyung Han6beac042020-10-17 21:59:43 +09003582};
3583} // namespace a
3584} // namespace aidl
3585)";
3586
3587const char kUnionExampleExpectedOutputNdkSource[] = R"(#include "aidl/a/Foo.h"
3588
3589#include <android/binder_parcel_utils.h>
3590
3591namespace aidl {
3592namespace a {
3593const char* Foo::descriptor = "a.Foo";
3594
3595binder_status_t Foo::readFromParcel(const AParcel* _parcel) {
3596 binder_status_t _aidl_ret_status;
3597 int32_t _aidl_tag;
3598 if ((_aidl_ret_status = AParcel_readInt32(_parcel, &_aidl_tag)) != STATUS_OK) return _aidl_ret_status;
3599 switch (_aidl_tag) {
3600 case ns: {
3601 std::vector<int32_t> _aidl_value;
3602 if ((_aidl_ret_status = ::ndk::AParcel_readVector(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status;
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003603 if constexpr (std::is_trivially_copyable_v<std::vector<int32_t>>) {
3604 set<ns>(_aidl_value);
3605 } else {
3606 // NOLINTNEXTLINE(performance-move-const-arg)
3607 set<ns>(std::move(_aidl_value));
3608 }
Jooyung Han6beac042020-10-17 21:59:43 +09003609 return STATUS_OK; }
3610 case e: {
3611 ::aidl::a::ByteEnum _aidl_value;
3612 if ((_aidl_ret_status = AParcel_readByte(_parcel, reinterpret_cast<int8_t*>(&_aidl_value))) != STATUS_OK) return _aidl_ret_status;
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003613 if constexpr (std::is_trivially_copyable_v<::aidl::a::ByteEnum>) {
3614 set<e>(_aidl_value);
3615 } else {
3616 // NOLINTNEXTLINE(performance-move-const-arg)
3617 set<e>(std::move(_aidl_value));
3618 }
Jooyung Han6beac042020-10-17 21:59:43 +09003619 return STATUS_OK; }
Jooyung Hand2fa0232020-10-19 02:51:41 +09003620 case pfd: {
3621 ::ndk::ScopedFileDescriptor _aidl_value;
3622 if ((_aidl_ret_status = ::ndk::AParcel_readRequiredParcelFileDescriptor(_parcel, &_aidl_value)) != STATUS_OK) return _aidl_ret_status;
Jiyong Parkdd57f1a2020-11-16 20:19:55 +09003623 if constexpr (std::is_trivially_copyable_v<::ndk::ScopedFileDescriptor>) {
3624 set<pfd>(_aidl_value);
3625 } else {
3626 // NOLINTNEXTLINE(performance-move-const-arg)
3627 set<pfd>(std::move(_aidl_value));
3628 }
Jooyung Hand2fa0232020-10-19 02:51:41 +09003629 return STATUS_OK; }
Jooyung Han6beac042020-10-17 21:59:43 +09003630 }
3631 return STATUS_BAD_VALUE;
3632}
3633binder_status_t Foo::writeToParcel(AParcel* _parcel) const {
3634 binder_status_t _aidl_ret_status = AParcel_writeInt32(_parcel, getTag());
3635 if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status;
3636 switch (getTag()) {
3637 case ns: return ::ndk::AParcel_writeVector(_parcel, get<ns>());
3638 case e: return AParcel_writeByte(_parcel, static_cast<int8_t>(get<e>()));
Jooyung Hand2fa0232020-10-19 02:51:41 +09003639 case pfd: return ::ndk::AParcel_writeRequiredParcelFileDescriptor(_parcel, get<pfd>());
Jooyung Han6beac042020-10-17 21:59:43 +09003640 }
Jooyung Handf39e192020-11-23 15:59:46 +09003641 __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "can't reach here");
Jooyung Han6beac042020-10-17 21:59:43 +09003642}
3643
3644} // namespace a
3645} // namespace aidl
3646)";
3647
Jooyung Han1f14ab32020-10-14 13:48:29 +09003648const char kUnionExampleExpectedOutputJava[] = R"(/*
3649 * This file is auto-generated. DO NOT MODIFY.
3650 */
3651package a;
3652
3653
3654public final class Foo implements android.os.Parcelable {
Jooyung Han97945de2020-10-15 16:41:38 +09003655 // tags for union fields
3656 public final static int ns = 0; // int[] ns;
3657 public final static int e = 1; // a.ByteEnum e;
Jooyung Hand2fa0232020-10-19 02:51:41 +09003658 public final static int pfd = 2; // ParcelFileDescriptor pfd;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003659
3660 private int _tag;
3661 private Object _value;
3662
3663 public Foo() {
Jooyung Hance62f932020-10-25 10:21:49 +09003664 int[] _value = {42};
3665 this._tag = ns;
3666 this._value = _value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003667 }
Jooyung Han97945de2020-10-15 16:41:38 +09003668
Jooyung Han1f14ab32020-10-14 13:48:29 +09003669 private Foo(android.os.Parcel _aidl_parcel) {
3670 readFromParcel(_aidl_parcel);
3671 }
Jooyung Han97945de2020-10-15 16:41:38 +09003672
Jooyung Hance62f932020-10-25 10:21:49 +09003673 private Foo(int _tag, Object _value) {
3674 this._tag = _tag;
3675 this._value = _value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003676 }
3677
3678 public int getTag() {
3679 return _tag;
3680 }
3681
Jooyung Han97945de2020-10-15 16:41:38 +09003682 // int[] ns;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003683
3684 public static Foo ns(int[] _value) {
3685 return new Foo(ns, _value);
3686 }
Jooyung Han97945de2020-10-15 16:41:38 +09003687
Jooyung Han1f14ab32020-10-14 13:48:29 +09003688 public int[] getNs() {
3689 _assertTag(ns);
3690 return (int[]) _value;
3691 }
Jooyung Han97945de2020-10-15 16:41:38 +09003692
Jooyung Han1f14ab32020-10-14 13:48:29 +09003693 public void setNs(int[] _value) {
3694 _set(ns, _value);
3695 }
3696
Jooyung Han97945de2020-10-15 16:41:38 +09003697 // a.ByteEnum e;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003698
3699 public static Foo e(byte _value) {
3700 return new Foo(e, _value);
3701 }
Jooyung Han97945de2020-10-15 16:41:38 +09003702
Jooyung Han1f14ab32020-10-14 13:48:29 +09003703 public byte getE() {
3704 _assertTag(e);
3705 return (byte) _value;
3706 }
Jooyung Han97945de2020-10-15 16:41:38 +09003707
Jooyung Han1f14ab32020-10-14 13:48:29 +09003708 public void setE(byte _value) {
3709 _set(e, _value);
3710 }
3711
Jooyung Hand2fa0232020-10-19 02:51:41 +09003712 // ParcelFileDescriptor pfd;
3713
3714 public static Foo pfd(android.os.ParcelFileDescriptor _value) {
3715 return new Foo(pfd, _value);
3716 }
3717
3718 public android.os.ParcelFileDescriptor getPfd() {
3719 _assertTag(pfd);
3720 return (android.os.ParcelFileDescriptor) _value;
3721 }
3722
3723 public void setPfd(android.os.ParcelFileDescriptor _value) {
3724 _set(pfd, _value);
3725 }
3726
Jooyung Han1f14ab32020-10-14 13:48:29 +09003727 public static final android.os.Parcelable.Creator<Foo> CREATOR = new android.os.Parcelable.Creator<Foo>() {
3728 @Override
3729 public Foo createFromParcel(android.os.Parcel _aidl_source) {
Jooyung Han97945de2020-10-15 16:41:38 +09003730 return new Foo(_aidl_source);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003731 }
3732 @Override
3733 public Foo[] newArray(int _aidl_size) {
3734 return new Foo[_aidl_size];
3735 }
3736 };
Jooyung Han97945de2020-10-15 16:41:38 +09003737
Jooyung Han1f14ab32020-10-14 13:48:29 +09003738 @Override
3739 public final void writeToParcel(android.os.Parcel _aidl_parcel, int _aidl_flag) {
3740 _aidl_parcel.writeInt(_tag);
3741 switch (_tag) {
3742 case ns:
3743 _aidl_parcel.writeIntArray(getNs());
3744 break;
3745 case e:
3746 _aidl_parcel.writeByte(getE());
3747 break;
Jooyung Hand2fa0232020-10-19 02:51:41 +09003748 case pfd:
3749 if ((getPfd()!=null)) {
3750 _aidl_parcel.writeInt(1);
3751 getPfd().writeToParcel(_aidl_parcel, 0);
3752 }
3753 else {
3754 _aidl_parcel.writeInt(0);
3755 }
3756 break;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003757 }
3758 }
Jooyung Han97945de2020-10-15 16:41:38 +09003759
Jooyung Han1f14ab32020-10-14 13:48:29 +09003760 public void readFromParcel(android.os.Parcel _aidl_parcel) {
3761 int _aidl_tag;
3762 _aidl_tag = _aidl_parcel.readInt();
3763 switch (_aidl_tag) {
3764 case ns: {
3765 int[] _aidl_value;
3766 _aidl_value = _aidl_parcel.createIntArray();
3767 _set(_aidl_tag, _aidl_value);
3768 return; }
3769 case e: {
3770 byte _aidl_value;
3771 _aidl_value = _aidl_parcel.readByte();
3772 _set(_aidl_tag, _aidl_value);
3773 return; }
Jooyung Hand2fa0232020-10-19 02:51:41 +09003774 case pfd: {
3775 android.os.ParcelFileDescriptor _aidl_value;
3776 if ((0!=_aidl_parcel.readInt())) {
3777 _aidl_value = android.os.ParcelFileDescriptor.CREATOR.createFromParcel(_aidl_parcel);
3778 }
3779 else {
3780 _aidl_value = null;
3781 }
3782 _set(_aidl_tag, _aidl_value);
3783 return; }
Jooyung Han1f14ab32020-10-14 13:48:29 +09003784 }
Jooyung Hanc453bea2020-11-21 01:00:22 +09003785 throw new IllegalArgumentException("union: unknown tag: " + _aidl_tag);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003786 }
Jooyung Han97945de2020-10-15 16:41:38 +09003787
Jooyung Han1f14ab32020-10-14 13:48:29 +09003788 @Override
3789 public int describeContents() {
Jooyung Hand2fa0232020-10-19 02:51:41 +09003790 int _mask = 0;
3791 switch (getTag()) {
3792 case pfd:
Jooyung Hanea2147c2020-10-21 18:16:56 +09003793 _mask |= describeContents(getPfd());
Jooyung Hand2fa0232020-10-19 02:51:41 +09003794 break;
3795 }
3796 return _mask;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003797 }
Jooyung Hanea2147c2020-10-21 18:16:56 +09003798 private int describeContents(Object _v) {
3799 if (_v == null) return 0;
3800 if (_v instanceof android.os.Parcelable) {
3801 return ((android.os.Parcelable) _v).describeContents();
3802 }
3803 return 0;
3804 }
Jooyung Han1f14ab32020-10-14 13:48:29 +09003805
3806 private void _assertTag(int tag) {
3807 if (getTag() != tag) {
Jooyung Hanef9b0f62020-10-14 21:52:55 +09003808 throw new IllegalStateException("bad access: " + _tagString(tag) + ", " + _tagString(getTag()) + " is available.");
Jooyung Han1f14ab32020-10-14 13:48:29 +09003809 }
3810 }
Jooyung Han97945de2020-10-15 16:41:38 +09003811
Jooyung Han1f14ab32020-10-14 13:48:29 +09003812 private String _tagString(int _tag) {
3813 switch (_tag) {
3814 case ns: return "ns";
3815 case e: return "e";
Jooyung Hand2fa0232020-10-19 02:51:41 +09003816 case pfd: return "pfd";
Jooyung Han1f14ab32020-10-14 13:48:29 +09003817 }
3818 throw new IllegalStateException("unknown field: " + _tag);
3819 }
Jooyung Han97945de2020-10-15 16:41:38 +09003820
Jooyung Hance62f932020-10-25 10:21:49 +09003821 private void _set(int _tag, Object _value) {
3822 this._tag = _tag;
3823 this._value = _value;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003824 }
3825}
3826)";
3827
Jooyung Hanf93b5bd2020-10-28 15:12:08 +09003828const char kUnionExampleExpectedOutputRust[] = R"(#[derive(Debug)]
3829pub enum Foo {
3830 Ns(Vec<i32>),
3831 E(crate::mangled::_1_a_8_ByteEnum),
3832 Pfd(Option<binder::parcel::ParcelFileDescriptor>),
3833}
3834pub(crate) mod mangled { pub use super::Foo as _1_a_3_Foo; }
3835impl Default for Foo {
3836 fn default() -> Self {
3837 Self::Ns(vec!{42})
3838 }
3839}
3840impl binder::parcel::Serialize for Foo {
3841 fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
3842 <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
3843 }
3844}
3845impl binder::parcel::SerializeArray for Foo {}
3846impl binder::parcel::SerializeOption for Foo {
3847 fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
3848 let this = if let Some(this) = this {
3849 parcel.write(&1i32)?;
3850 this
3851 } else {
3852 return parcel.write(&0i32);
3853 };
3854 match this {
3855 Self::Ns(v) => {
3856 parcel.write(&0i32)?;
3857 parcel.write(v)
3858 }
3859 Self::E(v) => {
3860 parcel.write(&1i32)?;
3861 parcel.write(v)
3862 }
3863 Self::Pfd(v) => {
3864 parcel.write(&2i32)?;
3865 let __field_ref = v.as_ref().ok_or(binder::StatusCode::UNEXPECTED_NULL)?;
3866 parcel.write(__field_ref)
3867 }
3868 }
3869 }
3870}
3871impl binder::parcel::Deserialize for Foo {
3872 fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
3873 <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
3874 .transpose()
3875 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
3876 }
3877}
3878impl binder::parcel::DeserializeArray for Foo {}
3879impl binder::parcel::DeserializeOption for Foo {
3880 fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
3881 let status: i32 = parcel.read()?;
3882 if status == 0 { return Ok(None); }
3883 let tag: i32 = parcel.read()?;
3884 match tag {
3885 0 => {
3886 let value: Vec<i32> = parcel.read()?;
3887 Ok(Some(Self::Ns(value)))
3888 }
3889 1 => {
3890 let value: crate::mangled::_1_a_8_ByteEnum = parcel.read()?;
3891 Ok(Some(Self::E(value)))
3892 }
3893 2 => {
3894 let value: Option<binder::parcel::ParcelFileDescriptor> = Some(parcel.read()?);
3895 Ok(Some(Self::Pfd(value)))
3896 }
3897 _ => {
3898 Err(binder::StatusCode::BAD_VALUE)
3899 }
3900 }
3901 }
3902}
3903)";
3904
Jooyung Han97945de2020-10-15 16:41:38 +09003905struct AidlUnionTest : ::testing::Test {
3906 void SetUp() override {
3907 io_delegate_.SetFileContents("a/Foo.aidl", R"(
Jooyung Han1f14ab32020-10-14 13:48:29 +09003908package a;
3909import a.ByteEnum;
3910union Foo {
3911 int[] ns = {42};
3912 ByteEnum e;
Jooyung Hand2fa0232020-10-19 02:51:41 +09003913 ParcelFileDescriptor pfd;
Jooyung Han1f14ab32020-10-14 13:48:29 +09003914}
3915)");
Jooyung Han97945de2020-10-15 16:41:38 +09003916 io_delegate_.SetFileContents("a/ByteEnum.aidl", R"(
Jooyung Han1f14ab32020-10-14 13:48:29 +09003917package a;
3918@Backing(type="byte")
3919enum ByteEnum {
3920 a, b, c
3921}
3922)");
Jooyung Han97945de2020-10-15 16:41:38 +09003923 }
3924 FakeIoDelegate io_delegate_;
3925 void Compile(string lang) {
3926 string command = "aidl --structured -I. -o out --lang=" + lang;
3927 if (lang == "cpp" || lang == "ndk") {
3928 command += " -h out";
3929 }
3930 command += " a/Foo.aidl";
3931 auto opts = Options::From(command);
Jooyung Han1f14ab32020-10-14 13:48:29 +09003932 CaptureStderr();
3933 auto ret = ::android::aidl::compile_aidl(opts, io_delegate_);
3934 auto err = GetCapturedStderr();
3935 EXPECT_EQ(0, ret) << err;
Jooyung Han97945de2020-10-15 16:41:38 +09003936 }
3937 void EXPECT_COMPILE_OUTPUTS(const map<string, string>& outputs) {
3938 for (const auto& [path, expected] : outputs) {
Jooyung Han1f14ab32020-10-14 13:48:29 +09003939 string actual;
3940 EXPECT_TRUE(io_delegate_.GetWrittenContents(path, &actual)) << path << " not found.";
3941 EXPECT_EQ(expected, actual);
3942 }
Jooyung Han97945de2020-10-15 16:41:38 +09003943 }
3944};
Jooyung Han1f14ab32020-10-14 13:48:29 +09003945
Jooyung Han97945de2020-10-15 16:41:38 +09003946TEST_F(AidlUnionTest, Example_Cpp) {
3947 Compile("cpp");
3948 EXPECT_COMPILE_OUTPUTS(
3949 map<string, string>({{"out/a/Foo.cpp", kUnionExampleExpectedOutputCppSource},
3950 {"out/a/Foo.h", kUnionExampleExpectedOutputCppHeader}}));
3951}
3952
Jooyung Han6beac042020-10-17 21:59:43 +09003953TEST_F(AidlUnionTest, Example_Ndk) {
3954 Compile("ndk");
3955 EXPECT_COMPILE_OUTPUTS(
3956 map<string, string>({{"out/a/Foo.cpp", kUnionExampleExpectedOutputNdkSource},
3957 {"out/aidl/a/Foo.h", kUnionExampleExpectedOutputNdkHeader}}));
3958}
3959
Jooyung Han97945de2020-10-15 16:41:38 +09003960TEST_F(AidlUnionTest, Example_Java) {
3961 Compile("java");
3962 EXPECT_COMPILE_OUTPUTS(
3963 map<string, string>({{"out/a/Foo.java", kUnionExampleExpectedOutputJava}}));
Jooyung Hanf93b5bd2020-10-28 15:12:08 +09003964}
3965
3966TEST_F(AidlUnionTest, Example_Rust) {
3967 Compile("rust");
3968 EXPECT_COMPILE_OUTPUTS(map<string, string>({{"out/a/Foo.rs", kUnionExampleExpectedOutputRust}}));
Jooyung Han1f14ab32020-10-14 13:48:29 +09003969}
3970
Jooyung Hanfe89f122020-10-14 03:49:18 +09003971TEST_P(AidlTest, UnionRejectsEmptyDecl) {
3972 const string method = "package a; union Foo {}";
3973 const string expected_stderr = "ERROR: a/Foo.aidl:1.17-21: The union 'Foo' has no fields.\n";
3974 CaptureStderr();
3975 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3976 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3977}
3978
3979TEST_P(AidlTest, UnionRejectsParcelableHolder) {
3980 const string method = "package a; union Foo { ParcelableHolder x; }";
3981 const string expected_stderr =
3982 "ERROR: a/Foo.aidl:1.40-42: A union can't have a member of ParcelableHolder 'x'\n";
3983 CaptureStderr();
3984 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3985 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3986}
3987
Jooyung Han53fb4242020-12-17 16:03:49 +09003988TEST_P(AidlTest, UnionRejectsFirstEnumWithNoDefaults) {
3989 import_paths_.insert(".");
3990 io_delegate_.SetFileContents("a/Enum.aidl", "package a; enum Enum { FOO, BAR }");
3991 const string expected_err = "The union's first member should have a useful default value.";
3992 CaptureStderr();
3993 EXPECT_EQ(nullptr,
3994 Parse("a/Foo.aidl", "package a; union Foo { a.Enum e; }", typenames_, GetLanguage()));
3995 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_err));
3996}
3997
Devin Moore53fc99c2020-08-12 08:07:52 -07003998TEST_P(AidlTest, GenericStructuredParcelable) {
3999 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T, U> { int a; int A; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004000 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Devin Moore53fc99c2020-08-12 08:07:52 -07004001 const string expected_stderr = "";
4002 CaptureStderr();
4003 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
4004 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4005}
4006
Jooyung Han3f347ca2020-12-01 12:41:50 +09004007TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
4008 io_delegate_.SetFileContents("Foo.aidl",
4009 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4010 Options options =
Jooyung Han9435e9a2021-01-06 10:16:31 +09004011 Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::CPP) + " -o out -h out");
Jooyung Han3f347ca2020-12-01 12:41:50 +09004012 const string expected_stderr = "";
4013 CaptureStderr();
4014 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
4015 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4016
4017 string code;
4018 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
4019 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4020const ::android::String16& Foo<T,U>::s() {
4021 static const ::android::String16 value(::android::String16(""));
4022 return value;
4023})--"));
4024}
4025
4026TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
4027 io_delegate_.SetFileContents("Foo.aidl",
4028 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4029 Options options =
Jooyung Han9435e9a2021-01-06 10:16:31 +09004030 Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::NDK) + " -o out -h out");
Jooyung Han3f347ca2020-12-01 12:41:50 +09004031 const string expected_stderr = "";
4032 CaptureStderr();
4033 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
4034 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4035
4036 string code;
4037 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
4038 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4039const char* Foo<T, U>::s = "";
4040)--"));
4041}
4042
Jooyung Han8c9a4e12020-10-26 15:39:54 +09004043TEST_F(AidlTest, NestedTypeArgs) {
4044 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
Steven Moreland6c07b832020-10-29 23:39:53 +00004045 io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");
4046
4047 io_delegate_.SetFileContents("a/Foo.aidl",
4048 "package a; import a.Bar; import a.Baz; parcelable Foo { "
4049 "Baz<Bar<Bar<String[]>>[], Bar<String>> barss; }");
Jooyung Han8c9a4e12020-10-26 15:39:54 +09004050 Options options = Options::From("aidl a/Foo.aidl -I . -o out --lang=java");
4051 const string expected_stderr = "";
4052 CaptureStderr();
4053 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
4054 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4055
4056 string code;
4057 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
Steven Moreland6c07b832020-10-29 23:39:53 +00004058 EXPECT_THAT(code,
4059 testing::HasSubstr(
4060 "a.Baz<a.Bar<a.Bar<java.lang.String[]>>[],a.Bar<java.lang.String>> barss;"));
4061}
4062
4063TEST_F(AidlTest, DoubleArrayError) {
4064 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][] a; }");
4065
4066 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4067 const string expected_stderr =
4068 "ERROR: a/Bar.aidl:1.28-37: Can only have one dimensional arrays.\n";
4069 CaptureStderr();
4070 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4071 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4072}
4073
4074TEST_F(AidlTest, DoubleGenericError) {
4075 io_delegate_.SetFileContents("a/Bar.aidl",
4076 "package a; parcelable Bar { List<String><String> a; }");
4077
4078 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4079 const string expected_stderr =
4080 "ERROR: a/Bar.aidl:1.28-33: Can only specify one set of type parameters.\n";
4081 CaptureStderr();
4082 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4083 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4084}
4085
4086TEST_F(AidlTest, ArrayBeforeGenericError) {
4087 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { List[]<String> a; }");
4088
4089 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4090 const string expected_stderr =
4091 "ERROR: a/Bar.aidl:1.28-33: Must specify type parameters (<>) before array ([]).\n";
4092 CaptureStderr();
4093 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4094 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jooyung Han8c9a4e12020-10-26 15:39:54 +09004095}
4096
Jooyung Han14004ed2020-10-16 03:49:57 +09004097struct GenericAidlTest : ::testing::Test {
4098 FakeIoDelegate io_delegate_;
4099 void Compile(string cmd) {
Steven Moreland6c07b832020-10-29 23:39:53 +00004100 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { Bar<Baz<Qux>> x; }");
Jooyung Han14004ed2020-10-16 03:49:57 +09004101 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar<T> { }");
4102 io_delegate_.SetFileContents("Baz.aidl", "parcelable Baz<T> { }");
4103 io_delegate_.SetFileContents("Qux.aidl", "parcelable Qux { }");
4104
4105 Options options = Options::From(cmd);
4106 CaptureStderr();
4107 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
4108 EXPECT_EQ("", GetCapturedStderr());
4109 }
4110};
4111
4112TEST_F(GenericAidlTest, ImportGenericParameterTypesCPP) {
4113 Compile("aidl Foo.aidl --lang=cpp -I . -o out -h out");
4114 string code;
4115 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
4116 EXPECT_THAT(code, testing::HasSubstr("#include <Bar.h>"));
4117 EXPECT_THAT(code, testing::HasSubstr("#include <Baz.h>"));
4118 EXPECT_THAT(code, testing::HasSubstr("#include <Qux.h>"));
4119}
4120
4121TEST_F(GenericAidlTest, ImportGenericParameterTypesNDK) {
4122 Compile("aidl Foo.aidl --lang=ndk -I . -o out -h out");
4123 string code;
4124 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
4125 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Bar.h>"));
4126 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Baz.h>"));
4127 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Qux.h>"));
4128}
4129
Devin Moore53fc99c2020-08-12 08:07:52 -07004130TEST_P(AidlTest, RejectGenericStructuredParcelabelRepeatedParam) {
4131 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { int a; int A; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004132 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Devin Moore53fc99c2020-08-12 08:07:52 -07004133 const string expected_stderr =
4134 "ERROR: Foo.aidl:1.11-15: Every type parameter should be unique.\n";
4135 CaptureStderr();
4136 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4137 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4138}
4139
4140TEST_P(AidlTest, RejectGenericStructuredParcelableField) {
4141 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { T a; int A; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004142 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Devin Moore53fc99c2020-08-12 08:07:52 -07004143 const string expected_stderr = "ERROR: Foo.aidl:1.22-24: Failed to resolve 'T'\n";
4144 CaptureStderr();
4145 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4146 EXPECT_EQ(expected_stderr, GetCapturedStderr());
4147}
4148
Jooyung Han7a308842020-10-27 19:06:49 +09004149TEST_P(AidlTest, LongCommentWithinConstExpression) {
4150 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { FOO = (1 << 1) /* comment */ | 0x0 }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004151 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jooyung Han7a308842020-10-27 19:06:49 +09004152 CaptureStderr();
4153 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
4154 EXPECT_EQ("", GetCapturedStderr());
4155}
4156
Jeongik Chaef44e622020-10-23 16:00:52 +09004157TEST_F(AidlTest, RejectUntypdeListAndMapInUnion) {
4158 io_delegate_.SetFileContents("a/Foo.aidl", "package a; union Foo { List l; Map m; }");
4159 Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
4160 std::string expectedErr =
4161 "ERROR: a/Foo.aidl:1.28-30: "
4162 "Encountered an untyped List or Map. The use of untyped List/Map is "
4163 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4164 "the receiving side. Consider switching to an array or a generic List/Map.\n"
4165 "ERROR: a/Foo.aidl:1.35-37: "
4166 "Encountered an untyped List or Map. The use of untyped List/Map is "
4167 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4168 "the receiving side. Consider switching to an array or a generic List/Map.\n";
4169 CaptureStderr();
4170 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4171 EXPECT_EQ(expectedErr, GetCapturedStderr());
4172}
4173
4174TEST_F(AidlTest, RejectUntypdeListAndMapInUnstructuredParcelable) {
Jooyung Hanea2147c2020-10-21 18:16:56 +09004175 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { List l; Map m; }");
4176 Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
Jeongik Chaef44e622020-10-23 16:00:52 +09004177 std::string expectedErr =
4178 "ERROR: a/Foo.aidl:1.33-35: "
4179 "Encountered an untyped List or Map. The use of untyped List/Map is "
4180 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4181 "the receiving side. Consider switching to an array or a generic List/Map.\n"
4182 "ERROR: a/Foo.aidl:1.40-42: "
4183 "Encountered an untyped List or Map. The use of untyped List/Map is "
4184 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4185 "the receiving side. Consider switching to an array or a generic List/Map.\n";
Jooyung Hanea2147c2020-10-21 18:16:56 +09004186 CaptureStderr();
Jeongik Chaef44e622020-10-23 16:00:52 +09004187 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4188 EXPECT_EQ(expectedErr, GetCapturedStderr());
4189}
Jooyung Hanea2147c2020-10-21 18:16:56 +09004190
Jeongik Chaef44e622020-10-23 16:00:52 +09004191TEST_F(AidlTest, RejectNestedUntypedListAndMap) {
4192 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<T>;");
4193 io_delegate_.SetFileContents(
4194 "a/Foo.aidl", "package a; import a.Bar; parcelable Foo { Bar<List> a; Bar<Map> b; }");
4195 Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
4196 std::string expectedErr =
4197 "ERROR: a/Foo.aidl:1.52-54: "
4198 "Encountered an untyped List or Map. The use of untyped List/Map is "
4199 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4200 "the receiving side. Consider switching to an array or a generic List/Map.\n"
4201 "ERROR: a/Foo.aidl:1.64-66: "
4202 "Encountered an untyped List or Map. The use of untyped List/Map is "
4203 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
4204 "the receiving side. Consider switching to an array or a generic List/Map.\n";
4205 CaptureStderr();
4206 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
4207 EXPECT_EQ(expectedErr, GetCapturedStderr());
Jooyung Hanea2147c2020-10-21 18:16:56 +09004208}
4209
Jooyung Han690f5842020-12-04 13:02:04 +09004210TEST_F(AidlTest, EnumWithDefaults_Java) {
4211 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
4212 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
4213package p;
4214import p.Enum;
4215parcelable Foo {
4216 Enum e = Enum.BAR;
4217})");
4218 CaptureStderr();
4219 auto options = Options::From("aidl -I a --lang java -o out a/p/Foo.aidl");
4220 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
4221 auto err = GetCapturedStderr();
4222 EXPECT_EQ("", err);
4223
4224 string code;
4225 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.java", &code));
Jooyung Han2d833612020-12-17 15:59:27 +09004226 EXPECT_THAT(code, testing::HasSubstr("byte e = p.Enum.BAR"));
Jooyung Han690f5842020-12-04 13:02:04 +09004227}
4228
4229TEST_F(AidlTest, EnumWithDefaults_Cpp) {
4230 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
4231 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
4232package p;
4233import p.Enum;
4234parcelable Foo {
4235 Enum e = Enum.BAR;
4236})");
4237 CaptureStderr();
4238 auto options = Options::From("aidl -I a --lang cpp -o out -h out a/p/Foo.aidl");
4239 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
4240 auto err = GetCapturedStderr();
4241 EXPECT_EQ("", err);
4242
4243 string code;
4244 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.h", &code));
4245 EXPECT_THAT(code, testing::HasSubstr("::p::Enum e = ::p::Enum(::p::Enum::BAR);"));
4246}
4247
4248TEST_F(AidlTest, EnumWithDefaults_Ndk) {
4249 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
4250 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
4251package p;
4252import p.Enum;
4253parcelable Foo {
4254 Enum e = Enum.BAR;
4255})");
4256 CaptureStderr();
4257 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
4258 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
4259 auto err = GetCapturedStderr();
4260 EXPECT_EQ("", err);
4261
4262 string code;
4263 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
4264 EXPECT_THAT(code, testing::HasSubstr("::aidl::p::Enum e = ::aidl::p::Enum::BAR;"));
4265}
4266
4267TEST_F(AidlTest, EnumWithDefaults_Rust) {
4268 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
4269 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
4270package p;
4271import p.Enum;
4272parcelable Foo {
4273 int n = 42;
4274 Enum e = Enum.BAR;
4275})");
4276 CaptureStderr();
4277 auto options = Options::From("aidl -I a --lang rust -o out -h out a/p/Foo.aidl");
4278 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
4279 auto err = GetCapturedStderr();
4280 EXPECT_EQ("", err);
4281
4282 string code;
4283 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.rs", &code));
4284 EXPECT_THAT(code, testing::HasSubstr(R"(
4285 fn default() -> Self {
4286 Self {
4287 n: 42,
4288 e: crate::mangled::_1_p_4_Enum::BAR,
4289 }
4290 })"));
4291}
4292
4293TEST_P(AidlTest, EnumeratorIsConstantValue_DefaultValue) {
4294 import_paths_.insert("a");
4295 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
4296 CaptureStderr();
4297 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
4298package p;
4299import p.Enum;
4300parcelable Foo {
4301 int e = Enum.FOO | Enum.BAR;
4302})",
4303 typenames_, GetLanguage());
4304 auto err = GetCapturedStderr();
4305 EXPECT_EQ("", err);
4306 EXPECT_TRUE(type);
4307 const auto& fields = type->AsStructuredParcelable()->GetFields();
4308 EXPECT_EQ("int e = 3", fields[0]->ToString());
4309}
4310
4311TEST_P(AidlTest, EnumeratorIsConstantValue_CanDefineOtherEnumerator) {
4312 CaptureStderr();
4313 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
4314@Backing(type="int")
4315enum Foo {
4316 STANDARD_SHIFT = 16,
4317 STANDARD_BT709 = 1 << STANDARD_SHIFT,
4318 STANDARD_BT601_625 = 2 << STANDARD_SHIFT,
4319}
4320)",
4321 typenames_, GetLanguage());
4322 auto err = GetCapturedStderr();
4323 EXPECT_EQ("", err);
4324 EXPECT_TRUE(type);
4325 const auto& enum_type = type->AsEnumDeclaration();
4326 string code;
4327 enum_type->Dump(CodeWriter::ForString(&code).get());
4328 EXPECT_EQ(R"--(@Backing(type="int")
4329enum Foo {
4330 STANDARD_SHIFT = 16,
4331 STANDARD_BT709 = 65536,
4332 STANDARD_BT601_625 = 131072,
4333}
4334)--",
4335 code);
4336}
4337
4338TEST_F(AidlTest, EnumDefaultShouldBeEnumerators) {
4339 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
4340 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
4341package p;
4342import p.Enum;
4343parcelable Foo {
4344 Enum e = Enum.FOO | Enum.BAR;
4345})");
4346 CaptureStderr();
4347 auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
4348 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
4349 auto err = GetCapturedStderr();
4350 EXPECT_EQ("ERROR: a/p/Foo.aidl:5.11-20: Invalid value (Enum.FOO|Enum.BAR) for enum p.Enum\n",
4351 err);
4352}
4353
4354TEST_P(AidlTest, DefaultWithEmptyArray) {
4355 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; parcelable Foo { p.Bar[] bars = {}; }");
4356 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; parcelable Bar { }");
4357 CaptureStderr();
Jooyung Han9435e9a2021-01-06 10:16:31 +09004358 auto options =
4359 Options::From("aidl -I a --lang " + to_string(GetLanguage()) + " -o out -h out a/p/Foo.aidl");
Jooyung Han690f5842020-12-04 13:02:04 +09004360 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
4361 auto err = GetCapturedStderr();
4362 EXPECT_EQ("", err);
4363}
4364
4365TEST_P(AidlTest, RejectRefsInAnnotation) {
4366 io_delegate_.SetFileContents("a/p/IFoo.aidl",
4367 "package p; interface IFoo {\n"
4368 " const String ANNOTATION = \"@Annotation\";\n"
4369 " @JavaPassthrough(annotation=ANNOTATION) void foo();\n"
4370 "}");
4371 CaptureStderr();
Jooyung Han9435e9a2021-01-06 10:16:31 +09004372 auto options =
4373 Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out a/p/IFoo.aidl");
Jooyung Han690f5842020-12-04 13:02:04 +09004374 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
4375 auto err = GetCapturedStderr();
4376 EXPECT_EQ(
4377 "ERROR: a/p/IFoo.aidl:3.31-41: Value must be a constant expression but contains reference to "
4378 "ANNOTATION.\n",
4379 err);
4380}
4381
4382TEST_F(AidlTest, DefaultWithEnumValues) {
4383 io_delegate_.SetFileContents(
4384 "a/p/Foo.aidl",
4385 "package p; import p.Bar; parcelable Foo { Bar[] bars = { Bar.FOO, Bar.FOO }; }");
4386 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; enum Bar { FOO, BAR }");
4387 CaptureStderr();
4388 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
4389 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
4390 auto err = GetCapturedStderr();
4391 EXPECT_EQ("", err);
4392 string code;
4393 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
4394 EXPECT_THAT(
4395 code, testing::HasSubstr(
4396 "std::vector<::aidl::p::Bar> bars = {::aidl::p::Bar::FOO, ::aidl::p::Bar::FOO};"));
4397}
4398
Jooyung Han14259392020-12-07 10:00:08 +09004399TEST_F(AidlTest, RejectsCircularReferencingEnumerators) {
4400 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; enum Foo { A = B, B }");
4401 CaptureStderr();
4402 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
4403 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
4404 auto err = GetCapturedStderr();
Jooyung Han29813842020-12-08 01:28:03 +09004405 EXPECT_EQ(
4406 "ERROR: a/p/Foo.aidl:1.26-28: Found a circular reference: B -> A -> B\n"
4407 "ERROR: a/p/Foo.aidl:1.29-31: Found a circular reference: A -> B -> A\n",
4408 err);
Jooyung Han14259392020-12-07 10:00:08 +09004409}
4410
4411TEST_F(AidlTest, RejectsCircularReferencingConsts) {
4412 io_delegate_.SetFileContents("a/p/Foo.aidl",
4413 "package p; parcelable Foo { const int A = A + 1; }");
4414 CaptureStderr();
4415 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
4416 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
4417 auto err = GetCapturedStderr();
Jooyung Han29813842020-12-08 01:28:03 +09004418 EXPECT_EQ("ERROR: a/p/Foo.aidl:1.42-44: Found a circular reference: A -> A\n", err);
4419}
4420
4421TEST_F(AidlTest, RecursiveReferences) {
4422 io_delegate_.SetFileContents("a/p/Foo.aidl",
4423 "package p; parcelable Foo { const int A = p.Bar.A + 1; }");
4424 io_delegate_.SetFileContents("a/p/Bar.aidl",
4425 "package p; parcelable Bar { const int A = p.Baz.A + 1; }");
4426 io_delegate_.SetFileContents("a/p/Baz.aidl", "package p; parcelable Baz { const int A = 1; }");
4427 CaptureStderr();
4428 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
4429 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
4430 EXPECT_EQ("", GetCapturedStderr());
4431}
4432
Jooyung Hane9f5b272021-01-07 00:18:11 +09004433TEST_P(AidlTest, UnknownConstReference) {
4434 io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { UnknownType field = UNKNOWN_REF; }");
4435 auto options =
4436 Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
4437 const string err =
4438 "ERROR: Foo.aidl:1.18-30: Failed to resolve 'UnknownType'\n"
4439 "ERROR: Foo.aidl:1.38-50: Can't find UNKNOWN_REF in Foo\n"
4440 "ERROR: Foo.aidl:1.38-50: Unknown reference 'UNKNOWN_REF'\n";
4441 CaptureStderr();
4442 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
4443 EXPECT_EQ(err, GetCapturedStderr());
4444}
4445
Jooyung Han29813842020-12-08 01:28:03 +09004446TEST_P(AidlTest, JavaCompatibleBuiltinTypes) {
4447 string contents = R"(
4448import android.os.IBinder;
4449import android.os.IInterface;
4450interface IFoo {}
4451 )";
4452 EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
Jooyung Han14259392020-12-07 10:00:08 +09004453}
4454
Jooyung Han888c5bc2020-12-22 17:28:47 +09004455TEST_P(AidlTest, WarningInterfaceName) {
4456 io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004457 auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
Jooyung Han888c5bc2020-12-22 17:28:47 +09004458 " -Weverything -o out -h out p/Foo.aidl");
4459 CaptureStderr();
4460 EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
Jooyung Han808a2a02020-12-28 16:46:54 +09004461 EXPECT_EQ("WARNING: p/Foo.aidl:1.1-10: Interface names should start with I. [-Winterface-name]\n",
Jooyung Han888c5bc2020-12-22 17:28:47 +09004462 GetCapturedStderr());
4463}
4464
4465TEST_P(AidlTest, ErrorInterfaceName) {
4466 io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004467 auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
Jooyung Han888c5bc2020-12-22 17:28:47 +09004468 " -Weverything -Werror -o out -h out p/Foo.aidl");
4469 CaptureStderr();
4470 EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
Jooyung Han808a2a02020-12-28 16:46:54 +09004471 EXPECT_EQ("ERROR: p/Foo.aidl:1.1-10: Interface names should start with I. [-Winterface-name]\n",
Jooyung Han3b990182020-12-22 17:44:31 +09004472 GetCapturedStderr());
4473}
4474
Jooyung Hanfd3be322020-12-13 09:11:06 +09004475struct TypeParam {
Jooyung Hane87cdd02020-12-11 16:47:35 +09004476 string kind;
4477 string literal;
4478};
4479
Jooyung Hanfd3be322020-12-13 09:11:06 +09004480const TypeParam kTypeParams[] = {
Jooyung Hane87cdd02020-12-11 16:47:35 +09004481 {"primitive", "int"}, {"String", "String"},
4482 {"IBinder", "IBinder"}, {"ParcelFileDescriptor", "ParcelFileDescriptor"},
4483 {"parcelable", "Foo"}, {"enum", "a.Enum"},
4484 {"union", "a.Union"}, {"interface", "a.IBar"},
4485};
4486
4487const std::map<std::string, std::string> kListSupportExpectations = {
4488 {"cpp_primitive", "A generic type cannot have any primitive type parameters."},
4489 {"java_primitive", "A generic type cannot have any primitive type parameters."},
4490 {"ndk_primitive", "A generic type cannot have any primitive type parameters."},
4491 {"rust_primitive", "A generic type cannot have any primitive type parameters."},
4492 {"cpp_String", ""},
4493 {"java_String", ""},
4494 {"ndk_String", ""},
4495 {"rust_String", ""},
4496 {"cpp_IBinder", ""},
4497 {"java_IBinder", ""},
4498 {"ndk_IBinder", "List<IBinder> is not supported. List in NDK doesn't support IBinder."},
4499 {"rust_IBinder", ""},
Jooyung Han55f96ad2020-12-13 10:08:33 +09004500 {"cpp_ParcelFileDescriptor", ""},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004501 {"java_ParcelFileDescriptor", ""},
4502 {"ndk_ParcelFileDescriptor", ""},
4503 {"rust_ParcelFileDescriptor", ""},
Jooyung Han55f96ad2020-12-13 10:08:33 +09004504 {"cpp_interface", "List<a.IBar> is not supported."},
4505 {"java_interface", "List<a.IBar> is not supported."},
4506 {"ndk_interface", "List<a.IBar> is not supported."},
4507 {"rust_interface", "List<a.IBar> is not supported."},
4508 {"cpp_parcelable", ""},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004509 {"java_parcelable", ""},
4510 {"ndk_parcelable", ""},
4511 {"rust_parcelable", ""},
4512 {"cpp_enum", "A generic type cannot have any primitive type parameters."},
4513 {"java_enum", "A generic type cannot have any primitive type parameters."},
4514 {"ndk_enum", "A generic type cannot have any primitive type parameters."},
4515 {"rust_enum", "A generic type cannot have any primitive type parameters."},
Jooyung Han55f96ad2020-12-13 10:08:33 +09004516 {"cpp_union", ""},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004517 {"java_union", ""},
4518 {"ndk_union", ""},
4519 {"rust_union", ""},
4520};
4521
Jooyung Hand236e552020-12-13 09:21:27 +09004522const std::map<std::string, std::string> kArraySupportExpectations = {
4523 {"cpp_primitive", ""},
4524 {"java_primitive", ""},
4525 {"ndk_primitive", ""},
4526 {"rust_primitive", ""},
4527 {"cpp_String", ""},
4528 {"java_String", ""},
4529 {"ndk_String", ""},
4530 {"rust_String", ""},
4531 {"cpp_IBinder", ""},
4532 {"java_IBinder", ""},
4533 {"ndk_IBinder", "The ndk backend does not support array of IBinder"},
4534 {"rust_IBinder", "The rust backend does not support array of IBinder"},
4535 {"cpp_ParcelFileDescriptor", ""},
4536 {"java_ParcelFileDescriptor", ""},
4537 {"ndk_ParcelFileDescriptor", ""},
4538 {"rust_ParcelFileDescriptor", ""},
4539 {"cpp_interface", "Binder type cannot be an array"},
4540 {"java_interface", "Binder type cannot be an array"},
4541 {"ndk_interface", "Binder type cannot be an array"},
4542 {"rust_interface", "Binder type cannot be an array"},
4543 {"cpp_parcelable", ""},
4544 {"java_parcelable", ""},
4545 {"ndk_parcelable", ""},
4546 {"rust_parcelable", ""},
4547 {"cpp_enum", ""},
4548 {"java_enum", ""},
4549 {"ndk_enum", ""},
4550 {"rust_enum", ""},
4551 {"cpp_union", ""},
4552 {"java_union", ""},
4553 {"ndk_union", ""},
4554 {"rust_union", ""},
4555};
4556
Jooyung Hanfd3be322020-12-13 09:11:06 +09004557class AidlTypeParamTest : public testing::TestWithParam<std::tuple<Options::Language, TypeParam>> {
Jooyung Hane87cdd02020-12-11 16:47:35 +09004558 public:
Jooyung Hanfd3be322020-12-13 09:11:06 +09004559 void Run(const std::string& generic_type_decl,
4560 const std::map<std::string, std::string>& expectations) {
Jooyung Hane87cdd02020-12-11 16:47:35 +09004561 const auto& param = GetParam();
Jooyung Han9435e9a2021-01-06 10:16:31 +09004562 const auto& lang = to_string(std::get<0>(param));
Jooyung Hane87cdd02020-12-11 16:47:35 +09004563 const auto& kind = std::get<1>(param).kind;
4564
4565 FakeIoDelegate io;
4566 io.SetFileContents("a/IBar.aidl", "package a; interface IBar { }");
4567 io.SetFileContents("a/Enum.aidl", "package a; enum Enum { A }");
4568 io.SetFileContents("a/Union.aidl", "package a; union Union { int a; }");
Jooyung Hanfd3be322020-12-13 09:11:06 +09004569 std::string decl = fmt::format(generic_type_decl, std::get<1>(param).literal);
4570 io.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { " + decl + " f; }");
Jooyung Hane87cdd02020-12-11 16:47:35 +09004571
4572 const auto options =
4573 Options::From(fmt::format("aidl -I . --lang={} a/Foo.aidl -o out -h out", lang));
4574 CaptureStderr();
4575 compile_aidl(options, io);
Jooyung Hanfd3be322020-12-13 09:11:06 +09004576 auto it = expectations.find(lang + "_" + kind);
4577 EXPECT_TRUE(it != expectations.end());
Jooyung Hane87cdd02020-12-11 16:47:35 +09004578 const string err = GetCapturedStderr();
4579 if (it->second.empty()) {
4580 EXPECT_EQ("", err);
4581 } else {
4582 EXPECT_THAT(err, testing::HasSubstr(it->second));
4583 }
4584 }
4585};
4586
4587INSTANTIATE_TEST_SUITE_P(
Jooyung Hanfd3be322020-12-13 09:11:06 +09004588 AidlTestSuite, AidlTypeParamTest,
Jooyung Hane87cdd02020-12-11 16:47:35 +09004589 testing::Combine(testing::Values(Options::Language::CPP, Options::Language::JAVA,
4590 Options::Language::NDK, Options::Language::RUST),
Jooyung Hanfd3be322020-12-13 09:11:06 +09004591 testing::ValuesIn(kTypeParams)),
4592 [](const testing::TestParamInfo<std::tuple<Options::Language, TypeParam>>& info) {
Jooyung Han9435e9a2021-01-06 10:16:31 +09004593 return to_string(std::get<0>(info.param)) + "_" + std::get<1>(info.param).kind;
Jooyung Hane87cdd02020-12-11 16:47:35 +09004594 });
4595
Jooyung Hanfd3be322020-12-13 09:11:06 +09004596TEST_P(AidlTypeParamTest, ListSupportedTypes) {
4597 Run("List<{}>", kListSupportExpectations);
4598}
Jooyung Hane87cdd02020-12-11 16:47:35 +09004599
Jooyung Hand236e552020-12-13 09:21:27 +09004600TEST_P(AidlTypeParamTest, ArraySupportedTypes) {
4601 Run("{}[]", kArraySupportExpectations);
4602}
4603
Christopher Wiley90be4e32015-10-20 14:55:25 -07004604} // namespace aidl
4605} // namespace android