blob: 6484fd03749f0e2fc2595fe6ac81482e53c78327 [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"
Jooyung Han1f56b702021-02-11 13:16:15 +090031#include "aidl_dumpapi.h"
Christopher Wiley90be4e32015-10-20 14:55:25 -070032#include "aidl_language.h"
Steven Moreland860b1942018-08-16 14:59:28 -070033#include "aidl_to_cpp.h"
Jeongik Cha047c5ee2019-08-07 23:16:49 +090034#include "aidl_to_java.h"
Jooyung Han161bb0f2021-01-21 12:30:16 +090035#include "comments.h"
Jiyong Park2a7c92b2020-07-22 19:12:36 +090036#include "logging.h"
Jeongik Cha047c5ee2019-08-07 23:16:49 +090037#include "options.h"
Jooyung Han93f48f02021-06-05 00:11:16 +090038#include "parser.h"
39#include "preprocess.h"
Christopher Wiley90be4e32015-10-20 14:55:25 -070040#include "tests/fake_io_delegate.h"
Christopher Wiley90be4e32015-10-20 14:55:25 -070041
42using android::aidl::test::FakeIoDelegate;
Christopher Wileyec31a052016-01-25 07:28:51 -080043using android::base::StringPrintf;
Jooyung Han1f14ab32020-10-14 13:48:29 +090044using std::map;
Christopher Wiley12e894a2016-01-29 11:55:07 -080045using std::set;
Christopher Wiley90be4e32015-10-20 14:55:25 -070046using std::string;
47using std::unique_ptr;
Christopher Wiley12e894a2016-01-29 11:55:07 -080048using std::vector;
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +090049using testing::HasSubstr;
Devin Moore7b8d5c92020-03-17 14:14:08 -070050using testing::TestParamInfo;
Jeongik Cha2a5b4d82019-08-06 19:37:59 +090051using testing::internal::CaptureStderr;
52using testing::internal::GetCapturedStderr;
Christopher Wiley90be4e32015-10-20 14:55:25 -070053
54namespace android {
55namespace aidl {
Christopher Wileyf8136192016-04-12 14:19:35 -070056namespace {
57
58const char kExpectedDepFileContents[] =
59R"(place/for/output/p/IFoo.java : \
60 p/IFoo.aidl
61
62p/IFoo.aidl :
63)";
64
Dan Willemsen93298ee2016-11-10 23:55:55 -080065const char kExpectedNinjaDepFileContents[] =
66R"(place/for/output/p/IFoo.java : \
67 p/IFoo.aidl
68)";
69
Jiyong Parkdf202122019-09-30 20:48:35 +090070const char kExpectedParcelableDeclarationDepFileContents[] =
71 R"( : \
72 p/Foo.aidl
73
74p/Foo.aidl :
75)";
76
77const char kExpectedStructuredParcelableDepFileContents[] =
Steven Moreland2a9a7d62019-02-05 16:11:54 -080078 R"(place/for/output/p/Foo.java : \
Christopher Wileyb1bbdf82016-04-21 11:43:45 -070079 p/Foo.aidl
80
81p/Foo.aidl :
82)";
83
Christopher Wileyf8136192016-04-12 14:19:35 -070084} // namespace
Christopher Wiley90be4e32015-10-20 14:55:25 -070085
Devin Moore7b8d5c92020-03-17 14:14:08 -070086class AidlTest : public ::testing::TestWithParam<Options::Language> {
Christopher Wiley90be4e32015-10-20 14:55:25 -070087 protected:
Jeongik Cha047c5ee2019-08-07 23:16:49 +090088 AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
89 Options::Language lang, AidlError* error = nullptr,
Steven Moreland1eac5fa2018-08-27 19:35:05 -070090 const vector<string> additional_arguments = {}) {
Christopher Wiley0522cd52015-10-28 15:39:44 -070091 io_delegate_.SetFileContents(path, contents);
Jiyong Parkfbbfa932018-07-30 21:44:10 +090092 vector<string> args;
Devin Moore7b8d5c92020-03-17 14:14:08 -070093 args.emplace_back("aidl");
Jooyung Han9435e9a2021-01-06 10:16:31 +090094 args.emplace_back("--lang=" + to_string(lang));
Steven Moreland1eac5fa2018-08-27 19:35:05 -070095 for (const string& s : additional_arguments) {
96 args.emplace_back(s);
97 }
98 for (const string& f : preprocessed_files_) {
Jiyong Parkfbbfa932018-07-30 21:44:10 +090099 args.emplace_back("--preprocessed=" + f);
100 }
Steven Moreland1eac5fa2018-08-27 19:35:05 -0700101 for (const string& i : import_paths_) {
Jiyong Parkfbbfa932018-07-30 21:44:10 +0900102 args.emplace_back("--include=" + i);
103 }
104 args.emplace_back(path);
105 Options options = Options::From(args);
Jiyong Parkb034bf02018-07-30 17:44:33 +0900106 vector<string> imported_files;
Jooyung Han6529b822021-06-11 22:05:26 +0900107 ImportResolver import_resolver{io_delegate_, path, import_paths_};
Christopher Wiley69b44cf2016-05-03 13:43:33 -0700108 AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900109 path, options, io_delegate_, &typenames_, &imported_files);
Jiyong Parkb034bf02018-07-30 17:44:33 +0900110
Christopher Wiley69b44cf2016-05-03 13:43:33 -0700111 if (error != nullptr) {
112 *error = actual_error;
113 }
Jiyong Parkb034bf02018-07-30 17:44:33 +0900114
115 if (actual_error != AidlError::OK) {
116 return nullptr;
117 }
118
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900119 const auto& defined_types = typenames_.MainDocument().DefinedTypes();
Jiyong Parkb034bf02018-07-30 17:44:33 +0900120 EXPECT_EQ(1ul, defined_types.size());
121
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900122 return defined_types.front().get();
Christopher Wiley90be4e32015-10-20 14:55:25 -0700123 }
Christopher Wiley0522cd52015-10-28 15:39:44 -0700124
Devin Moore7b8d5c92020-03-17 14:14:08 -0700125 Options::Language GetLanguage() { return GetParam(); }
126
Christopher Wiley0522cd52015-10-28 15:39:44 -0700127 FakeIoDelegate io_delegate_;
Christopher Wiley41544372015-11-03 14:52:29 -0800128 vector<string> preprocessed_files_;
Jiyong Park8c380532018-08-30 14:55:26 +0900129 set<string> import_paths_;
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900130 AidlTypenames typenames_;
Christopher Wiley90be4e32015-10-20 14:55:25 -0700131};
132
Devin Moore7b8d5c92020-03-17 14:14:08 -0700133// Instantiate the AidlTest parameterized suite, calling all of the TEST_P
134// tests with each of the supported languages as a parameter.
135INSTANTIATE_TEST_SUITE_P(AidlTestSuite, AidlTest,
136 testing::Values(Options::Language::CPP, Options::Language::JAVA,
Andrei Homescub62afd92020-05-11 19:24:59 -0700137 Options::Language::NDK, Options::Language::RUST),
Devin Moore7b8d5c92020-03-17 14:14:08 -0700138 [](const testing::TestParamInfo<Options::Language>& info) {
Jooyung Han9435e9a2021-01-06 10:16:31 +0900139 return to_string(info.param);
Devin Moore7b8d5c92020-03-17 14:14:08 -0700140 });
141
142TEST_P(AidlTest, AcceptMissingPackage) {
143 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, GetLanguage()));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700144}
145
Devin Moore7b8d5c92020-03-17 14:14:08 -0700146TEST_P(AidlTest, EndsInSingleLineComment) {
147 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, GetLanguage()));
Steven Moreland9c2988f2019-07-17 17:49:10 -0700148}
149
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000150TEST_P(AidlTest, InterfaceRequiresCorrectPath) {
151 const string expected_stderr =
152 "ERROR: a/Foo.aidl:1.11-21: IBar should be declared in a file called a/IBar.aidl\n";
153 const std::string file_contents = "package a; interface IBar {}";
154 CaptureStderr();
155 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
156 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
157}
158
159TEST_P(AidlTest, ParcelableRequiresCorrectPath) {
160 const string expected_stderr =
161 "ERROR: a/Foo.aidl:1.11-21: Bar should be declared in a file called a/Bar.aidl\n";
162 const std::string file_contents = "package a; interface Bar {}";
163 CaptureStderr();
164 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
165 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
166}
167
168TEST_P(AidlTest, UnstructuredParcelableRequiresCorrectPath) {
169 const string expected_stderr =
170 "ERROR: a/Foo.aidl:1.22-26: Bar should be declared in a file called a/Bar.aidl\n";
171 const std::string file_contents = "package a; parcelable Bar cpp_header \"anything.h\";";
172 CaptureStderr();
173 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
174 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
175}
176
177TEST_P(AidlTest, EnumRequiresCorrectPath) {
178 const string expected_stderr =
179 "ERROR: a/Foo.aidl:1.16-20: Bar should be declared in a file called a/Bar.aidl\n";
180 const std::string file_contents = "package a; enum Bar { A, }";
181 CaptureStderr();
182 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
183 EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
184}
185
Devin Moore7b8d5c92020-03-17 14:14:08 -0700186TEST_P(AidlTest, RejectsArraysOfBinders) {
Jiyong Park8c380532018-08-30 14:55:26 +0900187 import_paths_.emplace("");
Christopher Wiley0522cd52015-10-28 15:39:44 -0700188 io_delegate_.SetFileContents("bar/IBar.aidl",
189 "package bar; interface IBar {}");
Devin Moore097a3ab2020-03-11 16:08:44 -0700190 const string path = "foo/IFoo.aidl";
191 const string contents =
192 "package foo;\n"
193 "import bar.IBar;\n"
194 "interface IFoo { void f(in IBar[] input); }";
195 const string expected_stderr = "ERROR: foo/IFoo.aidl:3.27-32: Binder type cannot be an array\n";
196 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700197 EXPECT_EQ(nullptr, Parse(path, contents, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700198 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley0522cd52015-10-28 15:39:44 -0700199}
200
Devin Moore7b8d5c92020-03-17 14:14:08 -0700201TEST_P(AidlTest, SupportOnlyOutParameters) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700202 const string interface_list = "package a; interface IBar { void f(out List<String> bar); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700203 EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, GetLanguage()));
Jiyong Park40782d02020-07-24 19:17:43 +0900204}
Devin Moore097a3ab2020-03-11 16:08:44 -0700205
Jiyong Park40782d02020-07-24 19:17:43 +0900206TEST_P(AidlTest, RejectOutParametersForIBinder) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700207 const string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
208 const string expected_ibinder_stderr =
Jooyung Han15fd6c62020-10-23 13:54:46 +0900209 "ERROR: a/IBaz.aidl:1.47-51: 'bar' can't be an out parameter because IBinder can only be an "
210 "in parameter.\n";
Devin Moore097a3ab2020-03-11 16:08:44 -0700211 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700212 EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700213 EXPECT_EQ(expected_ibinder_stderr, GetCapturedStderr());
Jeongik Chaa2080bf2019-06-18 16:44:29 +0900214}
215
Jiyong Park40782d02020-07-24 19:17:43 +0900216TEST_P(AidlTest, RejectsOutParametersInOnewayInterface) {
Jooyung Han020d8d12021-02-26 17:23:02 +0900217 const string oneway_interface = "package a; oneway interface IBar { void f(out int[] bar); }";
Devin Moore097a3ab2020-03-11 16:08:44 -0700218 const string expected_stderr =
219 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700220 CaptureStderr();
221 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
222 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park40782d02020-07-24 19:17:43 +0900223}
Devin Moore7b8d5c92020-03-17 14:14:08 -0700224
Jiyong Park40782d02020-07-24 19:17:43 +0900225TEST_P(AidlTest, RejectsOutParametersInOnewayMethod) {
Jooyung Han020d8d12021-02-26 17:23:02 +0900226 const string oneway_method = "package a; interface IBar { oneway void f(out int[] bar); }";
Jiyong Park40782d02020-07-24 19:17:43 +0900227 const string expected_stderr =
228 "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
Devin Moore097a3ab2020-03-11 16:08:44 -0700229 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700230 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700231 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley90be4e32015-10-20 14:55:25 -0700232}
233
Devin Moore7b8d5c92020-03-17 14:14:08 -0700234TEST_P(AidlTest, RejectsOnewayNonVoidReturn) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700235 const string oneway_method = "package a; interface IFoo { oneway int f(); }";
236 const string expected_stderr =
237 "ERROR: a/IFoo.aidl:1.39-41: oneway method 'f' cannot return a value\n";
238 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700239 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700240 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley90be4e32015-10-20 14:55:25 -0700241}
242
Devin Moore7b8d5c92020-03-17 14:14:08 -0700243TEST_P(AidlTest, RejectsNullablePrimitive) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700244 const string oneway_method = "package a; interface IFoo { @nullable int f(); }";
245 const string expected_stderr =
246 "ERROR: a/IFoo.aidl:1.38-42: Primitive type cannot get nullable annotation\n";
247 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700248 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700249 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Casey Dahlin57dbe242015-12-04 11:44:02 -0800250}
251
Devin Moore2f2077a2020-08-28 11:27:53 -0700252TEST_P(AidlTest, AcceptNullableList) {
253 const string oneway_method = "package a; interface IFoo { @nullable List<String> f(); }";
254 const string expected_stderr = "";
255 CaptureStderr();
256 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
257 EXPECT_EQ(expected_stderr, GetCapturedStderr());
258}
259
Devin Moore7b8d5c92020-03-17 14:14:08 -0700260TEST_P(AidlTest, RejectsDuplicatedArgumentNames) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700261 const string method = "package a; interface IFoo { void f(int a, int a); }";
262 const string expected_stderr =
263 "ERROR: a/IFoo.aidl:1.33-35: method 'f' has duplicate argument name 'a'\n";
264 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700265 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700266 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelandb3cd3c72018-10-11 12:37:45 -0700267}
268
Jeongik Cha13066da2020-08-06 15:43:19 +0900269TEST_P(AidlTest, RejectsDuplicatedFieldNames) {
270 const string method = "package a; parcelable Foo { int a; String a; }";
Jooyung Han59af9cc2020-10-25 21:44:14 +0900271 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 +0900272 CaptureStderr();
273 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
274 EXPECT_EQ(expected_stderr, GetCapturedStderr());
275}
276
Jooyung Hand902a972020-10-23 17:32:44 +0900277TEST_P(AidlTest, RejectsRepeatedAnnotations) {
278 const string method = R"(@Hide @Hide parcelable Foo {})";
279 const string expected_stderr =
280 "ERROR: Foo.aidl:1.23-27: 'Hide' is repeated, but not allowed. Previous location: "
281 "Foo.aidl:1.1-6\n";
282 CaptureStderr();
283 EXPECT_EQ(nullptr, Parse("Foo.aidl", method, typenames_, GetLanguage()));
284 EXPECT_EQ(expected_stderr, GetCapturedStderr());
285}
286
Jooyung Han05bd8a82021-04-28 23:56:38 +0900287TEST_P(AidlTest, AcceptsEmptyParcelable) {
288 CaptureStderr();
289 EXPECT_NE(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage()));
290 EXPECT_EQ("", GetCapturedStderr());
291}
292
Devin Moore7b8d5c92020-03-17 14:14:08 -0700293TEST_P(AidlTest, RejectsDuplicatedAnnotationParams) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700294 const string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
295 const string expected_stderr = "ERROR: a/IFoo.aidl:1.56-62: Trying to redefine parameter foo.\n";
296 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700297 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -0700298 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Andrei Onea9445fc62019-06-27 18:11:59 +0100299}
300
Devin Moore7b8d5c92020-03-17 14:14:08 -0700301TEST_P(AidlTest, RejectUnsupportedInterfaceAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700302 AidlError error;
303 const string method = "package a; @nullable interface IFoo { int f(); }";
Devin Moorec054bf82020-03-10 16:31:48 -0700304 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700305 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900306 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
Devin Moorec054bf82020-03-10 16:31:48 -0700307 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800308}
309
Devin Moore7b8d5c92020-03-17 14:14:08 -0700310TEST_P(AidlTest, RejectUnsupportedTypeAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700311 AidlError error;
312 const string method = "package a; interface IFoo { @JavaOnlyStableParcelable int f(); }";
Devin Moorec054bf82020-03-10 16:31:48 -0700313 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700314 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900315 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaOnlyStableParcelable is not available."));
Devin Moorec054bf82020-03-10 16:31:48 -0700316 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800317}
318
Devin Moore7b8d5c92020-03-17 14:14:08 -0700319TEST_P(AidlTest, RejectUnsupportedParcelableAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700320 AidlError error;
321 const string method = "package a; @nullable parcelable IFoo cpp_header \"IFoo.h\";";
Devin Moorec054bf82020-03-10 16:31:48 -0700322 CaptureStderr();
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000323 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900324 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
Devin Moorec054bf82020-03-10 16:31:48 -0700325 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800326}
327
Devin Moore7b8d5c92020-03-17 14:14:08 -0700328TEST_P(AidlTest, RejectUnsupportedParcelableDefineAnnotations) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700329 AidlError error;
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000330 const string method = "package a; @nullable parcelable IFoo { String a; String b; }";
Devin Moorec054bf82020-03-10 16:31:48 -0700331 CaptureStderr();
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000332 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900333 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
Devin Moorec054bf82020-03-10 16:31:48 -0700334 EXPECT_EQ(AidlError::BAD_TYPE, error);
Devin Moore24f68572020-02-26 13:20:59 -0800335}
336
Jiyong Park40782d02020-07-24 19:17:43 +0900337TEST_P(AidlTest, ParsesNonNullableAnnotation) {
338 auto parse_result =
339 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
340 ASSERT_NE(nullptr, parse_result);
341 const AidlInterface* interface = parse_result->AsInterface();
342 ASSERT_NE(nullptr, interface);
343 ASSERT_FALSE(interface->GetMethods().empty());
344 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsNullable());
345}
346
Devin Moore7b8d5c92020-03-17 14:14:08 -0700347TEST_P(AidlTest, ParsesNullableAnnotation) {
Jiyong Park40782d02020-07-24 19:17:43 +0900348 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @nullable String f(); }",
349 typenames_, GetLanguage());
350 ASSERT_NE(nullptr, parse_result);
351 const AidlInterface* interface = parse_result->AsInterface();
352 ASSERT_NE(nullptr, interface);
353 ASSERT_FALSE(interface->GetMethods().empty());
354 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsNullable());
355}
356
357TEST_P(AidlTest, ParsesNonUtf8Annotations) {
358 auto parse_result =
359 Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
360 ASSERT_NE(nullptr, parse_result);
361 const AidlInterface* interface = parse_result->AsInterface();
362 ASSERT_NE(nullptr, interface);
363 ASSERT_FALSE(interface->GetMethods().empty());
364 EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
Christopher Wileyec31a052016-01-25 07:28:51 -0800365}
366
Devin Moore7b8d5c92020-03-17 14:14:08 -0700367TEST_P(AidlTest, ParsesUtf8Annotations) {
Jiyong Park40782d02020-07-24 19:17:43 +0900368 auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @utf8InCpp String f(); }",
369 typenames_, GetLanguage());
370 ASSERT_NE(nullptr, parse_result);
371 const AidlInterface* interface = parse_result->AsInterface();
372 ASSERT_NE(nullptr, interface);
373 ASSERT_FALSE(interface->GetMethods().empty());
374 EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
Christopher Wileyec31a052016-01-25 07:28:51 -0800375}
376
Devin Moore7b8d5c92020-03-17 14:14:08 -0700377TEST_P(AidlTest, VintfRequiresStructuredAndStability) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700378 AidlError error;
Devin Moore0d0e3f62020-03-30 17:45:39 -0700379 const string expected_stderr =
380 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
381 "\"vintf\"'\n"
382 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
383 "--structured\n";
384 CaptureStderr();
Devin Moore097a3ab2020-03-11 16:08:44 -0700385 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
Devin Moore7b8d5c92020-03-17 14:14:08 -0700386 GetLanguage(), &error));
Devin Moore0d0e3f62020-03-30 17:45:39 -0700387 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700388 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700389}
390
Devin Moore7b8d5c92020-03-17 14:14:08 -0700391TEST_P(AidlTest, VintfRequiresStructured) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700392 AidlError error;
Devin Moore0d0e3f62020-03-30 17:45:39 -0700393 const string expected_stderr =
394 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
395 "--structured\n";
396 CaptureStderr();
Devin Moore097a3ab2020-03-11 16:08:44 -0700397 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
Devin Moore7b8d5c92020-03-17 14:14:08 -0700398 GetLanguage(), &error, {"--stability", "vintf"}));
Devin Moore0d0e3f62020-03-30 17:45:39 -0700399 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700400 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700401}
402
Devin Moore7b8d5c92020-03-17 14:14:08 -0700403TEST_P(AidlTest, VintfRequiresSpecifiedStability) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700404 AidlError error;
Devin Moore097a3ab2020-03-11 16:08:44 -0700405 const string expected_stderr =
406 "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
407 "\"vintf\"'\n";
408 CaptureStderr();
409 ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
Devin Moore7b8d5c92020-03-17 14:14:08 -0700410 GetLanguage(), &error, {"--structured"}));
Devin Moore097a3ab2020-03-11 16:08:44 -0700411 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700412 ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700413}
414
Devin Moore7b8d5c92020-03-17 14:14:08 -0700415TEST_P(AidlTest, ParsesStabilityAnnotations) {
Steven Morelanda57d0a62019-07-30 09:41:14 -0700416 AidlError error;
Devin Moore7b8d5c92020-03-17 14:14:08 -0700417 auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
418 GetLanguage(), &error, {"--structured", "--stability", "vintf"});
Steven Morelanda57d0a62019-07-30 09:41:14 -0700419 ASSERT_EQ(AidlError::OK, error);
420 ASSERT_NE(nullptr, parse_result);
421 const AidlInterface* interface = parse_result->AsInterface();
422 ASSERT_NE(nullptr, interface);
423 ASSERT_TRUE(interface->IsVintfStability());
Steven Morelanda57d0a62019-07-30 09:41:14 -0700424}
425
Jeongik Cha64783ed2019-06-07 18:30:54 +0900426TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
427 Options java_options = Options::From("aidl -o out --structured a/Foo.aidl");
Jeongik Cha88f95a82020-01-15 13:02:16 +0900428 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out/include a/Foo.aidl");
429 Options cpp_structured_options =
Jeongik Cha64783ed2019-06-07 18:30:54 +0900430 Options::From("aidl --lang=cpp --structured -o out -h out/include a/Foo.aidl");
Andrei Homescub62afd92020-05-11 19:24:59 -0700431 Options rust_options = Options::From("aidl --lang=rust -o out --structured a/Foo.aidl");
Jeongik Cha64783ed2019-06-07 18:30:54 +0900432 io_delegate_.SetFileContents(
Jeongik Cha88f95a82020-01-15 13:02:16 +0900433 "a/Foo.aidl",
434 StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
Jeongik Cha64783ed2019-06-07 18:30:54 +0900435
Steven Moreland4e059132021-08-11 13:36:30 -0700436 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
437 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
Jooyung Han2cb8ecd2021-07-28 18:41:30 +0900438
Devin Moorec054bf82020-03-10 16:31:48 -0700439 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700440 EXPECT_FALSE(compile_aidl(cpp_structured_options, io_delegate_));
Jooyung Han2cb8ecd2021-07-28 18:41:30 +0900441 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
Andrei Homescub62afd92020-05-11 19:24:59 -0700442
443 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700444 EXPECT_FALSE(compile_aidl(rust_options, io_delegate_));
Jooyung Han2cb8ecd2021-07-28 18:41:30 +0900445 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
Jeongik Cha64783ed2019-06-07 18:30:54 +0900446}
447
Jooyung Han1cbc4962020-10-25 10:07:15 +0900448TEST_F(AidlTest, ParcelableSupportJavaDeriveToString) {
449 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
450 @JavaDerive(toString=true) parcelable Foo { int a; float b; })");
451 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -0700452 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
Jiyong Park43113fb2020-07-20 16:26:19 +0900453
454 string java_out;
Jooyung Han1cbc4962020-10-25 10:07:15 +0900455 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
Jiyong Park43113fb2020-07-20 16:26:19 +0900456 EXPECT_THAT(java_out, testing::HasSubstr("public String toString() {"));
457
458 // Other backends shouldn't be bothered
Jooyung Han1cbc4962020-10-25 10:07:15 +0900459 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -0700460 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
Jiyong Park43113fb2020-07-20 16:26:19 +0900461
Jooyung Han1cbc4962020-10-25 10:07:15 +0900462 Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -0700463 EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
Jiyong Park43113fb2020-07-20 16:26:19 +0900464}
465
Jooyung Han1cbc4962020-10-25 10:07:15 +0900466TEST_F(AidlTest, UnionSupportJavaDeriveToString) {
467 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
468 @JavaDerive(toString=true) union Foo { int a; int[] b; })");
469 CaptureStderr();
470 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -0700471 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
Jooyung Han1cbc4962020-10-25 10:07:15 +0900472 EXPECT_EQ("", GetCapturedStderr());
473
474 const string expected_to_string_method = R"--(
475 @Override
476 public String toString() {
477 switch (_tag) {
478 case a: return "a.Foo.a(" + (getA()) + ")";
479 case b: return "a.Foo.b(" + (java.util.Arrays.toString(getB())) + ")";
480 }
481 throw new IllegalStateException("unknown field: " + _tag);
482 }
483)--";
484
485 string java_out;
486 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
487 EXPECT_THAT(java_out, testing::HasSubstr(expected_to_string_method));
488}
489
Jiyong Park9aa3d042020-12-04 23:30:02 +0900490TEST_F(AidlTest, ParcelableSupportJavaDeriveEquals) {
491 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
492 @JavaDerive(equals=true) parcelable Foo { int a; float b; })");
493 CaptureStderr();
494 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -0700495 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
Jiyong Park9aa3d042020-12-04 23:30:02 +0900496 EXPECT_EQ("", GetCapturedStderr());
497
498 const std::string expected = R"--(
499 @Override
500 public boolean equals(Object other) {
501 if (this == other) return true;
502 if (other == null) return false;
503 if (!(other instanceof Foo)) return false;
504 Foo that = (Foo)other;
505 if (!java.util.Objects.deepEquals(a, that.a)) return false;
506 if (!java.util.Objects.deepEquals(b, that.b)) return false;
507 return true;
508 }
509
510 @Override
511 public int hashCode() {
512 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(a, b).toArray());
513 }
514)--";
515
516 string java_out;
517 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
518 EXPECT_THAT(java_out, testing::HasSubstr(expected));
519}
520
521TEST_F(AidlTest, UnionSupportJavaDeriveEquals) {
522 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
523 @JavaDerive(equals=true) union Foo { int a; int[] b; })");
524 CaptureStderr();
525 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -0700526 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
Jiyong Park9aa3d042020-12-04 23:30:02 +0900527 EXPECT_EQ("", GetCapturedStderr());
528
529 const std::string expected = R"--(
530 @Override
531 public boolean equals(Object other) {
532 if (this == other) return true;
533 if (other == null) return false;
534 if (!(other instanceof Foo)) return false;
535 Foo that = (Foo)other;
536 if (_tag != that._tag) return false;
537 if (!java.util.Objects.deepEquals(_value, that._value)) return false;
538 return true;
539 }
540
541 @Override
542 public int hashCode() {
543 return java.util.Arrays.deepHashCode(java.util.Arrays.asList(_tag, _value).toArray());
544 }
545)--";
546
547 string java_out;
548 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
549 EXPECT_THAT(java_out, testing::HasSubstr(expected));
550}
551
Jooyung Han90345002020-10-23 15:28:53 +0900552TEST_F(AidlTest, RejectsJavaDeriveAnnotation) {
Jiyong Park43113fb2020-07-20 16:26:19 +0900553 {
Jooyung Han90345002020-10-23 15:28:53 +0900554 io_delegate_.SetFileContents("a/Foo.aidl",
555 "package a; @JavaDerive(blah=true) parcelable Foo{}");
556 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
557 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700558 EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
Jooyung Han90345002020-10-23 15:28:53 +0900559 const std::string expected_stderr =
560 "ERROR: a/Foo.aidl:1.11-34: Parameter blah not supported for annotation JavaDerive.";
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900561 EXPECT_THAT(GetCapturedStderr(),
562 HasSubstr("Parameter blah not supported for annotation JavaDerive."));
Jooyung Han90345002020-10-23 15:28:53 +0900563 }
564
565 {
566 io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive interface IFoo{}");
Jiyong Park43113fb2020-07-20 16:26:19 +0900567 Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
568 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700569 EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900570 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
Jiyong Park43113fb2020-07-20 16:26:19 +0900571 }
572
573 {
Jooyung Han90345002020-10-23 15:28:53 +0900574 io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive enum IFoo { A=1, }");
Jiyong Park43113fb2020-07-20 16:26:19 +0900575 Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
576 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700577 EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900578 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
Jiyong Park43113fb2020-07-20 16:26:19 +0900579 }
580}
581
Jiyong Park27fd7fd2020-08-27 16:25:09 +0900582TEST_P(AidlTest, ParseDescriptorAnnotation) {
583 AidlError error;
584 auto parse_result = Parse("IFoo.aidl", R"(@Descriptor(value="IBar") interface IFoo{})",
585 typenames_, GetLanguage(), &error, {"--structured"});
586 ASSERT_EQ(AidlError::OK, error);
587 ASSERT_NE(nullptr, parse_result);
588 const AidlInterface* interface = parse_result->AsInterface();
589 ASSERT_NE(nullptr, interface);
590 ASSERT_EQ("IBar", interface->GetDescriptor());
591}
592
Jiyong Park40782d02020-07-24 19:17:43 +0900593TEST_P(AidlTest, AcceptsOnewayMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700594 const string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700595 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Jiyong Park40782d02020-07-24 19:17:43 +0900596}
597
598TEST_P(AidlTest, AcceptsOnewayInterface) {
599 const string oneway_interface = "package a; oneway interface IBar { void f(int a); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700600 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
Christopher Wiley90be4e32015-10-20 14:55:25 -0700601}
Christopher Wileyef140932015-11-03 09:29:19 -0800602
Devin Moore7b8d5c92020-03-17 14:14:08 -0700603TEST_P(AidlTest, AcceptsAnnotatedOnewayMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -0700604 const string oneway_method =
605 "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
Devin Moore7b8d5c92020-03-17 14:14:08 -0700606 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
Artur Satayev91fe8712019-07-29 13:06:01 +0100607}
608
Steven Moreland65297cc2020-04-20 20:17:36 -0700609TEST_P(AidlTest, AnnotationsInMultiplePlaces) {
610 const string oneway_method =
611 "package a; interface IFoo { @UnsupportedAppUsage oneway @Hide void f(int a); }";
612 const AidlDefinedType* defined = Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage());
613 ASSERT_NE(nullptr, defined);
614 const AidlInterface* iface = defined->AsInterface();
615 ASSERT_NE(nullptr, iface);
616
617 const auto& methods = iface->GetMethods();
618 ASSERT_EQ(1u, methods.size());
619 const auto& method = methods[0];
620 const AidlTypeSpecifier& ret_type = method->GetType();
621
622 // TODO(b/151102494): these annotations should be on the method
623 ASSERT_NE(nullptr, ret_type.UnsupportedAppUsage());
624 ASSERT_TRUE(ret_type.IsHide());
625}
626
Devin Moore7b8d5c92020-03-17 14:14:08 -0700627TEST_P(AidlTest, WritesComments) {
Artur Satayev91fe8712019-07-29 13:06:01 +0100628 string foo_interface =
Jooyung Han8451a202021-01-16 03:07:06 +0900629 R"(package a;
630 /* foo */
631 interface IFoo {
632 /* i */
633 int i();
634 // j
635 @nullable String j();
636 // k1
637 /* k2 */
638 @UnsupportedAppUsage oneway void k(int a);
639 })";
Artur Satayev91fe8712019-07-29 13:06:01 +0100640
Jooyung Han8451a202021-01-16 03:07:06 +0900641 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -0700642 auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, GetLanguage());
Artur Satayev91fe8712019-07-29 13:06:01 +0100643 EXPECT_NE(nullptr, parse_result);
Jooyung Han8451a202021-01-16 03:07:06 +0900644 EXPECT_EQ("", GetCapturedStderr());
645
Jooyung Han161bb0f2021-01-21 12:30:16 +0900646 EXPECT_EQ((Comments{{"/* foo */"}}), parse_result->GetComments());
Artur Satayev91fe8712019-07-29 13:06:01 +0100647
648 const AidlInterface* interface = parse_result->AsInterface();
Jooyung Han161bb0f2021-01-21 12:30:16 +0900649 EXPECT_EQ((Comments{{"/* i */"}}), interface->GetMethods()[0]->GetComments());
650 EXPECT_EQ((Comments{{"// j\n"}}), interface->GetMethods()[1]->GetComments());
651 EXPECT_EQ((Comments{{"// k1\n"}, {"/* k2 */"}}), interface->GetMethods()[2]->GetComments());
Artur Satayev91fe8712019-07-29 13:06:01 +0100652}
653
Jooyung Han1a551d32020-10-05 15:37:26 +0900654TEST_P(AidlTest, CppHeaderCanBeIdentifierAsWell) {
655 io_delegate_.SetFileContents("p/cpp_header.aidl",
656 R"(package p;
657 parcelable cpp_header cpp_header "bar/header";)");
658 import_paths_.emplace("");
659 const string input_path = "p/IFoo.aidl";
660 const string input = R"(package p;
661 import p.cpp_header;
662 interface IFoo {
663 // get bar
664 cpp_header get();
665 })";
666
667 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
668 EXPECT_NE(nullptr, parse_result);
669 const AidlInterface* interface = parse_result->AsInterface();
Jooyung Han161bb0f2021-01-21 12:30:16 +0900670 EXPECT_EQ((Comments{{"// get bar\n"}}), interface->GetMethods()[0]->GetComments());
Jooyung Han1a551d32020-10-05 15:37:26 +0900671}
672
Jooyung Han2cb8ecd2021-07-28 18:41:30 +0900673TEST_F(AidlTest, RejectsIfCppHeaderIsMissing) {
674 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo;");
675 Options options = Options::From("aidl --lang cpp -h h -o o Foo.aidl");
676 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700677 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han2cb8ecd2021-07-28 18:41:30 +0900678 EXPECT_THAT(GetCapturedStderr(), HasSubstr("must have C++ header defined"));
679}
680
681TEST_F(AidlTest, RejectsIfTypeRefsCppHeaderIsMissing) {
682 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo;");
683 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void bar(in Foo foo); }");
684 Options options = Options::From("aidl -I . --lang cpp -h h -o o IBar.aidl");
685 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700686 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han2cb8ecd2021-07-28 18:41:30 +0900687 EXPECT_THAT(GetCapturedStderr(), HasSubstr("must have C++ header defined"));
688}
689
Christopher Wileyef140932015-11-03 09:29:19 -0800690TEST_F(AidlTest, ParsesPreprocessedFile) {
691 string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
692 io_delegate_.SetFileContents("path", simple_content);
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700693 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
Jooyung Han93f48f02021-06-05 00:11:16 +0900694 EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700695 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
696 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
Christopher Wileyef140932015-11-03 09:29:19 -0800697}
698
699TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
700 string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
701 io_delegate_.SetFileContents("path", simple_content);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900702
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700703 EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
Jooyung Han93f48f02021-06-05 00:11:16 +0900704 EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700705 EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
706 EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
Christopher Wileyef140932015-11-03 09:29:19 -0800707}
708
Devin Moore7b8d5c92020-03-17 14:14:08 -0700709TEST_P(AidlTest, PreferImportToPreprocessed) {
Christopher Wiley41544372015-11-03 14:52:29 -0800710 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
711 io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
712 "interface IBar {}");
713 preprocessed_files_.push_back("preprocessed");
Jiyong Park8c380532018-08-30 14:55:26 +0900714 import_paths_.emplace("");
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900715 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
Devin Moore7b8d5c92020-03-17 14:14:08 -0700716 typenames_, GetLanguage());
Christopher Wiley41544372015-11-03 14:52:29 -0800717 EXPECT_NE(nullptr, parse_result);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900718
Christopher Wiley41544372015-11-03 14:52:29 -0800719 // We expect to know about both kinds of IBar
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700720 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
721 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
Christopher Wiley41544372015-11-03 14:52:29 -0800722 // But if we request just "IBar" we should get our imported one.
Jooyung Han8451a202021-01-16 03:07:06 +0900723 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, {});
Jooyung Han13f1fa52021-06-11 18:06:12 +0900724 ambiguous_type.Resolve(typenames_, parse_result);
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900725 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
Christopher Wiley41544372015-11-03 14:52:29 -0800726}
727
Jiyong Park8f6ec462020-01-19 20:52:47 +0900728// Special case of PreferImportToPreprocessed. Imported type should be preferred
729// even when the preprocessed file already has the same type.
Devin Moore7b8d5c92020-03-17 14:14:08 -0700730TEST_P(AidlTest, B147918827) {
Jiyong Park8f6ec462020-01-19 20:52:47 +0900731 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;\ninterface one.IBar;");
732 io_delegate_.SetFileContents("one/IBar.aidl",
733 "package one; "
734 "interface IBar {}");
735 preprocessed_files_.push_back("preprocessed");
736 import_paths_.emplace("");
737 auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
Devin Moore7b8d5c92020-03-17 14:14:08 -0700738 typenames_, GetLanguage());
Jiyong Park8f6ec462020-01-19 20:52:47 +0900739 EXPECT_NE(nullptr, parse_result);
740
741 // We expect to know about both kinds of IBar
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700742 EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
743 EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
Jiyong Park8f6ec462020-01-19 20:52:47 +0900744 // But if we request just "IBar" we should get our imported one.
Jooyung Han8451a202021-01-16 03:07:06 +0900745 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, {});
Jooyung Han13f1fa52021-06-11 18:06:12 +0900746 ambiguous_type.Resolve(typenames_, parse_result);
Jiyong Park8f6ec462020-01-19 20:52:47 +0900747 EXPECT_EQ("one.IBar", ambiguous_type.GetName());
748}
749
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800750TEST_F(AidlTest, WritePreprocessedFile) {
751 io_delegate_.SetFileContents("p/Outer.aidl",
752 "package p; parcelable Outer.Inner;");
753 io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
754 "interface IBar {}");
755
Jooyung Han93f48f02021-06-05 00:11:16 +0900756 vector<string> args{"aidl", "--preprocess", "preprocessed",
757 "-I.", "p/Outer.aidl", "one/IBar.aidl"};
Jiyong Park6f77e0c2018-07-28 16:55:44 +0900758 Options options = Options::From(args);
Jooyung Han93f48f02021-06-05 00:11:16 +0900759 EXPECT_TRUE(::android::aidl::Preprocess(options, io_delegate_));
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800760
Jooyung Han93f48f02021-06-05 00:11:16 +0900761 std::map<std::string, std::string> expected = {{"preprocessed",
762 "parcelable p.Outer.Inner;\n"
763 "interface one.IBar {\n"
764 "}\n"}};
765 EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
766}
767
768TEST_F(AidlTest, PreprocessVariousThings) {
769 io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
770 "package foo.bar;\n"
771 "interface IFoo {\n"
772 " int foo();\n"
773 " const int FOO = foo.bar.Bar.BAR + 1; // should be 44\n"
774 "}\n");
775 io_delegate_.SetFileContents("foo/bar/Bar.aidl",
776 "package foo.bar;\n"
777 "parcelable Bar {\n"
778 " const int BAR = imported.Foo.FOO + 1; // should be 43\n"
779 " imported.Foo foo;\n"
780 "}\n");
781 io_delegate_.SetFileContents("foo/bar/Gen.aidl",
782 "package foo.bar;\n"
783 "parcelable Gen<T> {\n"
784 "}\n");
785 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
786 "package foo.bar;\n"
787 "enum Enum {\n"
788 " FOO = 3, BAR = FOO + 3, // should be 3, 6\n"
789 "}\n");
790 io_delegate_.SetFileContents("sub/imported/Foo.aidl",
791 "package imported;\n"
792 "parcelable Foo {\n"
793 " const int FOO = 42;\n"
794 "}\n");
795
796 vector<string> args = {
797 "aidl",
798 "--preprocess",
799 "preprocessed",
800 "-Isub",
801 "-I.",
802 "foo/bar/IFoo.aidl",
803 "foo/bar/Bar.aidl",
804 "foo/bar/Gen.aidl",
805 "foo/bar/Enum.aidl",
806 };
807 ASSERT_TRUE(Preprocess(Options::From(args), io_delegate_));
808 std::string preprocessed =
809 "interface foo.bar.IFoo {\n"
810 " const int FOO = 44;\n"
811 "}\n"
812 "parcelable foo.bar.Bar {\n"
813 " const int BAR = 43;\n"
814 "}\n"
815 "parcelable foo.bar.Gen<T> {\n"
816 "}\n"
817 "enum foo.bar.Enum {\n"
818 " FOO = 3,\n"
819 " BAR = 6,\n"
820 "}\n";
821 std::map<std::string, std::string> expected = {{"preprocessed", preprocessed}};
822 EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
823
824 // use preprocessed
825 io_delegate_.SetFileContents("a/Foo.aidl",
826 "package a; parcelable Foo { const int y = foo.bar.Bar.BAR; }");
827 io_delegate_.SetFileContents("preprocessed", preprocessed);
828 CaptureStderr();
829 auto options = Options::From("aidl --lang java -o out a/Foo.aidl -ppreprocessed");
Steven Moreland4e059132021-08-11 13:36:30 -0700830 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han93f48f02021-06-05 00:11:16 +0900831 EXPECT_EQ("", GetCapturedStderr());
832 string code;
833 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
834 EXPECT_THAT(code, testing::HasSubstr("public static final int y = 43;"));
835}
836
Jooyung Han35784982021-06-29 06:26:12 +0900837TEST_F(AidlTest, AllowMultipleUnstructuredNestedParcelablesInASingleDocument) {
838 io_delegate_.SetFileContents("p/IFoo.aidl",
839 "package p;\n"
840 "import x.Outer;\n"
841 "interface IFoo {\n"
842 " void foo(in Outer.Inner1 in1, in Outer.Inner2 in2);\n"
843 "}");
844 io_delegate_.SetFileContents("imported/x/Outer.aidl",
845 "package x;\n"
846 "parcelable Outer.Inner1;\n"
847 "parcelable Outer.Inner2;\n");
848 auto opt = Options::From("aidl -Iimported --lang=java p/IFoo.aidl");
849 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700850 EXPECT_TRUE(compile_aidl(opt, io_delegate_));
Jooyung Han35784982021-06-29 06:26:12 +0900851 EXPECT_EQ("", GetCapturedStderr());
852}
853
854TEST_F(AidlTest,
855 StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlLater) {
856 // Main doc(Foo.aidl) is loaded
857 // And then framework.aidl is loaded as preprocessed. (conflict)
858 io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
859 io_delegate_.SetFileContents("x/Foo.aidl",
860 "package x;\n"
861 "parcelable Foo.Inner;\n");
862 auto opt = Options::From("aidl -psdk/framework.aidl -I. x/Foo.aidl");
863 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700864 EXPECT_TRUE(compile_aidl(opt, io_delegate_));
Jooyung Han35784982021-06-29 06:26:12 +0900865 EXPECT_EQ("", GetCapturedStderr());
866}
867
868TEST_F(AidlTest,
869 StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlFirst) {
870 // Main doc(IBar.aidl) is loaded first.
871 // Framework.aidl is loaded as preprocessed.
872 // And then import(Foo.aidl) is loaded. (conflict)
873 io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
874 io_delegate_.SetFileContents("x/IBar.aidl",
875 "package x;\n"
876 "import x.Foo;\n"
877 "interface IBar {\n"
878 " void bar(in Foo.Inner inner);\n"
879 "}");
880 io_delegate_.SetFileContents("x/Foo.aidl",
881 "package x;\n"
882 "parcelable Foo.Inner;\n");
883 auto opt = Options::From("aidl -psdk/framework.aidl -I. x/IBar.aidl");
884 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -0700885 EXPECT_TRUE(compile_aidl(opt, io_delegate_));
Jooyung Han35784982021-06-29 06:26:12 +0900886 EXPECT_EQ("", GetCapturedStderr());
887}
888
Jooyung Han93f48f02021-06-05 00:11:16 +0900889TEST_F(AidlTest, PreprocessedFileCantDeclarePackage) {
890 string simple_content = "package xxx; parcelable a.Foo;";
891 io_delegate_.SetFileContents("path", simple_content);
892 CaptureStderr();
893 EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
894 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Preprocessed file can't declare package."));
895}
896
897TEST_F(AidlTest, RejectQualifiedTypeNameUnlessPreprocessed) {
898 string simple_content = "parcelable a.Foo {}";
899 io_delegate_.SetFileContents("path", simple_content);
900 CaptureStderr();
901 EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/false));
902 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Type name can't be qualified"));
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800903}
904
Jooyung Han13f1fa52021-06-11 18:06:12 +0900905TEST_P(AidlTest, PreprocessedCanDeclareJavaStyleBuiltinTypes) {
906 string contents = R"(
907 interface android.os.IBinder;
908 interface android.os.IInterface;
909 parcelable android.os.ParcelFileDescriptor;
910 )";
911 io_delegate_.SetFileContents("path", contents);
912 CaptureStderr();
913 EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
914 EXPECT_THAT(GetCapturedStderr(), "");
915}
916
Jooyung Han720253d2021-01-05 19:13:17 +0900917TEST_P(AidlTest, SupportDeprecated) {
918 struct TestCase {
919 std::string output_file;
920 std::string annotation;
921 };
922
923 auto CheckDeprecated = [&](const std::string& filename, const std::string& contents,
Jooyung Hand4fe00e2021-01-11 16:21:53 +0900924 std::vector<std::pair<Options::Language, TestCase>> expectations) {
Jooyung Han720253d2021-01-05 19:13:17 +0900925 io_delegate_.SetFileContents(filename, contents);
926
927 auto options = Options::From("aidl --lang=" + to_string(GetLanguage()) + " " + filename +
928 " --out=out --header_out=out");
Steven Moreland4e059132021-08-11 13:36:30 -0700929 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Hand4fe00e2021-01-11 16:21:53 +0900930 for (const auto& [lang, test_case] : expectations) {
931 if (lang != GetLanguage()) continue;
Jooyung Han720253d2021-01-05 19:13:17 +0900932 string output;
Jooyung Han652ce482021-02-26 12:40:35 +0900933 EXPECT_TRUE(io_delegate_.GetWrittenContents(test_case.output_file, &output));
Jooyung Han720253d2021-01-05 19:13:17 +0900934 EXPECT_THAT(output, HasSubstr(test_case.annotation));
935 }
936 };
937
Jooyung Hand4fe00e2021-01-11 16:21:53 +0900938 // Emit escaped string for notes
939 CheckDeprecated(
940 "IFoo.aidl",
941 R"(interface IFoo {
942 /**
943 * @note asdf
944 * @deprecated a really long deprecation message
945 *
946 * which is really long
947 * @param foo bar
948 */
949 List<String> foo();
950 })",
951 {
952 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
953 {Options::Language::CPP,
954 {"out/IFoo.h",
955 R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
956 {Options::Language::NDK,
957 {"out/aidl/IFoo.h",
958 R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
959 {Options::Language::RUST,
960 {"out/IFoo.rs",
961 R"(#[deprecated = "a really long deprecation message which is really long"])"}},
962 });
963
Jooyung Han24effbf2021-01-16 10:24:03 +0900964 // In AIDL @deprecated can be in block comments as well as javadoc style
Jooyung Hand4fe00e2021-01-11 16:21:53 +0900965 CheckDeprecated(
966 "IFoo.aidl",
967 "interface IFoo {\n"
Jooyung Han24effbf2021-01-16 10:24:03 +0900968 " /* @deprecated use bar() */\n"
Jooyung Hand4fe00e2021-01-11 16:21:53 +0900969 " List<String> foo();\n"
970 "}",
971 {
972 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
Jooyung Hanb7a60ec2021-01-21 13:47:59 +0900973 {Options::Language::JAVA, {"out/IFoo.java", "/** @deprecated use bar() */"}},
Jooyung Hand4fe00e2021-01-11 16:21:53 +0900974 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
975 {Options::Language::NDK,
976 {"out/aidl/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
977 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated = \"use bar()\"]"}},
978 });
Jooyung Han720253d2021-01-05 19:13:17 +0900979
Jooyung Han24effbf2021-01-16 10:24:03 +0900980 // but not in line comments
981 auto parsed = Parse("IFoo.aidl", "// @deprecated\ninterface IFoo {}", typenames_, GetLanguage());
982 EXPECT_FALSE(parsed->IsDeprecated());
983
984 // parcelable
Jooyung Han720253d2021-01-05 19:13:17 +0900985 CheckDeprecated("Foo.aidl",
986 "parcelable Foo {\n"
987 " /** @deprecated use bar*/\n"
988 " int foo = 0;\n"
989 "}",
990 {
991 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
992 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
993 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
994 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
995 });
996
Jooyung Han24effbf2021-01-16 10:24:03 +0900997 // interface constants
Jooyung Han720253d2021-01-05 19:13:17 +0900998 CheckDeprecated("IFoo.aidl",
999 "interface IFoo {\n"
1000 " /** @deprecated use bar*/\n"
1001 " const int FOO = 0;\n"
1002 "}",
1003 {
1004 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1005 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1006 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1007 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1008 });
1009
1010 // union fields
1011 CheckDeprecated("Foo.aidl",
1012 "union Foo {\n"
1013 " int bar = 0;\n"
1014 " /** @deprecated use bar*/\n"
1015 " int foo;\n"
1016 "}",
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 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1022 });
1023
1024 CheckDeprecated("Foo.aidl",
1025 "/** @deprecated use Bar */\n"
1026 "parcelable Foo {}",
1027 {
1028 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1029 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1030 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1031 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1032 });
1033
1034 CheckDeprecated("Foo.aidl",
1035 "/** @deprecated use Bar */\n"
1036 "union Foo { int foo = 0; }",
1037 {
1038 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1039 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1040 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1041 {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1042 });
1043
1044 CheckDeprecated("IFoo.aidl",
1045 "/** @deprecated use IBar */\n"
1046 "interface IFoo {}",
1047 {
1048 {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1049 {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1050 {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1051 {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1052 });
1053
1054 CheckDeprecated("Foo.aidl",
1055 "/** @deprecated use IBar */\n"
1056 "enum Foo { FOO }",
1057 {
1058 {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1059 {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1060 {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
Jooyung Hanb7a60ec2021-01-21 13:47:59 +09001061 // TODO(b/177860423) support "deprecated" in Rust enum
Jooyung Han720253d2021-01-05 19:13:17 +09001062 // {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1063 });
1064}
1065
Devin Moore7b8d5c92020-03-17 14:14:08 -07001066TEST_P(AidlTest, RequireOuterClass) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001067 const string expected_stderr = "ERROR: p/IFoo.aidl:1.54-60: Failed to resolve 'Inner'\n";
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001068 io_delegate_.SetFileContents("p/Outer.aidl",
1069 "package p; parcelable Outer.Inner;");
Jiyong Park8c380532018-08-30 14:55:26 +09001070 import_paths_.emplace("");
Devin Moore097a3ab2020-03-11 16:08:44 -07001071 CaptureStderr();
1072 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1073 "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001074 typenames_, GetLanguage()));
Devin Moore097a3ab2020-03-11 16:08:44 -07001075 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001076}
1077
Devin Moore7b8d5c92020-03-17 14:14:08 -07001078TEST_P(AidlTest, ParseCompoundParcelableFromPreprocess) {
Steven Moreland58d402b2021-07-27 18:35:07 -07001079 io_delegate_.SetFileContents("preprocessed", "parcelable p.Outer.Inner cpp_header \"inner.h\";");
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001080 preprocessed_files_.push_back("preprocessed");
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001081 auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001082 typenames_, GetLanguage());
Christopher Wiley63bce2a2015-11-03 14:55:03 -08001083 // TODO(wiley): This should actually return nullptr because we require
1084 // the outer class name. However, for legacy reasons,
1085 // this behavior must be maintained. b/17415692
1086 EXPECT_NE(nullptr, parse_result);
1087}
1088
Christopher Wiley632801d2015-11-05 14:15:49 -08001089TEST_F(AidlTest, FailOnParcelable) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001090 const string expected_foo_stderr =
1091 "ERROR: p/IFoo.aidl:1.22-27: Refusing to generate code with unstructured parcelables. "
1092 "Declared parcelables should be in their own file and/or cannot be used with --structured "
1093 "interfaces.\n";
Steven Morelande2c64b42018-09-18 15:06:37 -07001094 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; parcelable IFoo;");
1095
Christopher Wiley632801d2015-11-05 14:15:49 -08001096 // By default, we shouldn't fail on parcelable.
Steven Morelande2c64b42018-09-18 15:06:37 -07001097 Options options1 = Options::From("aidl p/IFoo.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001098 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001099 EXPECT_TRUE(compile_aidl(options1, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001100 EXPECT_EQ("", GetCapturedStderr());
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001101
Steven Morelande2c64b42018-09-18 15:06:37 -07001102 // -b considers this an error
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001103 Options options2 = Options::From("aidl -b p/IFoo.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001104 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001105 EXPECT_FALSE(compile_aidl(options2, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001106 EXPECT_EQ(expected_foo_stderr, GetCapturedStderr());
Steven Morelande2c64b42018-09-18 15:06:37 -07001107
Devin Moore097a3ab2020-03-11 16:08:44 -07001108 const string expected_bar_stderr =
1109 "ERROR: p/IBar.aidl:1.22-26: Refusing to generate code with unstructured parcelables. "
1110 "Declared parcelables should be in their own file and/or cannot be used with --structured "
1111 "interfaces.\n";
Steven Morelande2c64b42018-09-18 15:06:37 -07001112 io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
1113
Jiyong Parkda8c6932019-08-12 19:56:08 +09001114 // With '-b' option, a parcelable and an interface should fail.
Steven Morelande2c64b42018-09-18 15:06:37 -07001115 Options options3 = Options::From("aidl p/IBar.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001116 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001117 EXPECT_TRUE(compile_aidl(options3, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001118 EXPECT_EQ("", GetCapturedStderr());
Steven Morelande2c64b42018-09-18 15:06:37 -07001119 Options options4 = Options::From("aidl -b p/IBar.aidl");
Devin Moore097a3ab2020-03-11 16:08:44 -07001120 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001121 EXPECT_FALSE(compile_aidl(options4, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001122 EXPECT_EQ(expected_bar_stderr, GetCapturedStderr());
Christopher Wiley632801d2015-11-05 14:15:49 -08001123}
1124
Jooyung Han13f1fa52021-06-11 18:06:12 +09001125TEST_P(AidlTest, ImportingJavaStyleBuiltinTypesIsAllowed) {
1126 string contents = R"(
1127 import android.os.IBinder;
1128 import android.os.IInterface;
1129 interface IFoo {
1130 void foo(in IBinder b);
1131 }
1132 )";
1133 EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
1134}
1135
Devin Moore7b8d5c92020-03-17 14:14:08 -07001136TEST_P(AidlTest, StructuredFailOnUnstructuredParcelable) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001137 const string expected_stderr =
Jooyung Han397a7602021-06-05 00:06:22 +09001138 "ERROR: o/WhoKnowsWhat.aidl:1.22-35: o.WhoKnowsWhat is not structured, but this is a "
Devin Moore097a3ab2020-03-11 16:08:44 -07001139 "structured interface.\n";
Steven Moreland58d402b2021-07-27 18:35:07 -07001140 io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl",
1141 "package o; parcelable WhoKnowsWhat cpp_header \"who_knows.h\";");
Steven Moreland1eac5fa2018-08-27 19:35:05 -07001142 import_paths_.emplace("");
Devin Moore097a3ab2020-03-11 16:08:44 -07001143 AidlError error;
1144 CaptureStderr();
1145 EXPECT_EQ(
1146 nullptr,
Steven Moreland1eac5fa2018-08-27 19:35:05 -07001147 Parse("p/IFoo.aidl",
1148 "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001149 typenames_, GetLanguage(), &error, {"--structured"}));
Devin Moore097a3ab2020-03-11 16:08:44 -07001150 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1151 EXPECT_EQ(AidlError::NOT_STRUCTURED, error);
Steven Moreland1eac5fa2018-08-27 19:35:05 -07001152}
1153
Devin Moore7b8d5c92020-03-17 14:14:08 -07001154TEST_P(AidlTest, FailOnDuplicateConstantNames) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001155 AidlError error;
1156 const string expected_stderr =
1157 "ERROR: p/IFoo.aidl:4.34-45: Found duplicate constant name 'DUPLICATED'\n";
1158 CaptureStderr();
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001159 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1160 R"(package p;
Christopher Wiley69b44cf2016-05-03 13:43:33 -07001161 interface IFoo {
1162 const String DUPLICATED = "d";
1163 const int DUPLICATED = 1;
1164 }
1165 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001166 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07001167 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1168 EXPECT_EQ(AidlError::BAD_TYPE, error);
Christopher Wiley69b44cf2016-05-03 13:43:33 -07001169}
1170
Steven Morelande689da22020-11-10 02:06:30 +00001171TEST_P(AidlTest, FailOnTooBigConstant) {
1172 AidlError error;
1173 const string expected_stderr =
1174 "ERROR: p/IFoo.aidl:3.48-52: Invalid type specifier for an int32 literal: byte\n";
1175 CaptureStderr();
1176 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1177 R"(package p;
1178 interface IFoo {
1179 const byte type2small = 256;
1180 }
1181 )",
1182 typenames_, GetLanguage(), &error));
1183 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1184 EXPECT_EQ(AidlError::BAD_TYPE, error);
1185}
1186
Jooyung Han30f64ad2020-12-15 08:16:31 +09001187TEST_F(AidlTest, BoolConstantsEvaluatesToIntegers) {
1188 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { const int y = true; }");
1189 CaptureStderr();
1190 auto options = Options::From("aidl --lang java -o out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07001191 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han30f64ad2020-12-15 08:16:31 +09001192 EXPECT_EQ("", GetCapturedStderr());
1193 string code;
1194 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
1195 EXPECT_THAT(code, testing::HasSubstr("public static final int y = 1;"));
1196}
1197
Jooyung Han535c5e82020-12-29 15:16:59 +09001198TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) {
Jooyung Han71a1b582020-12-25 23:58:41 +09001199 using Ptr = unique_ptr<AidlConstantValue>;
1200 const AidlLocation& loc = AIDL_LOCATION_HERE;
1201
Jooyung Han535c5e82020-12-29 15:16:59 +09001202 EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, 'c'))->EvaluatedValue<char>());
1203 EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>());
1204 EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>());
1205 EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>());
Jooyung Han71a1b582020-12-25 23:58:41 +09001206
1207 AidlBinaryConstExpression one_plus_one(loc, Ptr(AidlConstantValue::Integral(loc, "1")), "+",
1208 Ptr(AidlConstantValue::Integral(loc, "1")));
Jooyung Han535c5e82020-12-29 15:16:59 +09001209 EXPECT_EQ(2, one_plus_one.EvaluatedValue<int32_t>());
Jooyung Han71a1b582020-12-25 23:58:41 +09001210
1211 auto values = unique_ptr<vector<Ptr>>{new vector<Ptr>};
1212 values->emplace_back(AidlConstantValue::String(loc, "\"hello\""));
1213 values->emplace_back(AidlConstantValue::String(loc, "\"world\""));
1214 vector<string> expected{"hello", "world"};
Jooyung Han535c5e82020-12-29 15:16:59 +09001215 EXPECT_EQ(
1216 expected,
1217 Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>());
Jooyung Han71a1b582020-12-25 23:58:41 +09001218}
1219
Devin Moore7b8d5c92020-03-17 14:14:08 -07001220TEST_P(AidlTest, FailOnManyDefinedTypes) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001221 AidlError error;
Devin Moore5de18ed2020-04-02 13:52:29 -07001222 const string expected_stderr =
1223 "ERROR: p/IFoo.aidl:3.33-38: You must declare only one type per file.\n";
Devin Moorec054bf82020-03-10 16:31:48 -07001224 CaptureStderr();
Steven Morelandc258abc2018-07-10 14:03:38 -07001225 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1226 R"(package p;
1227 interface IFoo {}
Steven Morelandc258abc2018-07-10 14:03:38 -07001228 parcelable IBar {}
1229 parcelable StructuredParcelable {}
1230 interface IBaz {}
Jeongik Cha2a5b4d82019-08-06 19:37:59 +09001231 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001232 typenames_, GetLanguage(), &error));
Devin Moorec054bf82020-03-10 16:31:48 -07001233 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Steven Morelandc258abc2018-07-10 14:03:38 -07001234 // Parse success is important for clear error handling even if the cases aren't
1235 // actually supported in code generation.
Devin Moore097a3ab2020-03-11 16:08:44 -07001236 EXPECT_EQ(AidlError::BAD_TYPE, error);
Steven Morelandc258abc2018-07-10 14:03:38 -07001237}
1238
Devin Moore7b8d5c92020-03-17 14:14:08 -07001239TEST_P(AidlTest, FailOnNoDefinedTypes) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001240 AidlError error;
1241 const string expected_stderr = "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected $end\n";
1242 CaptureStderr();
Devin Moore7b8d5c92020-03-17 14:14:08 -07001243 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07001244 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1245 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Steven Morelandc258abc2018-07-10 14:03:38 -07001246}
1247
Steven Morelandf9e922f2020-07-08 21:15:27 +00001248TEST_P(AidlTest, FailOnEmptyListWithComma) {
1249 AidlError error;
1250 const string expected_stderr =
1251 "ERROR: p/Foo.aidl:1.45-47: syntax error, unexpected ',', expecting '}'\n";
1252 CaptureStderr();
1253 EXPECT_EQ(nullptr, Parse("p/Foo.aidl", R"(package p; parcelable Foo { uint64_t[] a = { , }; })",
1254 typenames_, GetLanguage(), &error));
1255 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1256 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1257}
1258
Devin Moore7b8d5c92020-03-17 14:14:08 -07001259TEST_P(AidlTest, FailOnMalformedConstHexValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001260 AidlError error;
1261 const string expected_stderr =
Devin Moore2a088902020-09-17 10:51:19 -07001262 "ERROR: p/IFoo.aidl:3.50-71: Could not parse hexvalue: 0xffffffffffffffffff\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07001263 CaptureStderr();
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001264 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1265 R"(package p;
Roshan Pius3b2203d2016-07-22 16:13:20 -07001266 interface IFoo {
1267 const int BAD_HEX_VALUE = 0xffffffffffffffffff;
1268 }
1269 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001270 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07001271 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1272 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Roshan Pius3b2203d2016-07-22 16:13:20 -07001273}
1274
Jiyong Park18132182020-06-08 20:24:40 +09001275TEST_P(AidlTest, FailOnMalformedQualifiedNameAsIdentifier) {
1276 AidlError error;
1277 const string expected_stderr =
1278 "ERROR: p/IFoo.aidl:1.25-26: syntax error, unexpected ';', expecting identifier or "
1279 "cpp_header (which can also be used as an identifier)\n";
1280 CaptureStderr();
1281 // Notice the trailing dot(.) in the name, which isn't a correct name
1282 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p; parcelable A.; )", typenames_,
1283 GetLanguage(), &error));
1284 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1285 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1286}
1287
1288TEST_P(AidlTest, FailOnMalformedQualifiedNameAsPackage) {
1289 AidlError error;
1290 const string expected_stderr =
1291 "ERROR: p/IFoo.aidl:1.11-12: syntax error, unexpected ';', expecting identifier or "
1292 "cpp_header (which can also be used as an identifier)\n";
1293 CaptureStderr();
1294 // Notice the trailing dot(.) in the package name
1295 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p.; parcelable A; )", typenames_,
1296 GetLanguage(), &error));
1297 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1298 EXPECT_EQ(AidlError::PARSE_ERROR, error);
1299}
1300
Devin Moore7b8d5c92020-03-17 14:14:08 -07001301TEST_P(AidlTest, ParsePositiveConstHexValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001302 AidlError error;
Devin Moore7b8d5c92020-03-17 14:14:08 -07001303 auto parse_result = Parse("p/IFoo.aidl",
1304 R"(package p;
Roshan Pius3b2203d2016-07-22 16:13:20 -07001305 interface IFoo {
1306 const int POSITIVE_HEX_VALUE = 0xf5;
1307 }
1308 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001309 typenames_, GetLanguage(), &error);
1310 EXPECT_NE(nullptr, parse_result);
1311 const AidlInterface* interface = parse_result->AsInterface();
Steven Moreland5557f1c2018-07-02 13:50:23 -07001312 ASSERT_NE(nullptr, interface);
Steven Moreland693640b2018-07-19 13:46:27 -07001313 const auto& cpp_constants = interface->GetConstantDeclarations();
1314 EXPECT_EQ((size_t)1, cpp_constants.size());
1315 EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
Will McVickerd7d18df2019-09-12 13:40:50 -07001316 EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
Steven Moreland860b1942018-08-16 14:59:28 -07001317 EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
Roshan Pius3b2203d2016-07-22 16:13:20 -07001318}
1319
Devin Moore7b8d5c92020-03-17 14:14:08 -07001320TEST_P(AidlTest, ParseNegativeConstHexValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001321 AidlError error;
Devin Moore7b8d5c92020-03-17 14:14:08 -07001322 auto parse_result = Parse("p/IFoo.aidl",
1323 R"(package p;
Roshan Pius3b2203d2016-07-22 16:13:20 -07001324 interface IFoo {
1325 const int NEGATIVE_HEX_VALUE = 0xffffffff;
1326 }
1327 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07001328 typenames_, GetLanguage(), &error);
1329 ASSERT_NE(nullptr, parse_result);
1330 const AidlInterface* interface = parse_result->AsInterface();
Steven Moreland5557f1c2018-07-02 13:50:23 -07001331 ASSERT_NE(nullptr, interface);
Steven Moreland693640b2018-07-19 13:46:27 -07001332 const auto& cpp_constants = interface->GetConstantDeclarations();
1333 EXPECT_EQ((size_t)1, cpp_constants.size());
1334 EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
Will McVickerd7d18df2019-09-12 13:40:50 -07001335 EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
Steven Moreland860b1942018-08-16 14:59:28 -07001336 EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
Roshan Pius3b2203d2016-07-22 16:13:20 -07001337}
1338
Devin Moore7b8d5c92020-03-17 14:14:08 -07001339TEST_P(AidlTest, UnderstandsNestedParcelables) {
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001340 io_delegate_.SetFileContents(
1341 "p/Outer.aidl",
1342 "package p; parcelable Outer.Inner cpp_header \"baz/header\";");
Jiyong Park8c380532018-08-30 14:55:26 +09001343 import_paths_.emplace("");
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001344 const string input_path = "p/IFoo.aidl";
1345 const string input = "package p; import p.Outer; interface IFoo"
1346 " { Outer.Inner get(); }";
1347
Devin Moore7b8d5c92020-03-17 14:14:08 -07001348 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1349 EXPECT_NE(nullptr, parse_result);
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001350
Steven Morelandcb1bcd72020-04-29 16:30:35 -07001351 EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001352 // C++ uses "::" instead of "." to refer to a inner class.
Jooyung Han8451a202021-01-16 03:07:06 +09001353 AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", false, nullptr, {});
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001354 EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
Ningyuan Wangd17c58b2016-09-29 14:33:14 -07001355}
1356
Jooyung Han78fcaa82021-06-11 22:27:57 +09001357TEST_P(AidlTest, UnderstandsNestedParcelablesWithoutImports) {
1358 io_delegate_.SetFileContents("p/Outer.aidl",
1359 "package p; parcelable Outer.Inner cpp_header \"baz/header\";");
1360 import_paths_.emplace("");
1361 const string input_path = "p/IFoo.aidl";
1362 const string input = "package p; interface IFoo { p.Outer.Inner get(); }";
1363
1364 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1365 EXPECT_NE(nullptr, parse_result);
1366
1367 EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1368 // C++ uses "::" instead of "." to refer to a inner class.
1369 AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", false, nullptr, {});
1370 EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1371}
1372
Jooyung Han0a950bd2021-05-15 12:50:36 +09001373TEST_F(AidlTest, CppNameOf_GenericType) {
1374 io_delegate_.SetFileContents("p/Wrapper.aidl", "package p; parcelable Wrapper<T> { T wrapped; }");
1375 import_paths_.emplace("");
1376 // Since we don't support compilation of Wrapper directly (due to "T" reference),
1377 // prepare Holder so that Wrapper gets parsed into AidlTypenames
1378 const string input_path = "p/Holder.aidl";
1379 const string input =
1380 "package p; import p.Wrapper; parcelable Holder {\n"
1381 " @nullable Wrapper<String> value;\n"
1382 "}";
1383
1384 auto parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
1385 EXPECT_NE(nullptr, parse_result);
1386
1387 auto type = [](std::string name, auto&&... type_params) -> std::unique_ptr<AidlTypeSpecifier> {
1388 auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>;
1389 (..., params->emplace_back(std::move(type_params)));
1390 return std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, name, false, params, Comments{});
1391 };
1392
1393 auto set_nullable = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
1394 std::vector<AidlAnnotation> annotations;
1395 annotations.emplace_back(*AidlAnnotation::Parse(AIDL_LOCATION_HERE, "nullable", nullptr, {}));
1396 type->Annotate(std::move(annotations));
1397 return std::move(type);
1398 };
1399
1400 auto set_array = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
1401 (void)type->SetArray();
1402 return std::move(type);
1403 };
1404
1405 auto w = type("p.Wrapper", type("String"));
1406 EXPECT_EQ("::p::Wrapper<::android::String16>", cpp::CppNameOf(*w, typenames_));
1407
1408 auto nullable_w = set_nullable(type("p.Wrapper", type("String")));
1409 EXPECT_EQ("::std::optional<::p::Wrapper<::android::String16>>",
1410 cpp::CppNameOf(*nullable_w, typenames_));
1411
1412 auto array_w = set_array(type("p.Wrapper", type("String")));
1413 EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
1414 cpp::CppNameOf(*array_w, typenames_));
1415
1416 auto nullable_array_w = set_nullable(set_array(type("p.Wrapper", type("String"))));
1417 EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
1418 cpp::CppNameOf(*nullable_array_w, typenames_));
1419
1420 auto list_w = type("List", type("p.Wrapper", type("String")));
1421 EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
1422 cpp::CppNameOf(*list_w, typenames_));
1423
1424 auto nullable_list_w = set_nullable(type("List", type("p.Wrapper", type("String"))));
1425 EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
1426 cpp::CppNameOf(*nullable_list_w, typenames_));
1427}
1428
Devin Moore7b8d5c92020-03-17 14:14:08 -07001429TEST_P(AidlTest, UnderstandsNativeParcelables) {
Christopher Wiley9078d722015-11-17 10:23:49 -08001430 io_delegate_.SetFileContents(
1431 "p/Bar.aidl",
Casey Dahlincd639212015-12-15 12:51:04 -08001432 "package p; parcelable Bar cpp_header \"baz/header\";");
Jiyong Park8c380532018-08-30 14:55:26 +09001433 import_paths_.emplace("");
Christopher Wiley9078d722015-11-17 10:23:49 -08001434 const string input_path = "p/IFoo.aidl";
1435 const string input = "package p; import p.Bar; interface IFoo { }";
Devin Moore7b8d5c92020-03-17 14:14:08 -07001436 auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1437 EXPECT_NE(nullptr, parse_result);
Steven Morelandcb1bcd72020-04-29 16:30:35 -07001438 EXPECT_TRUE(typenames_.ResolveTypename("p.Bar").is_resolved);
Jooyung Han8451a202021-01-16 03:07:06 +09001439 AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, {});
Jooyung Han13f1fa52021-06-11 18:06:12 +09001440 native_type.Resolve(typenames_, parse_result);
Devin Moore7b8d5c92020-03-17 14:14:08 -07001441
1442 EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type, typenames_));
1443 // C++ understands C++ specific stuff
1444 EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
1445 set<string> headers;
Devin Moore2f2077a2020-08-28 11:27:53 -07001446 cpp::AddHeaders(native_type, typenames_, &headers);
Devin Moore7b8d5c92020-03-17 14:14:08 -07001447 EXPECT_EQ(1u, headers.size());
1448 EXPECT_EQ(1u, headers.count("baz/header"));
Christopher Wiley9078d722015-11-17 10:23:49 -08001449}
1450
Christopher Wileyf8136192016-04-12 14:19:35 -07001451TEST_F(AidlTest, WritesCorrectDependencyFile) {
1452 // While the in tree build system always gives us an output file name,
1453 // other android tools take advantage of our ability to infer the intended
1454 // file name. This test makes sure we handle this correctly.
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001455 vector<string> args = {
1456 "aidl",
1457 "-d dep/file/path",
1458 "-o place/for/output",
1459 "p/IFoo.aidl"};
1460 Options options = Options::From(args);
1461 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
Steven Moreland4e059132021-08-11 13:36:30 -07001462 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Christopher Wileyf8136192016-04-12 14:19:35 -07001463 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001464 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Christopher Wileyf8136192016-04-12 14:19:35 -07001465 EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
1466}
1467
Dan Willemsen93298ee2016-11-10 23:55:55 -08001468TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
1469 // While the in tree build system always gives us an output file name,
1470 // other android tools take advantage of our ability to infer the intended
1471 // file name. This test makes sure we handle this correctly.
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001472 vector<string> args = {
1473 "aidl",
1474 "-d dep/file/path",
1475 "--ninja",
1476 "-o place/for/output",
1477 "p/IFoo.aidl"};
1478 Options options = Options::From(args);
1479 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
Steven Moreland4e059132021-08-11 13:36:30 -07001480 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Dan Willemsen93298ee2016-11-10 23:55:55 -08001481 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001482 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Dan Willemsen93298ee2016-11-10 23:55:55 -08001483 EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
1484}
1485
Jiyong Parkdf202122019-09-30 20:48:35 +09001486TEST_F(AidlTest, WritesTrivialDependencyFileForParcelableDeclaration) {
Christopher Wileyb1bbdf82016-04-21 11:43:45 -07001487 // The SDK uses aidl to decide whether a .aidl file is a parcelable. It does
1488 // this by calling aidl with every .aidl file it finds, then parsing the
1489 // generated dependency files. Those that reference .java output files are
1490 // for interfaces and those that do not are parcelables. However, for both
1491 // parcelables and interfaces, we *must* generate a non-empty dependency file.
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001492 vector<string> args = {
1493 "aidl",
1494 "-o place/for/output",
1495 "-d dep/file/path",
1496 "p/Foo.aidl"};
1497 Options options = Options::From(args);
1498 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
Steven Moreland4e059132021-08-11 13:36:30 -07001499 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Christopher Wileyb1bbdf82016-04-21 11:43:45 -07001500 string actual_dep_file_contents;
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001501 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
Jiyong Parkdf202122019-09-30 20:48:35 +09001502 EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDeclarationDepFileContents);
1503}
1504
1505TEST_F(AidlTest, WritesDependencyFileForStructuredParcelable) {
1506 vector<string> args = {
1507 "aidl",
1508 "--structured",
1509 "-o place/for/output",
1510 "-d dep/file/path",
1511 "p/Foo.aidl"};
1512 Options options = Options::From(args);
1513 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo {int a;}");
Steven Moreland4e059132021-08-11 13:36:30 -07001514 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Parkdf202122019-09-30 20:48:35 +09001515 string actual_dep_file_contents;
1516 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1517 EXPECT_EQ(actual_dep_file_contents, kExpectedStructuredParcelableDepFileContents);
Christopher Wileyb1bbdf82016-04-21 11:43:45 -07001518}
1519
Jiyong Park9ca5c7e2019-10-17 15:01:14 +09001520TEST_F(AidlTest, NoJavaOutputForParcelableDeclaration) {
1521 vector<string> args = {
1522 "aidl",
1523 "--lang=java",
1524 "-o place/for/output",
1525 "p/Foo.aidl"};
1526 Options options = Options::From(args);
1527 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
Steven Moreland4e059132021-08-11 13:36:30 -07001528 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Park9ca5c7e2019-10-17 15:01:14 +09001529 string output_file_contents;
1530 EXPECT_FALSE(io_delegate_.GetWrittenContents(options.OutputFile(), &output_file_contents));
1531}
1532
Devin Moore21b26772020-08-26 16:37:56 -07001533TEST_P(AidlTest, RejectsListArray) {
Devin Moore6a01ca12020-08-28 10:24:19 -07001534 const string expected_stderr = "ERROR: a/Foo.aidl:2.1-7: List[] is not supported.\n";
Devin Moore21b26772020-08-26 16:37:56 -07001535 const string list_array_parcelable =
1536 "package a; parcelable Foo {\n"
1537 " List[] lists; }";
1538 CaptureStderr();
1539 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", list_array_parcelable, typenames_, GetLanguage()));
1540 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1541}
1542
Jiyong Parkf8d53612020-05-04 14:06:13 +09001543TEST_P(AidlTest, RejectsPrimitiveListInStableAidl) {
1544 AidlError error;
1545 string expected_stderr =
1546 "ERROR: a/IFoo.aidl:2.7-11: "
1547 "Encountered an untyped List or Map. The use of untyped List/Map is "
1548 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
1549 "the receiving side. Consider switching to an array or a generic List/Map.\n";
1550 if (GetLanguage() != Options::Language::JAVA) {
1551 expected_stderr =
1552 "ERROR: a/IFoo.aidl:2.1-7: "
1553 "Currently, only the Java backend supports non-generic List.\n";
1554 }
1555
1556 const string primitive_interface =
1557 "package a; interface IFoo {\n"
1558 " List foo(); }";
1559 CaptureStderr();
Jiyong Park40782d02020-07-24 19:17:43 +09001560 AidlTypenames tn1;
1561 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_interface, tn1, GetLanguage(), &error,
Jiyong Parkf8d53612020-05-04 14:06:13 +09001562 {"--structured"}));
1563 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkf8d53612020-05-04 14:06:13 +09001564
1565 string primitive_parcelable =
1566 "package a; parcelable IFoo {\n"
1567 " List foo;}";
1568 CaptureStderr();
Jiyong Park40782d02020-07-24 19:17:43 +09001569 AidlTypenames tn2;
1570 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_parcelable, tn2, GetLanguage(), &error,
Jiyong Parkf8d53612020-05-04 14:06:13 +09001571 {"--structured"}));
1572 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1573}
1574
Jeongik Cha225519b2020-08-29 01:55:32 +09001575TEST_P(AidlTest, ExtensionTest) {
1576 CaptureStderr();
Jeongik Cha649e8a72020-03-27 17:47:40 +09001577 string extendable_parcelable =
1578 "package a; parcelable Data {\n"
1579 " ParcelableHolder extension;\n"
1580 " ParcelableHolder extension2;\n"
1581 "}";
Jeongik Cha8f02a532020-10-14 00:16:28 +09001582 if (GetLanguage() == Options::Language::RUST) {
Jeongik Cha225519b2020-08-29 01:55:32 +09001583 EXPECT_EQ(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1584 EXPECT_EQ(
Jeongik Cha8f02a532020-10-14 00:16:28 +09001585 "ERROR: a/Data.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
Jeongik Cha225519b2020-08-29 01:55:32 +09001586 "yet.\n",
1587 GetCapturedStderr());
1588 } else {
1589 EXPECT_NE(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1590 EXPECT_EQ("", GetCapturedStderr());
1591 }
1592}
1593TEST_P(AidlTest, ParcelableHolderAsReturnType) {
1594 CaptureStderr();
Jeongik Cha649e8a72020-03-27 17:47:40 +09001595 string parcelableholder_return_interface =
1596 "package a; interface IFoo {\n"
1597 " ParcelableHolder foo();\n"
1598 "}";
Jeongik Cha225519b2020-08-29 01:55:32 +09001599 EXPECT_EQ(nullptr,
1600 Parse("a/IFoo.aidl", parcelableholder_return_interface, typenames_, GetLanguage()));
Jeongik Cha649e8a72020-03-27 17:47:40 +09001601
Jeongik Cha8f02a532020-10-14 00:16:28 +09001602 if (GetLanguage() == Options::Language::RUST) {
Jeongik Cha225519b2020-08-29 01:55:32 +09001603 EXPECT_EQ(
Steven Morelandebc3c5d2020-09-30 23:40:33 +00001604 "ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n"
Jeongik Cha8f02a532020-10-14 00:16:28 +09001605 "ERROR: a/IFoo.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
Jeongik Cha225519b2020-08-29 01:55:32 +09001606 "yet.\n",
1607 GetCapturedStderr());
1608 return;
1609 }
1610 EXPECT_EQ("ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n",
1611 GetCapturedStderr());
1612}
1613
1614TEST_P(AidlTest, ParcelableHolderAsArgumentType) {
1615 CaptureStderr();
Jeongik Cha649e8a72020-03-27 17:47:40 +09001616 string extendable_parcelable_arg_interface =
1617 "package a; interface IFoo {\n"
1618 " void foo(in ParcelableHolder ph);\n"
1619 "}";
Jeongik Cha225519b2020-08-29 01:55:32 +09001620 EXPECT_EQ(nullptr,
1621 Parse("a/IFoo.aidl", extendable_parcelable_arg_interface, typenames_, GetLanguage()));
1622
Jeongik Cha8f02a532020-10-14 00:16:28 +09001623 if (GetLanguage() == Options::Language::RUST) {
Jeongik Cha225519b2020-08-29 01:55:32 +09001624 EXPECT_EQ(
Steven Morelandebc3c5d2020-09-30 23:40:33 +00001625 "ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n"
Jeongik Cha8f02a532020-10-14 00:16:28 +09001626 "ERROR: a/IFoo.aidl:2.14-31: The Rust backend does not support ParcelableHolder "
Jeongik Cha225519b2020-08-29 01:55:32 +09001627 "yet.\n",
1628 GetCapturedStderr());
1629 return;
1630 }
1631 EXPECT_EQ("ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n",
1632 GetCapturedStderr());
Jeongik Cha649e8a72020-03-27 17:47:40 +09001633}
1634
Jeongik Chaf6ec8982020-10-15 00:10:30 +09001635TEST_P(AidlTest, RejectNullableParcelableHolderField) {
1636 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { @nullable ParcelableHolder ext; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09001637 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jeongik Chaf6ec8982020-10-15 00:10:30 +09001638 const string expected_stderr = "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n";
1639 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001640 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jeongik Chaf6ec8982020-10-15 00:10:30 +09001641 if (GetLanguage() == Options::Language::RUST) {
1642 EXPECT_EQ(
1643 "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n"
1644 "ERROR: Foo.aidl:1.27-44: The Rust backend does not support ParcelableHolder "
1645 "yet.\n",
1646 GetCapturedStderr());
1647 return;
1648 }
1649 EXPECT_EQ(expected_stderr, GetCapturedStderr());
1650}
1651
Jooyung Han3f347ca2020-12-01 12:41:50 +09001652TEST_P(AidlTest, ParcelablesWithConstants) {
1653 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { const int BIT = 0x1 << 3; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09001654 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jooyung Han3f347ca2020-12-01 12:41:50 +09001655 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001656 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han3f347ca2020-12-01 12:41:50 +09001657 EXPECT_EQ("", GetCapturedStderr());
1658}
1659
1660TEST_P(AidlTest, UnionWithConstants) {
1661 io_delegate_.SetFileContents("Foo.aidl", "union Foo { const int BIT = 0x1 << 3; int n; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09001662 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jooyung Han3f347ca2020-12-01 12:41:50 +09001663 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001664 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han3f347ca2020-12-01 12:41:50 +09001665 EXPECT_EQ("", GetCapturedStderr());
1666}
1667
Jooyung Han633eab62021-01-07 14:12:40 +09001668TEST_F(AidlTest, ConstantsWithAnnotations) {
1669 io_delegate_.SetFileContents("IFoo.aidl",
1670 "interface IFoo {\n"
1671 " @JavaPassthrough(annotation=\"@Foo\")\n"
1672 " const @JavaPassthrough(annotation=\"@Bar\") int FOO = 0;\n"
1673 "}");
1674 Options options = Options::From("aidl IFoo.aidl --lang=java -o out");
1675 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001676 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han633eab62021-01-07 14:12:40 +09001677 EXPECT_EQ("", GetCapturedStderr());
1678 string code;
1679 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/IFoo.java", &code));
1680 EXPECT_THAT(code, HasSubstr("@Foo\n"));
1681 EXPECT_THAT(code, HasSubstr("@Bar\n"));
1682}
1683
Jiyong Park02da7422018-07-16 16:00:26 +09001684TEST_F(AidlTest, ApiDump) {
1685 io_delegate_.SetFileContents(
1686 "foo/bar/IFoo.aidl",
1687 "package foo.bar;\n"
1688 "import foo.bar.Data;\n"
Jooyung Han24effbf2021-01-16 10:24:03 +09001689 "// commented /* @hide */\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001690 "interface IFoo {\n"
Jooyung Han161bb0f2021-01-21 12:30:16 +09001691 " /* @hide applied \n"
1692 " @deprecated use foo2 */\n"
1693 " int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
1694 " int foo2(@utf8InCpp String x, inout List<String> y);\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001695 " IFoo foo3(IFoo foo);\n"
1696 " Data getData();\n"
Jooyung Han161bb0f2021-01-21 12:30:16 +09001697 " // @hide not applied\n"
Jooyung Han9fd67022021-01-13 10:49:48 +09001698 " /** blahblah\n"
1699 " @deprecated\n"
1700 " reason why... */\n"
Jiyong Parka428d212018-08-29 22:26:30 +09001701 " const int A = 1;\n"
Jooyung Han24effbf2021-01-16 10:24:03 +09001702 " // @deprecated tags in line comments are ignored\n"
Jiyong Parka428d212018-08-29 22:26:30 +09001703 " const String STR = \"Hello\";\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001704 "}\n");
1705 io_delegate_.SetFileContents("foo/bar/Data.aidl",
1706 "package foo.bar;\n"
1707 "import foo.bar.IFoo;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001708 "/* @hide*/\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001709 "parcelable Data {\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001710 " // @hide\n"
Jiyong Parka468e2a2018-08-29 21:25:18 +09001711 " int x = 10;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001712 " // @hide\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001713 " int y;\n"
Jeongik Cha997281d2020-01-16 15:23:59 +09001714 " /*@hide2*/\n"
Jooyung Han55f96ad2020-12-13 10:08:33 +09001715 " IFoo foo;\n"
Jooyung Han24effbf2021-01-16 10:24:03 +09001716 " // Ignore @hide property in line comment\n"
Jeongik Cha3271ffa2018-12-04 15:19:20 +09001717 " @nullable String[] c;\n"
Jiyong Park02da7422018-07-16 16:00:26 +09001718 "}\n");
1719 io_delegate_.SetFileContents("api.aidl", "");
Jiyong Park633246c2019-11-25 10:50:05 +09001720 vector<string> args = {"aidl", "--dumpapi", "--out=dump", "--include=.",
1721 "foo/bar/IFoo.aidl", "foo/bar/Data.aidl"};
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001722 Options options = Options::From(args);
Jiyong Park02da7422018-07-16 16:00:26 +09001723 bool result = dump_api(options, io_delegate_);
1724 ASSERT_TRUE(result);
1725 string actual;
Jiyong Parke59c3682018-09-11 23:10:25 +09001726 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
Jooyung Han161bb0f2021-01-21 12:30:16 +09001727 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
Jiyong Parke59c3682018-09-11 23:10:25 +09001728interface IFoo {
Jooyung Han161bb0f2021-01-21 12:30:16 +09001729 /**
1730 * @hide
1731 * @deprecated use foo2
1732 */
Jiyong Parke59c3682018-09-11 23:10:25 +09001733 int foo(out int[] a, String b, boolean c, inout List<String> d);
1734 int foo2(@utf8InCpp String x, inout List<String> y);
1735 foo.bar.IFoo foo3(foo.bar.IFoo foo);
1736 foo.bar.Data getData();
Jooyung Han161bb0f2021-01-21 12:30:16 +09001737 /**
1738 * @deprecated reason why...
1739 */
Jiyong Parke59c3682018-09-11 23:10:25 +09001740 const int A = 1;
1741 const String STR = "Hello";
1742}
Jooyung Han161bb0f2021-01-21 12:30:16 +09001743)"),
1744 actual);
Jiyong Park02da7422018-07-16 16:00:26 +09001745
Jiyong Parke59c3682018-09-11 23:10:25 +09001746 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
Jooyung Han161bb0f2021-01-21 12:30:16 +09001747 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
Jooyung Han8db65942021-03-02 18:14:44 +09001748/* @hide */
Jiyong Parke59c3682018-09-11 23:10:25 +09001749parcelable Data {
1750 int x = 10;
1751 int y;
1752 foo.bar.IFoo foo;
Jeongik Cha3271ffa2018-12-04 15:19:20 +09001753 @nullable String[] c;
Jiyong Park02da7422018-07-16 16:00:26 +09001754}
Jooyung Han161bb0f2021-01-21 12:30:16 +09001755)"),
1756 actual);
Jiyong Park02da7422018-07-16 16:00:26 +09001757}
1758
Jiyong Parked65bf42018-08-28 15:43:27 +09001759TEST_F(AidlTest, ApiDumpWithManualIds) {
1760 io_delegate_.SetFileContents(
1761 "foo/bar/IFoo.aidl",
1762 "package foo.bar;\n"
1763 "interface IFoo {\n"
1764 " int foo() = 1;\n"
1765 " int bar() = 2;\n"
1766 " int baz() = 10;\n"
1767 "}\n");
1768
Jiyong Parke59c3682018-09-11 23:10:25 +09001769 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
Jiyong Parked65bf42018-08-28 15:43:27 +09001770 Options options = Options::From(args);
1771 bool result = dump_api(options, io_delegate_);
1772 ASSERT_TRUE(result);
1773 string actual;
Jiyong Parke59c3682018-09-11 23:10:25 +09001774 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
Paul Trautrimb01451d2020-02-27 13:10:16 +09001775 EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
Jiyong Parke59c3682018-09-11 23:10:25 +09001776interface IFoo {
1777 int foo() = 1;
1778 int bar() = 2;
1779 int baz() = 10;
Jiyong Parked65bf42018-08-28 15:43:27 +09001780}
Paul Trautrimb01451d2020-02-27 13:10:16 +09001781)"));
Jiyong Parked65bf42018-08-28 15:43:27 +09001782}
1783
1784TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001785 const string expected_stderr =
1786 "ERROR: foo/bar/IFoo.aidl:4.8-12: You must either assign id's to all methods or to none of "
1787 "them.\n";
Jiyong Parked65bf42018-08-28 15:43:27 +09001788 io_delegate_.SetFileContents(
1789 "foo/bar/IFoo.aidl",
1790 "package foo.bar;\n"
1791 "interface IFoo {\n"
1792 " int foo() = 1;\n"
1793 " int bar();\n"
1794 " int baz() = 10;\n"
1795 "}\n");
1796
Jiyong Parke59c3682018-09-11 23:10:25 +09001797 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
Jiyong Parked65bf42018-08-28 15:43:27 +09001798 Options options = Options::From(args);
Devin Moore097a3ab2020-03-11 16:08:44 -07001799 CaptureStderr();
Jiyong Parked65bf42018-08-28 15:43:27 +09001800 EXPECT_FALSE(dump_api(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001801 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parked65bf42018-08-28 15:43:27 +09001802}
1803
Jooyung Han965e31d2020-11-27 12:30:16 +09001804TEST_F(AidlTest, ApiDumpConstWithAnnotation) {
1805 io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
1806 "package foo.bar;\n"
1807 "interface IFoo {\n"
1808 " @utf8InCpp String foo();\n"
1809 " const @utf8InCpp String bar = \"bar\";\n"
1810 "}\n");
1811
1812 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1813 Options options = Options::From(args);
1814 CaptureStderr();
1815 EXPECT_TRUE(dump_api(options, io_delegate_));
1816 EXPECT_EQ("", GetCapturedStderr());
1817 string actual;
1818 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
Jooyung Han965e31d2020-11-27 12:30:16 +09001819 EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1820interface IFoo {
1821 @utf8InCpp String foo();
Jooyung Hanb3ca6302020-11-27 14:13:27 +09001822 const @utf8InCpp String bar = "bar";
Jooyung Han965e31d2020-11-27 12:30:16 +09001823}
1824)"),
1825 actual);
1826}
1827
Jooyung Hanfdaae1d2020-12-14 13:16:15 +09001828TEST_F(AidlTest, ApiDumpWithEnums) {
1829 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1830 "package foo.bar;\n"
1831 "enum Enum {\n"
1832 " FOO,\n"
1833 " BAR = FOO + 1,\n"
1834 "}\n");
1835
1836 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Enum.aidl"};
1837 Options options = Options::From(args);
1838 CaptureStderr();
1839 EXPECT_TRUE(dump_api(options, io_delegate_));
1840 EXPECT_EQ("", GetCapturedStderr());
1841 string actual;
1842 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
1843 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1844 "enum Enum {\n"
1845 " FOO = 0,\n"
1846 " BAR = 1,\n"
1847 "}\n"),
1848 actual);
1849}
1850
1851TEST_F(AidlTest, ApiDumpWithEnumDefaultValues) {
1852 io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1853 "package foo.bar;\n"
1854 "enum Enum {\n"
1855 " FOO,\n"
1856 "}\n");
1857 io_delegate_.SetFileContents("foo/bar/Foo.aidl",
1858 "package foo.bar;\n"
1859 "import foo.bar.Enum;\n"
1860 "parcelable Foo {\n"
1861 " Enum e = Enum.FOO;\n"
1862 "}\n");
1863
1864 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
1865 Options options = Options::From(args);
1866 CaptureStderr();
1867 EXPECT_TRUE(dump_api(options, io_delegate_));
1868 EXPECT_EQ("", GetCapturedStderr());
1869 string actual;
1870 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
1871 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1872 "parcelable Foo {\n"
1873 " foo.bar.Enum e = foo.bar.Enum.FOO;\n"
1874 "}\n"),
1875 actual);
1876}
1877
Jooyung Han71dfec32021-05-23 07:18:58 +09001878TEST_F(AidlTest, ApiDumpWithGenerics) {
1879 io_delegate_.SetFileContents("foo/bar/Foo.aidl",
1880 "package foo.bar;\n"
1881 "parcelable Foo<T, U> {\n"
1882 "}\n");
1883
1884 vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
1885 Options options = Options::From(args);
1886 CaptureStderr();
1887 EXPECT_TRUE(dump_api(options, io_delegate_));
1888 EXPECT_EQ("", GetCapturedStderr());
1889 string actual;
1890 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
1891 EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1892 "parcelable Foo<T, U> {\n"
1893 "}\n"),
1894 actual);
1895}
1896
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001897TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001898 const string expected_list_stderr =
Steven Morelandebc3c5d2020-09-30 23:40:33 +00001899 "ERROR: p/IFoo.aidl:1.37-41: List can only have one type parameter, but got: "
1900 "'List<String,String>'\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07001901 const string expected_map_stderr =
1902 "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 +09001903 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1904 io_delegate_.SetFileContents(options.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001905 "package p; interface IFoo {"
1906 "void foo(List<String, String> a);}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001907 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001908 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001909 EXPECT_EQ(expected_list_stderr, GetCapturedStderr());
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001910
Jiyong Park6f77e0c2018-07-28 16:55:44 +09001911 io_delegate_.SetFileContents(options.InputFiles().front(),
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001912 "package p; interface IFoo {"
1913 "void foo(Map<String> a);}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001914 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001915 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001916 EXPECT_EQ(expected_map_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09001917}
1918
Jeongik Chae48d9942020-01-02 17:39:00 +09001919TEST_F(AidlTest, CheckTypeParameterInMapType) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001920 const string expected_stderr =
1921 "ERROR: p/IFoo.aidl:1.28-31: The type of key in map must be String, but it is 'p.Bar'\n";
Jooyung Han13f1fa52021-06-11 18:06:12 +09001922 Options options = Options::From("aidl -I . p/IFoo.aidl");
Jeongik Chae48d9942020-01-02 17:39:00 +09001923 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar { String s; }");
1924
1925 io_delegate_.SetFileContents("p/IFoo.aidl",
1926 "package p; interface IFoo {"
Jooyung Han13f1fa52021-06-11 18:06:12 +09001927 "Map<String, p.Bar> foo();}");
Steven Moreland4e059132021-08-11 13:36:30 -07001928 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jeongik Chae48d9942020-01-02 17:39:00 +09001929
1930 io_delegate_.SetFileContents("p/IFoo.aidl",
1931 "package p; interface IFoo {"
Jooyung Han13f1fa52021-06-11 18:06:12 +09001932 "Map<p.Bar, p.Bar> foo();}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001933 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001934 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001935 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jeongik Chae48d9942020-01-02 17:39:00 +09001936
1937 io_delegate_.SetFileContents("p/IFoo.aidl",
1938 "package p; interface IFoo {"
1939 "Map<String, String> foo();}");
Steven Moreland4e059132021-08-11 13:36:30 -07001940 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jeongik Chae48d9942020-01-02 17:39:00 +09001941
1942 io_delegate_.SetFileContents("p/IFoo.aidl",
1943 "package p; interface IFoo {"
1944 "Map<String, ParcelFileDescriptor> foo();}");
Steven Moreland4e059132021-08-11 13:36:30 -07001945 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jeongik Chae48d9942020-01-02 17:39:00 +09001946}
1947
Jeongik Chadf76dc72019-11-28 00:08:47 +09001948TEST_F(AidlTest, WrongGenericType) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001949 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 +09001950 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1951 io_delegate_.SetFileContents(options.InputFiles().front(),
1952 "package p; interface IFoo {"
1953 "String<String> foo(); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07001954 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001955 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001956 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jeongik Chadf76dc72019-11-28 00:08:47 +09001957}
1958
1959TEST_F(AidlTest, UserDefinedUnstructuredGenericParcelableType) {
Jooyung Han13f1fa52021-06-11 18:06:12 +09001960 Options optionsForParcelable = Options::From("aidl -I . p/Bar.aidl");
Jeongik Chadf76dc72019-11-28 00:08:47 +09001961 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, T>;");
Devin Moore097a3ab2020-03-11 16:08:44 -07001962 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001963 EXPECT_FALSE(compile_aidl(optionsForParcelable, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07001964 EXPECT_EQ("ERROR: p/Bar.aidl:1.22-26: Every type parameter should be unique.\n",
1965 GetCapturedStderr());
Jeongik Chadf76dc72019-11-28 00:08:47 +09001966
Jooyung Han13f1fa52021-06-11 18:06:12 +09001967 Options options = Options::From("aidl -I . p/IFoo.aidl");
Jeongik Chadf76dc72019-11-28 00:08:47 +09001968 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar;");
1969 io_delegate_.SetFileContents("p/IFoo.aidl",
1970 "package p; interface IFoo {"
Jooyung Han13f1fa52021-06-11 18:06:12 +09001971 "p.Bar<String, String> foo();}");
Devin Moore097a3ab2020-03-11 16:08:44 -07001972 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001973 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han13f1fa52021-06-11 18:06:12 +09001974 EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar is not a generic type"));
Jeongik Chadf76dc72019-11-28 00:08:47 +09001975 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T>;");
Devin Moore097a3ab2020-03-11 16:08:44 -07001976 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07001977 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han13f1fa52021-06-11 18:06:12 +09001978 EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar must have 1 type parameters, but got 2"));
Jeongik Chadf76dc72019-11-28 00:08:47 +09001979 io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, V>;");
Steven Moreland4e059132021-08-11 13:36:30 -07001980 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jeongik Chadf76dc72019-11-28 00:08:47 +09001981 io_delegate_.SetFileContents("p/IFoo.aidl",
1982 "package p; interface IFoo {"
Jooyung Han13f1fa52021-06-11 18:06:12 +09001983 "p.Bar<String, ParcelFileDescriptor> foo();}");
Steven Moreland4e059132021-08-11 13:36:30 -07001984 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jeongik Chae74c86d2019-12-12 16:54:03 +09001985
1986 io_delegate_.SetFileContents("p/IFoo.aidl",
1987 "package p; interface IFoo {"
Jooyung Han13f1fa52021-06-11 18:06:12 +09001988 "p.Bar<int, long> foo();}");
Jeongik Chae74c86d2019-12-12 16:54:03 +09001989
1990 io_delegate_.SetFileContents("p/IFoo.aidl",
1991 "package p; interface IFoo {"
Jooyung Han13f1fa52021-06-11 18:06:12 +09001992 "p.Bar<int[], long[]> foo();}");
Jeongik Chae74c86d2019-12-12 16:54:03 +09001993
Steven Moreland4e059132021-08-11 13:36:30 -07001994 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jeongik Chadf76dc72019-11-28 00:08:47 +09001995}
1996
Jeongik Cha0e426012019-07-29 15:57:02 +09001997TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
1998 std::vector<std::string> rawOptions{"aidl --lang=java -o out foo/bar/Foo.aidl",
Andrei Homescub62afd92020-05-11 19:24:59 -07001999 "aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl",
2000 "aidl --lang=rust -o out foo/bar/Foo.aidl"};
Devin Moore5de18ed2020-04-02 13:52:29 -07002001 for (const auto& rawOption : rawOptions) {
2002 string expected_stderr =
2003 "ERROR: foo/bar/Foo.aidl:3.1-10: You must declare only one type per file.\n";
Jeongik Cha0e426012019-07-29 15:57:02 +09002004 Options options = Options::From(rawOption);
2005 io_delegate_.SetFileContents(options.InputFiles().front(),
2006 "package foo.bar;\n"
2007 "interface IFoo1 { int foo(); }\n"
2008 "interface IFoo2 { int foo(); }\n"
2009 "parcelable Data1 { int a; int b;}\n"
2010 "parcelable Data2 { int a; int b;}\n");
Devin Moore097a3ab2020-03-11 16:08:44 -07002011 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07002012 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002013 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09002014
Jeongik Cha0e426012019-07-29 15:57:02 +09002015 io_delegate_.SetFileContents(options.InputFiles().front(),
2016 "package foo.bar;\n"
2017 "interface IFoo1 { int foo(); }\n"
2018 "interface IFoo2 { int foo(); }\n");
Devin Moore097a3ab2020-03-11 16:08:44 -07002019 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07002020 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002021 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09002022
Devin Moore5de18ed2020-04-02 13:52:29 -07002023 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 +09002024 io_delegate_.SetFileContents(options.InputFiles().front(),
2025 "package foo.bar;\n"
2026 "parcelable Data1 { int a; int b;}\n"
2027 "parcelable Data2 { int a; int b;}\n");
Devin Moore097a3ab2020-03-11 16:08:44 -07002028 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07002029 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002030 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkb034bf02018-07-30 17:44:33 +09002031 }
2032}
2033
Devin Moorebdba2a82020-03-31 15:19:02 -07002034TEST_P(AidlTest, FailParseOnEmptyFile) {
2035 const string contents = "";
2036 const string expected_stderr = "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected $end\n";
2037 CaptureStderr();
2038 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", contents, typenames_, GetLanguage()));
2039 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2040}
2041
Jiyong Parkb034bf02018-07-30 17:44:33 +09002042TEST_F(AidlTest, MultipleInputFiles) {
2043 Options options = Options::From(
Jiyong Park633246c2019-11-25 10:50:05 +09002044 "aidl --lang=java -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
Jiyong Parkb034bf02018-07-30 17:44:33 +09002045
2046 io_delegate_.SetFileContents(options.InputFiles().at(0),
2047 "package foo.bar;\n"
2048 "import foo.bar.Data;\n"
2049 "interface IFoo { Data getData(); }\n");
2050
2051 io_delegate_.SetFileContents(options.InputFiles().at(1),
2052 "package foo.bar;\n"
2053 "import foo.bar.IFoo;\n"
2054 "parcelable Data { IFoo foo; }\n");
2055
Steven Moreland4e059132021-08-11 13:36:30 -07002056 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Parkb034bf02018-07-30 17:44:33 +09002057
2058 string content;
2059 for (const auto file : {
2060 "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
2061 content.clear();
2062 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2063 EXPECT_FALSE(content.empty());
2064 }
2065}
2066
2067TEST_F(AidlTest, MultipleInputFilesCpp) {
2068 Options options = Options::From("aidl --lang=cpp -o out -h out/include "
Jiyong Park633246c2019-11-25 10:50:05 +09002069 "-I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
Jiyong Parkb034bf02018-07-30 17:44:33 +09002070
2071 io_delegate_.SetFileContents(options.InputFiles().at(0),
2072 "package foo.bar;\n"
2073 "import foo.bar.Data;\n"
2074 "interface IFoo { Data getData(); }\n");
2075
2076 io_delegate_.SetFileContents(options.InputFiles().at(1),
2077 "package foo.bar;\n"
2078 "import foo.bar.IFoo;\n"
2079 "parcelable Data { IFoo foo; }\n");
2080
Steven Moreland4e059132021-08-11 13:36:30 -07002081 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Parkb034bf02018-07-30 17:44:33 +09002082
2083 string content;
2084 for (const auto file : {
Jiyong Parkb03551f2018-08-06 19:20:51 +09002085 "out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp",
Jiyong Parkb034bf02018-07-30 17:44:33 +09002086 "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
2087 "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
2088 "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
2089 content.clear();
2090 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2091 EXPECT_FALSE(content.empty());
2092 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +09002093}
2094
Andrei Homescub62afd92020-05-11 19:24:59 -07002095TEST_F(AidlTest, MultipleInputFilesRust) {
2096 Options options =
2097 Options::From("aidl --lang=rust -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2098
2099 io_delegate_.SetFileContents(options.InputFiles().at(0),
2100 "package foo.bar;\n"
2101 "import foo.bar.Data;\n"
2102 "interface IFoo { Data getData(); }\n");
2103
2104 io_delegate_.SetFileContents(options.InputFiles().at(1),
2105 "package foo.bar;\n"
2106 "import foo.bar.IFoo;\n"
2107 "parcelable Data { IFoo foo; }\n");
2108
Steven Moreland4e059132021-08-11 13:36:30 -07002109 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Andrei Homescub62afd92020-05-11 19:24:59 -07002110
2111 string content;
2112 for (const auto file : {"out/foo/bar/IFoo.rs", "out/foo/bar/Data.rs"}) {
2113 content.clear();
2114 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2115 EXPECT_FALSE(content.empty());
2116 }
2117}
2118
Devin Moore097a3ab2020-03-11 16:08:44 -07002119TEST_F(AidlTest, ConflictWithMetaTransactionGetVersion) {
2120 const string expected_stderr =
2121 "ERROR: p/IFoo.aidl:1.31-51: method getInterfaceVersion() is reserved for internal use.\n";
Jiyong Park309668e2018-07-28 16:55:44 +09002122 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
2123 // int getInterfaceVersion() is one of the meta transactions
2124 io_delegate_.SetFileContents(options.InputFiles().front(),
2125 "package p; interface IFoo {"
2126 "int getInterfaceVersion(); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002127 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07002128 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002129 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2130}
Jiyong Park309668e2018-07-28 16:55:44 +09002131
Devin Moore097a3ab2020-03-11 16:08:44 -07002132TEST_F(AidlTest, ConflictWithSimilarMetaTransaction) {
2133 // boolean getInterfaceVersion() is not a meta transaction, but should be
2134 // prevented because return type is not part of a method signature
2135 const string expected_stderr =
2136 "ERROR: p/IFoo.aidl:1.35-55: method getInterfaceVersion() is reserved for internal use.\n";
2137 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
Jiyong Park309668e2018-07-28 16:55:44 +09002138 io_delegate_.SetFileContents(options.InputFiles().front(),
2139 "package p; interface IFoo {"
2140 "boolean getInterfaceVersion(); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002141 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07002142 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002143 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2144}
Jiyong Park309668e2018-07-28 16:55:44 +09002145
Devin Moore097a3ab2020-03-11 16:08:44 -07002146TEST_F(AidlTest, ConflictWithMetaTransactionGetName) {
Jiyong Park309668e2018-07-28 16:55:44 +09002147 // this is another reserved name
Devin Moore097a3ab2020-03-11 16:08:44 -07002148 const string expected_stderr =
2149 "ERROR: p/IFoo.aidl:1.34-53: method getTransactionName(int) is reserved for internal use.\n";
2150 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
Jiyong Park309668e2018-07-28 16:55:44 +09002151 io_delegate_.SetFileContents(options.InputFiles().front(),
2152 "package p; interface IFoo {"
2153 "String getTransactionName(int code); }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002154 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07002155 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002156 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park309668e2018-07-28 16:55:44 +09002157
2158 // this is not a meta interface method as it differs type arguments
2159 io_delegate_.SetFileContents(options.InputFiles().front(),
2160 "package p; interface IFoo {"
2161 "String getTransactionName(); }");
Steven Moreland4e059132021-08-11 13:36:30 -07002162 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Park309668e2018-07-28 16:55:44 +09002163}
2164
Jooyung Hanb8a97772021-01-19 01:27:38 +09002165TEST_F(AidlTest, CheckApiForEquality) {
2166 CaptureStderr();
2167 Options options = Options::From("aidl --checkapi=equal old new");
2168
2169 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2170 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
2171 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2172 "package p; interface IFoo{ @utf8InCpp String foo();}");
2173
2174 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
2175 EXPECT_THAT(GetCapturedStderr(), HasSubstr("+ @utf8InCpp String foo();"));
2176}
2177
Daniel Norman85aed542019-08-21 12:01:14 -07002178TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
Jeongik Cha3271ffa2018-12-04 15:19:20 +09002179 Options options = Options::From("aidl --checkapi old new");
2180 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2181 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
2182 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2183 "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
2184
2185 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2186}
2187
Jiyong Park3656c3c2018-08-01 20:02:01 +09002188TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002189 Options options = Options::From("aidl --checkapi old new");
2190 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
2191 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
Jiyong Park3656c3c2018-08-01 20:02:01 +09002192
2193 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2194}
2195
Jooyung Hanfdaae1d2020-12-14 13:16:15 +09002196TEST_F(AidlTest, CheckApi_EnumFieldsWithDefaultValues) {
2197 Options options = Options::From("aidl --checkapi old new");
2198 const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
2199 const string enum_definition = "package p; enum Enum { FOO }";
2200 io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
2201 io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
2202 io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
2203 io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
2204
2205 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2206}
2207
Jooyung Han8e3b72c2021-05-22 02:54:37 +09002208TEST_F(AidlTest, CheckApi_EnumFieldsFromImported) {
2209 Options options = Options::From("aidl --checkapi old new -I import");
2210
2211 io_delegate_.SetFileContents("old/p/Foo.aidl", "package p; parcelable Foo{ other.Enum e; }");
2212 io_delegate_.SetFileContents("new/p/Foo.aidl",
2213 "package p; parcelable Foo{ other.Enum e = other.Enum.FOO; }");
2214 io_delegate_.SetFileContents("import/other/Enum.aidl", "package other; enum Enum { FOO }");
2215
2216 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2217}
2218
Jooyung Han02a11be2021-02-11 13:18:06 +09002219TEST_F(AidlTest, CheckApiEqual_EnumFieldsWithDefaultValues) {
2220 Options options = Options::From("aidl --checkapi=equal old new");
2221 const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
2222 const string enum_definition = "package p; enum Enum { FOO }";
2223 io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
2224 io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
2225 io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
2226 io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
2227 CaptureStderr();
2228 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2229 EXPECT_EQ("", GetCapturedStderr());
2230}
2231
Daniel Norman85aed542019-08-21 12:01:14 -07002232class AidlTestCompatibleChanges : public AidlTest {
2233 protected:
2234 Options options_ = Options::From("aidl --checkapi old new");
2235};
2236
2237TEST_F(AidlTestCompatibleChanges, NewType) {
2238 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2239 "package p;"
2240 "interface IFoo {"
2241 " void foo(int a);"
2242 "}");
2243 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2244 "package p;"
2245 "interface IFoo {"
2246 " void foo(int a);"
2247 "}");
2248 io_delegate_.SetFileContents("new/p/IBar.aidl",
2249 "package p;"
2250 "interface IBar {"
2251 " void bar();"
2252 "}");
2253 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2254}
2255
2256TEST_F(AidlTestCompatibleChanges, NewMethod) {
2257 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2258 "package p;"
2259 "interface IFoo {"
2260 " void foo(int a);"
2261 "}");
2262 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2263 "package p;"
2264 "interface IFoo {"
2265 " void foo(int a);"
2266 " void bar();"
Jooyung Han8e3b72c2021-05-22 02:54:37 +09002267 " void baz(in List<String> arg);"
Daniel Norman85aed542019-08-21 12:01:14 -07002268 "}");
2269 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2270}
2271
2272TEST_F(AidlTestCompatibleChanges, NewField) {
2273 io_delegate_.SetFileContents("old/p/Data.aidl",
2274 "package p;"
2275 "parcelable Data {"
2276 " int foo;"
2277 "}");
2278 io_delegate_.SetFileContents("new/p/Data.aidl",
2279 "package p;"
2280 "parcelable Data {"
2281 " int foo;"
Steven Moreland370ed342020-04-28 18:14:39 -07002282 " int bar = 0;"
Jiyong Parkf8d53612020-05-04 14:06:13 +09002283 " @nullable List<Data> list;"
Daniel Norman85aed542019-08-21 12:01:14 -07002284 "}");
2285 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2286}
2287
Jooyung Han05bd8a82021-04-28 23:56:38 +09002288TEST_F(AidlTestCompatibleChanges, NewField2) {
2289 io_delegate_.SetFileContents("old/p/Data.aidl",
2290 "package p;"
2291 "parcelable Data {"
2292 "}");
2293 io_delegate_.SetFileContents("new/p/Data.aidl",
2294 "package p;"
2295 "parcelable Data {"
2296 " int foo = 0;"
2297 "}");
2298 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2299}
2300
Daniel Norman85aed542019-08-21 12:01:14 -07002301TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
2302 io_delegate_.SetFileContents("old/p/Enum.aidl",
2303 "package p;"
2304 "enum Enum {"
2305 " FOO = 1,"
2306 "}");
2307 io_delegate_.SetFileContents("new/p/Enum.aidl",
2308 "package p;"
2309 "enum Enum {"
2310 " FOO = 1,"
2311 " BAR = 2,"
2312 "}");
2313 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2314}
2315
2316TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
2317 io_delegate_.SetFileContents("old/p/Enum.aidl",
2318 "package p;"
2319 "enum Enum {"
2320 " FOO = 1,"
2321 " BAR = 2,"
2322 "}");
2323 io_delegate_.SetFileContents("new/p/Enum.aidl",
2324 "package p;"
2325 "enum Enum {"
2326 " BAR = 2,"
2327 " FOO = 1,"
2328 "}");
2329 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2330}
2331
Jooyung Hanb5c55cd2020-10-22 07:59:01 +09002332TEST_F(AidlTestCompatibleChanges, NewUnionField) {
2333 io_delegate_.SetFileContents("old/p/Union.aidl",
2334 "package p;"
2335 "union Union {"
2336 " String foo;"
2337 "}");
2338 io_delegate_.SetFileContents("new/p/Union.aidl",
2339 "package p;"
2340 "union Union {"
2341 " String foo;"
2342 " int num;"
2343 "}");
2344 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2345}
2346
Daniel Norman85aed542019-08-21 12:01:14 -07002347TEST_F(AidlTestCompatibleChanges, NewPackage) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002348 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2349 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002350 "interface IFoo {"
2351 " void foo(int a);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002352 "}");
2353 io_delegate_.SetFileContents("old/p/Data.aidl",
2354 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002355 "parcelable Data {"
2356 " int foo;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002357 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002358 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2359 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002360 "interface IFoo {"
2361 " void foo(int a);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002362 "}");
2363 io_delegate_.SetFileContents("new/p/Data.aidl",
2364 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002365 "parcelable Data {"
2366 " int foo;"
Jiyong Parke59c3682018-09-11 23:10:25 +09002367 "}");
2368 io_delegate_.SetFileContents("new/q/IFoo.aidl",
2369 "package q;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002370 "interface IFoo {"
Jiyong Parke59c3682018-09-11 23:10:25 +09002371 " void foo(int a);"
2372 "}");
2373 io_delegate_.SetFileContents("new/q/Data.aidl",
2374 "package q;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002375 "parcelable Data {"
2376 " int foo;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002377 "}");
Daniel Norman85aed542019-08-21 12:01:14 -07002378 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2379}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002380
Daniel Norman85aed542019-08-21 12:01:14 -07002381TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
2382 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2383 "package p;"
2384 "interface IFoo {"
2385 " void foo(int a);"
2386 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002387 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2388 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002389 "interface IFoo {"
2390 " void foo(int b);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002391 "}");
Daniel Norman85aed542019-08-21 12:01:14 -07002392 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2393}
Jiyong Parke59c3682018-09-11 23:10:25 +09002394
Daniel Norman85aed542019-08-21 12:01:14 -07002395TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002396 io_delegate_.SetFileContents("old/p/I.aidl",
2397 "package p; interface I {"
2398 "const int A = 1; }");
2399 io_delegate_.SetFileContents("new/p/I.aidl",
2400 "package p ; interface I {"
2401 "const int A = 1; const int B = 2;}");
Daniel Norman85aed542019-08-21 12:01:14 -07002402 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2403}
Jiyong Parka428d212018-08-29 22:26:30 +09002404
Daniel Norman85aed542019-08-21 12:01:14 -07002405TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
Jiyong Parke59c3682018-09-11 23:10:25 +09002406 io_delegate_.SetFileContents("old/p/I.aidl",
2407 "package p; interface I {"
2408 "const int A = 1; const int B = 2;}");
2409 io_delegate_.SetFileContents("new/p/I.aidl",
2410 "package p ; interface I {"
2411 "const int B = 2; const int A = 1;}");
Daniel Norman85aed542019-08-21 12:01:14 -07002412 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
Jiyong Park3656c3c2018-08-01 20:02:01 +09002413}
2414
Jooyung Han69ea4ba2020-10-29 15:33:37 +09002415TEST_F(AidlTestCompatibleChanges, ReorderedAnnatations) {
2416 io_delegate_.SetFileContents("old/p/Foo.aidl",
2417 "package p;"
2418 "@JavaPassthrough(annotation=\"Alice\")"
2419 "@JavaPassthrough(annotation=\"Bob\")"
2420 "parcelable Foo {}");
2421 io_delegate_.SetFileContents("new/p/Foo.aidl",
2422 "package p;"
2423 "@JavaPassthrough(annotation=\"Bob\")"
2424 "@JavaPassthrough(annotation=\"Alice\")"
2425 "parcelable Foo {}");
2426 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2427}
2428
Jooyung Han00073272020-11-27 14:20:20 +09002429TEST_F(AidlTestCompatibleChanges, OkayToDeprecate) {
2430 io_delegate_.SetFileContents("old/p/Foo.aidl",
2431 "package p;"
2432 "parcelable Foo {}");
2433 io_delegate_.SetFileContents("new/p/Foo.aidl",
2434 "package p;"
2435 "@JavaPassthrough(annotation=\"@Deprecated\")"
2436 "parcelable Foo {}");
2437 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2438}
2439
Jooyung Han636fd2f2020-10-22 11:33:45 +09002440TEST_F(AidlTestCompatibleChanges, NewFieldOfNewType) {
2441 io_delegate_.SetFileContents("old/p/Data.aidl",
2442 "package p;"
2443 "parcelable Data {"
2444 " int num;"
2445 "}");
2446 io_delegate_.SetFileContents(
2447 "new/p/Data.aidl",
2448 "package p;"
2449 "parcelable Data {"
2450 " int num;"
2451 " p.Enum e;" // this is considered as valid since 0(enum default) is valid for "Enum" type
2452 "}");
2453 io_delegate_.SetFileContents("new/p/Enum.aidl",
2454 "package p;"
2455 "enum Enum {"
2456 " FOO = 0,"
2457 " BAR = 1,"
2458 "}");
2459 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2460}
2461
Jooyung Han308bbe02021-04-27 12:09:59 +09002462TEST_F(AidlTestCompatibleChanges, CompatibleExplicitDefaults) {
2463 io_delegate_.SetFileContents("old/p/Data.aidl",
2464 "package p;\n"
2465 "parcelable Data {\n"
2466 " p.Enum e;\n"
2467 "}");
2468 io_delegate_.SetFileContents("old/p/Enum.aidl",
2469 "package p;\n"
2470 "enum Enum {\n"
2471 " FOO = 0,\n"
2472 " BAR = 1,\n"
2473 "}");
2474 io_delegate_.SetFileContents("new/p/Data.aidl",
2475 "package p;\n"
2476 "parcelable Data {\n"
2477 " p.Enum e = p.Enum.FOO;\n"
2478 "}");
2479 io_delegate_.SetFileContents("new/p/Enum.aidl",
2480 "package p;\n"
2481 "enum Enum {\n"
2482 " FOO = 0,\n"
2483 " BAR = 1,\n"
2484 "}");
2485 EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2486}
2487
Daniel Norman85aed542019-08-21 12:01:14 -07002488class AidlTestIncompatibleChanges : public AidlTest {
2489 protected:
2490 Options options_ = Options::From("aidl --checkapi old new");
2491};
2492
2493TEST_F(AidlTestIncompatibleChanges, RemovedType) {
Jiyong Park0cf03b12020-07-22 19:36:34 +09002494 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002495 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2496 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002497 "interface IFoo {"
2498 " void foo(in String[] str);"
2499 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002500 "}");
Devin Moored131d5e2020-03-31 10:39:10 -07002501 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002502 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moored131d5e2020-03-31 10:39:10 -07002503 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002504}
2505
2506TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002507 const string expected_stderr =
2508 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002509 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2510 "package p;"
2511 "interface IFoo {"
2512 " void foo(in String[] str);"
2513 " void bar(@utf8InCpp String str);"
2514 "}");
2515 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2516 "package p;"
2517 "interface IFoo {"
2518 " void foo(in String[] str);"
2519 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002520 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002521 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002522 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002523}
2524
Jiyong Parkf8d53612020-05-04 14:06:13 +09002525TEST_F(AidlTestIncompatibleChanges, UntypedListInInterface) {
2526 const string expected_stderr =
2527 "ERROR: new/p/IFoo.aidl:1.61-65: "
2528 "Encountered an untyped List or Map. The use of untyped List/Map is "
2529 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2530 "the receiving side. Consider switching to an array or a generic List/Map.\n"
2531 "ERROR: new/p/IFoo.aidl: Failed to read.\n";
2532 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2533 "package p;"
2534 "interface IFoo {"
2535 " void foo(in String[] str);"
2536 "}");
2537 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2538 "package p;"
2539 "interface IFoo {"
2540 " void foo(in String[] str);"
2541 " void bar(in List arg);"
2542 "}");
2543 CaptureStderr();
2544 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2545 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2546}
2547
2548TEST_F(AidlTestCompatibleChanges, UntypedListInParcelable) {
2549 const string expected_stderr =
2550 "ERROR: new/p/Data.aidl:1.54-59: "
2551 "Encountered an untyped List or Map. The use of untyped List/Map is "
2552 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2553 "the receiving side. Consider switching to an array or a generic List/Map.\n"
2554 "ERROR: new/p/Data.aidl: Failed to read.\n";
2555 io_delegate_.SetFileContents("old/p/Data.aidl",
2556 "package p;"
2557 "parcelable Data {"
2558 " int foo;"
2559 "}");
2560 io_delegate_.SetFileContents("new/p/Data.aidl",
2561 "package p;"
2562 "parcelable Data {"
2563 " int foo;"
2564 " @nullable List list;"
2565 "}");
2566 CaptureStderr();
2567 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2568 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2569}
2570
Daniel Norman85aed542019-08-21 12:01:14 -07002571TEST_F(AidlTestIncompatibleChanges, RemovedField) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002572 const string expected_stderr =
2573 "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 +09002574 io_delegate_.SetFileContents("old/p/Data.aidl",
2575 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002576 "parcelable Data {"
2577 " int foo;"
2578 " int bar;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002579 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002580 io_delegate_.SetFileContents("new/p/Data.aidl",
2581 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002582 "parcelable Data {"
2583 " int foo;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002584 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002585 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002586 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002587 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002588}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002589
Jooyung Hanb5c55cd2020-10-22 07:59:01 +09002590TEST_F(AidlTestIncompatibleChanges, NewFieldWithNoDefault) {
2591 const string expected_stderr =
2592 "ERROR: new/p/Data.aidl:1.46-50: Field 'str' does not have a useful default in some "
2593 "backends. Please either provide a default value for this field or mark the field as "
2594 "@nullable. This value or a null value will be used automatically when an old version of "
2595 "this parcelable is sent to a process which understands a new version of this parcelable. In "
2596 "order to make sure your code continues to be backwards compatible, make sure the default or "
2597 "null value does not cause a semantic change to this parcelable.\n";
2598 io_delegate_.SetFileContents("old/p/Data.aidl",
2599 "package p;"
2600 "parcelable Data {"
2601 " int num;"
2602 "}");
2603 io_delegate_.SetFileContents("new/p/Data.aidl",
2604 "package p;"
2605 "parcelable Data {"
2606 " int num;"
2607 " String str;"
2608 "}");
2609 CaptureStderr();
2610 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2611 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2612}
2613
Jooyung Han636fd2f2020-10-22 11:33:45 +09002614TEST_F(AidlTestIncompatibleChanges, NewFieldWithNonZeroEnum) {
2615 const string expected_stderr =
2616 "ERROR: new/p/Data.aidl:1.46-48: Field 'e' of enum 'Enum' can't be initialized as '0'. "
2617 "Please make sure 'Enum' has '0' as a valid value.\n";
2618 io_delegate_.SetFileContents("old/p/Data.aidl",
2619 "package p;"
2620 "parcelable Data {"
2621 " int num;"
2622 "}");
2623 io_delegate_.SetFileContents("new/p/Data.aidl",
2624 "package p;"
2625 "parcelable Data {"
2626 " int num;"
2627 " p.Enum e;"
2628 "}");
2629 io_delegate_.SetFileContents("new/p/Enum.aidl",
2630 "package p;"
2631 "enum Enum {"
2632 " FOO = 1,"
2633 " BAR = 2,"
2634 "}");
2635 CaptureStderr();
2636 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2637 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2638}
2639
Daniel Norman85aed542019-08-21 12:01:14 -07002640TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002641 const string expected_stderr =
2642 "ERROR: new/p/Enum.aidl:1.15-20: Removed enumerator from p.Enum: FOO\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002643 io_delegate_.SetFileContents("old/p/Enum.aidl",
2644 "package p;"
2645 "enum Enum {"
2646 " FOO = 1,"
2647 " BAR = 2,"
2648 "}");
2649 io_delegate_.SetFileContents("new/p/Enum.aidl",
2650 "package p;"
2651 "enum Enum {"
2652 " BAR = 2,"
2653 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002654 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002655 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002656 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002657}
2658
Jooyung Hanb5c55cd2020-10-22 07:59:01 +09002659TEST_F(AidlTestIncompatibleChanges, RemovedUnionField) {
2660 const string expected_stderr =
2661 "ERROR: new/p/Union.aidl:1.16-22: Number of fields in p.Union is reduced from 2 to 1.\n";
2662 io_delegate_.SetFileContents("old/p/Union.aidl",
2663 "package p;"
2664 "union Union {"
2665 " String str;"
2666 " int num;"
2667 "}");
2668 io_delegate_.SetFileContents("new/p/Union.aidl",
2669 "package p;"
2670 "union Union {"
2671 " String str;"
2672 "}");
2673 CaptureStderr();
2674 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2675 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2676}
2677
Daniel Norman85aed542019-08-21 12:01:14 -07002678TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002679 const string expected_stderr =
2680 "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002681 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2682 "package p;"
2683 "interface IFoo {"
2684 " void foo(in String[] str);"
2685 " void bar(@utf8InCpp String str);"
2686 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002687 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2688 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002689 "interface IFoo {"
2690 " void foo(in String[] str);"
2691 " void bar2(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002692 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002693 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002694 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002695 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002696}
2697
Daniel Norman85aed542019-08-21 12:01:14 -07002698TEST_F(AidlTestIncompatibleChanges, RenamedType) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002699 const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002700 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2701 "package p;"
2702 "interface IFoo {"
2703 " void foo(in String[] str);"
2704 " void bar(@utf8InCpp String str);"
2705 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002706 io_delegate_.SetFileContents("new/p/IFoo2.aidl",
2707 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002708 "interface IFoo2 {"
2709 " void foo(in String[] str);"
2710 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002711 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002712 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002713 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002714 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002715}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002716
Daniel Norman85aed542019-08-21 12:01:14 -07002717TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002718 const string expected_stderr =
2719 "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 -07002720 io_delegate_.SetFileContents("old/p/Enum.aidl",
2721 "package p;"
2722 "enum Enum {"
2723 " FOO = 1,"
2724 " BAR = 2,"
2725 "}");
2726 io_delegate_.SetFileContents("new/p/Enum.aidl",
2727 "package p;"
2728 "enum Enum {"
2729 " FOO = 3,"
2730 " BAR = 2,"
2731 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002732 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002733 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002734 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002735}
2736
2737TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002738 const string expected_stderr =
2739 "ERROR: new/p/IFoo.aidl:1.67-71: Transaction ID changed: p.IFoo.foo(String[]) is changed "
2740 "from 0 to 1.\n"
2741 "ERROR: new/p/IFoo.aidl:1.33-37: Transaction ID changed: p.IFoo.bar(String) is changed from "
2742 "1 to 0.\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002743 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2744 "package p;"
2745 "interface IFoo {"
2746 " void foo(in String[] str);"
2747 " void bar(@utf8InCpp String str);"
2748 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002749 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2750 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002751 "interface IFoo {"
2752 " void bar(@utf8InCpp String str);"
2753 " void foo(in String[] str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002754 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002755 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002756 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002757 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002758}
2759
2760TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002761 const string expected_stderr =
Jiyong Parkb07d9932020-05-15 12:56:54 +09002762 "ERROR: new/p/Data.aidl:1.33-37: Reordered bar from 1 to 0.\n"
2763 "ERROR: new/p/Data.aidl:1.43-47: Reordered foo from 0 to 1.\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002764 io_delegate_.SetFileContents("old/p/Data.aidl",
Jiyong Parke59c3682018-09-11 23:10:25 +09002765 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002766 "parcelable Data {"
2767 " int foo;"
2768 " int bar;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002769 "}");
Daniel Norman85aed542019-08-21 12:01:14 -07002770 io_delegate_.SetFileContents("new/p/Data.aidl",
2771 "package p;"
2772 "parcelable Data {"
2773 " int bar;"
2774 " int foo;"
2775 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002776 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002777 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002778 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002779}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002780
Daniel Norman85aed542019-08-21 12:01:14 -07002781TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
Devin Mooreeccdb902020-03-24 16:22:40 -07002782 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 -07002783 io_delegate_.SetFileContents("old/p/IFoo.aidl",
Jiyong Parke59c3682018-09-11 23:10:25 +09002784 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002785 "interface IFoo {"
2786 " void foo(in String[] str);"
2787 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002788 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002789 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2790 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002791 "interface IFoo {"
2792 " void foo(out String[] str);"
2793 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002794 "}");
Devin Mooreeccdb902020-03-24 16:22:40 -07002795 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002796 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Mooreeccdb902020-03-24 16:22:40 -07002797 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002798}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002799
Daniel Norman85aed542019-08-21 12:01:14 -07002800TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002801 const string expected_stderr =
2802 "ERROR: new/p/IFoo.aidl:1.51-58: Changed annotations: (empty) to @utf8InCpp\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002803 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2804 "package p;"
2805 "interface IFoo {"
2806 " void foo(in String[] str);"
2807 " void bar(@utf8InCpp String str);"
2808 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002809 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2810 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002811 "interface IFoo {"
Jiyong Parke59c3682018-09-11 23:10:25 +09002812 " void foo(in @utf8InCpp String[] str);"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002813 " void bar(@utf8InCpp String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002814 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002815 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002816 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002817 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002818}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002819
Daniel Norman85aed542019-08-21 12:01:14 -07002820TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002821 const string expected_stderr =
2822 "ERROR: new/p/IFoo.aidl:1.66-72: Changed annotations: @utf8InCpp to (empty)\n";
Daniel Norman85aed542019-08-21 12:01:14 -07002823 io_delegate_.SetFileContents("old/p/IFoo.aidl",
2824 "package p;"
2825 "interface IFoo {"
2826 " void foo(in String[] str);"
2827 " void bar(@utf8InCpp String str);"
2828 "}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002829 io_delegate_.SetFileContents("new/p/IFoo.aidl",
2830 "package p;"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002831 "interface IFoo {"
Jiyong Parke59c3682018-09-11 23:10:25 +09002832 " void foo(in String[] str);"
Jiyong Park3656c3c2018-08-01 20:02:01 +09002833 " void bar(String str);"
Jiyong Parke59c3682018-09-11 23:10:25 +09002834 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002835 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002836 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002837 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002838}
Jiyong Park3656c3c2018-08-01 20:02:01 +09002839
Jooyung Han60b2fde2020-10-29 15:12:40 +09002840TEST_F(AidlTestIncompatibleChanges, ChangedBackingTypeOfEnum) {
2841 const string expected_stderr =
2842 "ERROR: new/p/Foo.aidl:1.11-32: Type changed: byte to long.\n"
2843 "ERROR: new/p/Foo.aidl:1.36-40: Changed backing types.\n";
2844 io_delegate_.SetFileContents("old/p/Foo.aidl",
2845 "package p;"
2846 "@Backing(type=\"byte\")"
2847 "enum Foo {"
2848 " FOO, BAR,"
2849 "}");
2850 io_delegate_.SetFileContents("new/p/Foo.aidl",
2851 "package p;"
2852 "@Backing(type=\"long\")"
2853 "enum Foo {"
2854 " FOO, BAR,"
2855 "}");
2856 CaptureStderr();
2857 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2858 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2859}
2860
Jooyung Han69ea4ba2020-10-29 15:33:37 +09002861TEST_F(AidlTestIncompatibleChanges, ChangedAnnatationParams) {
2862 const string expected_stderr =
2863 "ERROR: new/p/Foo.aidl:1.55-59: Changed annotations: @JavaPassthrough(annotation=\"Alice\") "
2864 "to @JavaPassthrough(annotation=\"Bob\")\n";
2865 io_delegate_.SetFileContents("old/p/Foo.aidl",
2866 "package p;"
2867 "@JavaPassthrough(annotation=\"Alice\")"
2868 "parcelable Foo {}");
2869 io_delegate_.SetFileContents("new/p/Foo.aidl",
2870 "package p;"
2871 "@JavaPassthrough(annotation=\"Bob\")"
2872 "parcelable Foo {}");
2873
2874 CaptureStderr();
2875 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2876 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2877}
2878
Devin Mooredb7ac512020-08-07 11:17:36 -07002879TEST_F(AidlTestIncompatibleChanges, AddedParcelableAnnotation) {
2880 const string expected_stderr =
Jooyung Han2d6b5c42021-01-09 01:01:06 +09002881 "ERROR: new/p/Foo.aidl:1.32-36: Changed annotations: (empty) to @FixedSize\n";
Devin Mooredb7ac512020-08-07 11:17:36 -07002882 io_delegate_.SetFileContents("old/p/Foo.aidl",
2883 "package p;"
2884 "parcelable Foo {"
2885 " int A;"
2886 "}");
2887 io_delegate_.SetFileContents("new/p/Foo.aidl",
2888 "package p;"
Jooyung Han2d6b5c42021-01-09 01:01:06 +09002889 "@FixedSize parcelable Foo {"
Devin Mooredb7ac512020-08-07 11:17:36 -07002890 " int A;"
2891 "}");
2892 CaptureStderr();
2893 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2894 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2895}
2896
2897TEST_F(AidlTestIncompatibleChanges, RemovedParcelableAnnotation) {
2898 const string expected_stderr =
Jooyung Han2d6b5c42021-01-09 01:01:06 +09002899 "ERROR: new/p/Foo.aidl:1.21-25: Changed annotations: @FixedSize to (empty)\n";
Devin Mooredb7ac512020-08-07 11:17:36 -07002900 io_delegate_.SetFileContents("old/p/Foo.aidl",
2901 "package p;"
Jooyung Han2d6b5c42021-01-09 01:01:06 +09002902 "@FixedSize parcelable Foo {"
Devin Mooredb7ac512020-08-07 11:17:36 -07002903 " int A;"
2904 "}");
2905 io_delegate_.SetFileContents("new/p/Foo.aidl",
2906 "package p;"
2907 "parcelable Foo {"
2908 " int A;"
2909 "}");
2910 CaptureStderr();
2911 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2912 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2913}
2914
Daniel Norman85aed542019-08-21 12:01:14 -07002915TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002916 const string expected_stderr = "ERROR: old/q/IFoo.aidl:1.11-21: Removed type: q.IFoo\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002917 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
2918 io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
Jiyong Parke59c3682018-09-11 23:10:25 +09002919 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
Devin Moore097a3ab2020-03-11 16:08:44 -07002920 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002921 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002922 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002923}
Jiyong Parka468e2a2018-08-29 21:25:18 +09002924
Daniel Norman85aed542019-08-21 12:01:14 -07002925TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
Steven Moreland370ed342020-04-28 18:14:39 -07002926 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 +09002927 io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
2928 io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002929 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002930 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002931 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002932}
Jiyong Parka428d212018-08-29 22:26:30 +09002933
Daniel Norman85aed542019-08-21 12:01:14 -07002934TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002935 const string expected_stderr =
2936 "ERROR: old/p/I.aidl:1.51-53: Removed constant declaration: p.I.B\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09002937 io_delegate_.SetFileContents("old/p/I.aidl",
2938 "package p; interface I {"
2939 "const int A = 1; const int B = 2;}");
2940 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002941 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002942 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002943 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Daniel Norman85aed542019-08-21 12:01:14 -07002944}
Jiyong Parka428d212018-08-29 22:26:30 +09002945
Daniel Norman85aed542019-08-21 12:01:14 -07002946TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
Devin Moore097a3ab2020-03-11 16:08:44 -07002947 const string expected_stderr =
2948 "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 +09002949 io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
2950 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
Devin Moore097a3ab2020-03-11 16:08:44 -07002951 CaptureStderr();
Daniel Norman85aed542019-08-21 12:01:14 -07002952 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07002953 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3c35e392018-08-30 13:10:30 +09002954}
2955
Devin Moorec7e47a32020-08-07 10:55:25 -07002956TEST_F(AidlTestIncompatibleChanges, FixedSizeAddedField) {
2957 const string expected_stderr =
2958 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is changed from 1 to 2. "
2959 "This is an incompatible change for FixedSize types.\n";
2960 io_delegate_.SetFileContents("old/p/Foo.aidl",
2961 "package p; @FixedSize parcelable Foo { int A = 1; }");
2962 io_delegate_.SetFileContents("new/p/Foo.aidl",
2963 "package p; @FixedSize parcelable Foo { int A = 1; int B = 2; }");
2964 CaptureStderr();
2965 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2966 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2967}
2968
Jeongik Cha68d18e72021-04-29 20:07:01 +09002969TEST_F(AidlTestIncompatibleChanges, UidRangeParcelAddedField) {
2970 const string expected_stderr =
2971 "ERROR: new/android/net/UidRangeParcel.aidl:1.32-47: Number of fields in "
2972 "android.net.UidRangeParcel is changed from 1 to 2. "
2973 "But it is forbidden because of legacy support.\n";
2974 io_delegate_.SetFileContents("old/android/net/UidRangeParcel.aidl",
2975 "package android.net; parcelable UidRangeParcel { int A = 1; }");
2976 io_delegate_.SetFileContents(
2977 "new/android/net/UidRangeParcel.aidl",
2978 "package android.net; parcelable UidRangeParcel { int A = 1; int B = 2; }");
2979 CaptureStderr();
2980 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2981 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2982}
2983
Devin Moorec7e47a32020-08-07 10:55:25 -07002984TEST_F(AidlTestIncompatibleChanges, FixedSizeRemovedField) {
2985 const string expected_stderr =
2986 "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
2987 io_delegate_.SetFileContents("old/p/Foo.aidl",
2988 "package p; @FixedSize parcelable Foo { int A = 1; int B = 1; }");
2989 io_delegate_.SetFileContents("new/p/Foo.aidl",
2990 "package p; @FixedSize parcelable Foo { int A = 1; }");
2991 CaptureStderr();
2992 EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2993 EXPECT_EQ(expected_stderr, GetCapturedStderr());
2994}
2995
2996TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize) {
2997 const string expected_stderr =
2998 "ERROR: Foo.aidl:1.36-38: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2999 "a.\n"
3000 "ERROR: Foo.aidl:1.44-46: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3001 "b.\n"
3002 "ERROR: Foo.aidl:1.55-57: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3003 "c.\n"
3004 "ERROR: Foo.aidl:1.80-82: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3005 "d.\n"
3006 "ERROR: Foo.aidl:1.92-94: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3007 "e.\n"
3008 "ERROR: Foo.aidl:1.109-111: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3009 "f.\n";
3010
3011 io_delegate_.SetFileContents("Foo.aidl",
3012 "@FixedSize parcelable Foo { "
3013 " int[] a;"
3014 " Bar b;"
3015 " String c;"
3016 " ParcelFileDescriptor d;"
3017 " IBinder e;"
3018 " List<String> f;"
Steven Moreland265f3d42020-09-24 19:06:54 +00003019 " int isFixedSize;"
Devin Moorec7e47a32020-08-07 10:55:25 -07003020 "}");
3021 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09003022 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
Devin Moorec7e47a32020-08-07 10:55:25 -07003023
3024 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003025 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moorec7e47a32020-08-07 10:55:25 -07003026 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3027}
3028
3029TEST_P(AidlTest, AcceptFixedSizeFromFixedSize) {
3030 const string expected_stderr = "";
3031
3032 io_delegate_.SetFileContents("Foo.aidl", "@FixedSize parcelable Foo { int a; Bar b; }");
3033 io_delegate_.SetFileContents("Bar.aidl", "@FixedSize parcelable Bar { Val c; }");
3034 io_delegate_.SetFileContents("Val.aidl", "enum Val { A, B, }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09003035 Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
Devin Moorec7e47a32020-08-07 10:55:25 -07003036
3037 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003038 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Devin Moorec7e47a32020-08-07 10:55:25 -07003039 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3040}
3041
Jiyong Park8c380532018-08-30 14:55:26 +09003042TEST_F(AidlTest, RejectAmbiguousImports) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003043 const string expected_stderr =
3044 "ERROR: p/IFoo.aidl: Duplicate files found for q.IBar from:\n"
3045 "dir1/q/IBar.aidl\n"
3046 "dir2/q/IBar.aidl\n"
Devin Moore5de18ed2020-04-02 13:52:29 -07003047 "ERROR: p/IFoo.aidl: Couldn't find import for class q.IBar\n";
Jiyong Park8c380532018-08-30 14:55:26 +09003048 Options options = Options::From("aidl --lang=java -o out -I dir1 -I dir2 p/IFoo.aidl");
3049 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
3050 io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
3051 io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
3052
Devin Moore097a3ab2020-03-11 16:08:44 -07003053 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003054 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07003055 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park8c380532018-08-30 14:55:26 +09003056}
3057
Jiyong Parked65bf42018-08-28 15:43:27 +09003058TEST_F(AidlTest, HandleManualIdAssignments) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003059 const string expected_stderr =
3060 "ERROR: new/p/IFoo.aidl:1.32-36: Transaction ID changed: p.IFoo.foo() is changed from 10 to "
3061 "11.\n";
Jiyong Parke59c3682018-09-11 23:10:25 +09003062 Options options = Options::From("aidl --checkapi old new");
3063 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
3064 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
Jiyong Parked65bf42018-08-28 15:43:27 +09003065
3066 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3067
Jiyong Parke59c3682018-09-11 23:10:25 +09003068 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
Devin Moore097a3ab2020-03-11 16:08:44 -07003069 CaptureStderr();
Jiyong Parked65bf42018-08-28 15:43:27 +09003070 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07003071 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parked65bf42018-08-28 15:43:27 +09003072}
3073
Jooyung Han652ce482021-02-26 12:40:35 +09003074TEST_P(AidlTest, ParcelFileDescriptorIsBuiltinType) {
3075 Options options =
3076 Options::From("aidl --lang=" + to_string(GetLanguage()) + " -h out -o out p/IFoo.aidl");
Jiyong Parke05195e2018-10-08 18:24:23 +09003077
3078 // use without import
3079 io_delegate_.SetFileContents("p/IFoo.aidl",
3080 "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
Steven Moreland4e059132021-08-11 13:36:30 -07003081 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han652ce482021-02-26 12:40:35 +09003082
3083 // capture output files
3084 map<string, string> outputs = io_delegate_.OutputFiles();
Jiyong Parke05195e2018-10-08 18:24:23 +09003085
Devin Moore7b8d5c92020-03-17 14:14:08 -07003086 // use without import but with full name
Jiyong Parke05195e2018-10-08 18:24:23 +09003087 io_delegate_.SetFileContents(
3088 "p/IFoo.aidl",
3089 "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
Steven Moreland4e059132021-08-11 13:36:30 -07003090 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han652ce482021-02-26 12:40:35 +09003091 // output files should be the same
3092 EXPECT_EQ(outputs, io_delegate_.OutputFiles());
Jiyong Parke05195e2018-10-08 18:24:23 +09003093
3094 // use with import (as before)
3095 io_delegate_.SetFileContents("p/IFoo.aidl",
3096 "package p;"
3097 "import android.os.ParcelFileDescriptor;"
3098 "interface IFoo{"
3099 " void foo(in ParcelFileDescriptor fd);"
3100 "}");
Steven Moreland4e059132021-08-11 13:36:30 -07003101 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han652ce482021-02-26 12:40:35 +09003102 // output files should be the same
3103 EXPECT_EQ(outputs, io_delegate_.OutputFiles());
Jiyong Parke05195e2018-10-08 18:24:23 +09003104}
Jiyong Parked65bf42018-08-28 15:43:27 +09003105
Jooyung Han020d8d12021-02-26 17:23:02 +09003106TEST_P(AidlTest, RejectsOutputParcelFileDescriptor) {
3107 Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
3108 CaptureStderr();
3109 io_delegate_.SetFileContents("p/IFoo.aidl",
3110 "package p;"
3111 "interface IFoo{"
3112 " void foo(out ParcelFileDescriptor fd);"
3113 "}");
Steven Moreland4e059132021-08-11 13:36:30 -07003114 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han020d8d12021-02-26 17:23:02 +09003115 EXPECT_THAT(GetCapturedStderr(), HasSubstr("can't be an out parameter"));
3116}
3117
3118TEST_P(AidlTest, RejectsArgumentDirectionNotSpecified) {
3119 Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
3120 CaptureStderr();
3121 io_delegate_.SetFileContents("p/IFoo.aidl",
3122 "package p;"
3123 "interface IFoo{"
3124 " void foo(ParcelFileDescriptor fd);"
3125 "}");
Steven Moreland4e059132021-08-11 13:36:30 -07003126 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han020d8d12021-02-26 17:23:02 +09003127 EXPECT_THAT(GetCapturedStderr(),
3128 HasSubstr("ParcelFileDescriptor can be an in or inout parameter."));
3129}
3130
Jiyong Park3633b722019-04-11 15:38:26 +09003131TEST_F(AidlTest, ManualIds) {
3132 Options options = Options::From("aidl --lang=java -o out IFoo.aidl");
3133 io_delegate_.SetFileContents("IFoo.aidl",
3134 "interface IFoo {\n"
3135 " void foo() = 0;\n"
3136 " void bar() = 1;\n"
3137 "}");
Steven Moreland4e059132021-08-11 13:36:30 -07003138 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Park3633b722019-04-11 15:38:26 +09003139}
3140
3141TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
3142 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
3143 io_delegate_.SetFileContents("IFoo.aidl",
3144 "interface IFoo {\n"
3145 " void foo() = 0;\n"
3146 " void bar() = 1;\n"
3147 "}");
Steven Moreland4e059132021-08-11 13:36:30 -07003148 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Park3633b722019-04-11 15:38:26 +09003149}
3150
3151TEST_F(AidlTest, FailOnDuplicatedIds) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003152 const string expected_stderr =
3153 "ERROR: IFoo.aidl:3.7-11: Found duplicate method id (3) for method bar\n";
Jiyong Park3633b722019-04-11 15:38:26 +09003154 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
3155 io_delegate_.SetFileContents("IFoo.aidl",
3156 "interface IFoo {\n"
3157 " void foo() = 3;\n"
3158 " void bar() = 3;\n"
3159 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07003160 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003161 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07003162 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3633b722019-04-11 15:38:26 +09003163}
3164
3165TEST_F(AidlTest, FailOnOutOfRangeIds) {
3166 // 16777115 is kLastMetaMethodId + 1
Devin Moore097a3ab2020-03-11 16:08:44 -07003167 const string expected_stderr =
3168 "ERROR: IFoo.aidl:3.7-11: Found out of bounds id (16777115) for method bar. "
3169 "Value for id must be between 0 and 16777114 inclusive.\n";
Jiyong Park3633b722019-04-11 15:38:26 +09003170 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
3171 io_delegate_.SetFileContents("IFoo.aidl",
3172 "interface IFoo {\n"
3173 " void foo() = 3;\n"
3174 " void bar() = 16777115;\n"
3175 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07003176 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003177 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07003178 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3633b722019-04-11 15:38:26 +09003179}
3180
3181TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003182 const string expected_stderr =
3183 "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 +09003184 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
3185 io_delegate_.SetFileContents("IFoo.aidl",
3186 "interface IFoo {\n"
3187 " void foo() = 3;\n"
3188 " void bar();\n"
3189 "}");
Devin Moore097a3ab2020-03-11 16:08:44 -07003190 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003191 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07003192 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Park3633b722019-04-11 15:38:26 +09003193}
3194
Jiyong Parkc6816252019-07-08 08:12:28 +09003195TEST_F(AidlTest, AllowDuplicatedImportPaths) {
3196 Options options = Options::From("aidl --lang=java -I dir -I dir IFoo.aidl");
3197 io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
3198 io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
Steven Moreland4e059132021-08-11 13:36:30 -07003199 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Parkc6816252019-07-08 08:12:28 +09003200}
3201
3202TEST_F(AidlTest, FailOnAmbiguousImports) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003203 const string expected_stderr =
3204 "ERROR: IFoo.aidl: Duplicate files found for IBar from:\n"
3205 "dir/IBar.aidl\n"
3206 "dir2/IBar.aidl\n"
Devin Moore5de18ed2020-04-02 13:52:29 -07003207 "ERROR: IFoo.aidl: Couldn't find import for class IBar\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07003208
Jiyong Parkc6816252019-07-08 08:12:28 +09003209 Options options = Options::From("aidl --lang=java -I dir -I dir2 IFoo.aidl");
3210 io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
3211 io_delegate_.SetFileContents("dir2/IBar.aidl", "interface IBar{}");
3212 io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
Devin Moore097a3ab2020-03-11 16:08:44 -07003213 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003214 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore097a3ab2020-03-11 16:08:44 -07003215 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Jiyong Parkc6816252019-07-08 08:12:28 +09003216}
3217
Jiyong Parkf1f5c802020-05-19 17:33:00 +09003218TEST_F(AidlTest, UnusedImportDoesNotContributeInclude) {
3219 io_delegate_.SetFileContents("a/b/IFoo.aidl",
3220 "package a.b;\n"
3221 "import a.b.IBar;\n"
3222 "import a.b.IQux;\n"
3223 "interface IFoo { IQux foo(); }\n");
3224 io_delegate_.SetFileContents("a/b/IBar.aidl", "package a.b; interface IBar { void foo(); }");
3225 io_delegate_.SetFileContents("a/b/IQux.aidl", "package a.b; interface IQux { void foo(); }");
3226
3227 Options options = Options::From("aidl --lang=ndk a/b/IFoo.aidl -I . -o out -h out/include");
Steven Moreland4e059132021-08-11 13:36:30 -07003228 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Parkf1f5c802020-05-19 17:33:00 +09003229
3230 string output;
3231 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/include/aidl/a/b/IFoo.h", &output));
3232 // IBar was imported but wasn't used. include is not expected.
3233 EXPECT_THAT(output, Not(testing::HasSubstr("#include <aidl/a/b/IBar.h>")));
3234 // IBar was imported and used. include is expected.
3235 EXPECT_THAT(output, (testing::HasSubstr("#include <aidl/a/b/IQux.h>")));
3236}
3237
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003238TEST_F(AidlTest, ParseJavaPassthroughAnnotation) {
Jooyung Hane6bc5e12020-10-13 10:57:10 +09003239 io_delegate_.SetFileContents("a/IFoo.aidl", R"--(package a;
Jooyung Han4cde01d2020-10-13 11:10:47 +09003240 import a.MyEnum;
Jooyung Hane6bc5e12020-10-13 10:57:10 +09003241 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
3242 @JavaPassthrough(annotation="@com.android.AliceTwo")
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003243 interface IFoo {
3244 @JavaPassthrough(annotation="@com.android.Bob")
Jooyung Han4cde01d2020-10-13 11:10:47 +09003245 void foo(@JavaPassthrough(annotation="@com.android.Cat") int x, MyEnum y);
Jiyong Park7c3b0e42020-08-04 16:08:32 +09003246 const @JavaPassthrough(annotation="@com.android.David") int A = 3;
Jooyung Hane6bc5e12020-10-13 10:57:10 +09003247 })--");
Jooyung Han4cde01d2020-10-13 11:10:47 +09003248 // JavaPassthrough should work with other types as well (e.g. enum)
3249 io_delegate_.SetFileContents("a/MyEnum.aidl", R"--(package a;
3250 @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
3251 @JavaPassthrough(annotation="@com.android.AliceTwo")
3252 @Backing(type="byte")
3253 enum MyEnum {
3254 a, b, c
3255 })--");
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003256
Jooyung Han4cde01d2020-10-13 11:10:47 +09003257 Options java_options = Options::From("aidl -I . --lang=java -o out a/IFoo.aidl a/MyEnum.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003258 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003259
3260 string java_out;
3261 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &java_out));
Jooyung Hane6bc5e12020-10-13 10:57:10 +09003262 // type-decl-level annotations with newline at the end
3263 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
3264 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3265 // member-decl-level annotations with newline at the end
3266 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Bob\n"));
3267 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.David\n"));
3268 // inline annotations with space at the end
3269 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Cat "));
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003270
Jooyung Han4cde01d2020-10-13 11:10:47 +09003271 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/MyEnum.java", &java_out));
3272 // type-decl-level annotations with newline at the end
3273 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
3274 EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3275
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003276 // Other backends shouldn't be bothered
Jooyung Han4cde01d2020-10-13 11:10:47 +09003277 Options cpp_options =
3278 Options::From("aidl -I . --lang=cpp -o out -h out a/IFoo.aidl a/MyEnum.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003279 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003280
Jooyung Han4cde01d2020-10-13 11:10:47 +09003281 Options ndk_options =
3282 Options::From("aidl -I . --lang=ndk -o out -h out a/IFoo.aidl a/MyEnum.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003283 EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
Andrei Homescub62afd92020-05-11 19:24:59 -07003284
Jooyung Han4cde01d2020-10-13 11:10:47 +09003285 Options rust_options = Options::From("aidl -I . --lang=rust -o out a/IFoo.aidl a/MyEnum.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003286 EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09003287}
3288
Andrei Homescue61feb52020-08-18 15:44:24 -07003289TEST_F(AidlTest, ParseRustDerive) {
3290 io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
3291 @RustDerive(Clone=true, Copy=false)
3292 parcelable Foo {
3293 int a;
3294 })");
3295
3296 Options rust_options = Options::From("aidl --lang=rust -o out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003297 EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
Andrei Homescue61feb52020-08-18 15:44:24 -07003298
3299 string rust_out;
3300 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.rs", &rust_out));
3301 EXPECT_THAT(rust_out, testing::HasSubstr("#[derive(Debug, Clone)]"));
3302
3303 // Other backends shouldn't be bothered
3304 Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003305 EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
Andrei Homescue61feb52020-08-18 15:44:24 -07003306
3307 Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003308 EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
Andrei Homescue61feb52020-08-18 15:44:24 -07003309
3310 Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003311 EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
Andrei Homescue61feb52020-08-18 15:44:24 -07003312}
3313
Jiyong Park56f73d72019-06-11 12:20:28 +09003314class AidlOutputPathTest : public AidlTest {
3315 protected:
3316 void SetUp() override {
3317 AidlTest::SetUp();
3318 io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
3319 }
3320
3321 void Test(const Options& options, const std::string expected_output_path) {
Steven Moreland4e059132021-08-11 13:36:30 -07003322 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jiyong Park56f73d72019-06-11 12:20:28 +09003323 // check the existence
3324 EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
3325 }
3326};
3327
3328TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
3329 // <out_dir> / <package_name> / <type_name>.java
3330 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
3331}
3332
3333TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
3334 // when output file is explicitly set, it is always respected. -o option is
3335 // ignored.
3336 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3337}
3338
3339TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
3340 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3341}
3342
3343TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
3344 // output is the same as the input file except for the suffix
3345 Test(Options::From("aidl sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
3346}
3347
Devin Moore7b8d5c92020-03-17 14:14:08 -07003348TEST_P(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003349 AidlError error;
3350 const string expected_stderr =
3351 "ERROR: p/IFoo.aidl:3.58-69: Invalid type specifier for an int64 literal: int\n";
3352 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003353 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3354 R"(package p;
3355 interface IFoo {
3356 const int int32_max_oob = 2147483650;
3357 }
3358 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003359 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003360 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3361 EXPECT_EQ(AidlError::BAD_TYPE, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003362}
3363
Devin Moore7b8d5c92020-03-17 14:14:08 -07003364TEST_P(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003365 AidlError error;
3366 const string expected_stderr =
3367 "ERROR: p/IFoo.aidl:3.58-60: Invalid type specifier for an int64 literal: int\n";
3368 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003369 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3370 R"(package p;
3371 interface IFoo {
3372 const int int32_min_oob = -2147483650;
3373 }
3374 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003375 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003376 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3377 EXPECT_EQ(AidlError::BAD_TYPE, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003378}
3379
Devin Moore7b8d5c92020-03-17 14:14:08 -07003380TEST_P(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003381 AidlError error;
3382 const string expected_stderr =
Devin Moore2a088902020-09-17 10:51:19 -07003383 "ERROR: p/IFoo.aidl:3.59-86: Could not parse integer: 21474836509999999999999999\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07003384 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003385 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3386 R"(package p;
3387 interface IFoo {
3388 const long int64_max_oob = 21474836509999999999999999;
3389 }
3390 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003391 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003392 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3393 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003394}
3395
Devin Moore7b8d5c92020-03-17 14:14:08 -07003396TEST_P(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003397 AidlError error;
3398 const string expected_stderr =
Devin Moore2a088902020-09-17 10:51:19 -07003399 "ERROR: p/IFoo.aidl:3.61-87: Could not parse integer: 21474836509999999999999999\n";
Devin Moore097a3ab2020-03-11 16:08:44 -07003400 CaptureStderr();
Will McVickera4e5b132019-10-03 13:52:21 -07003401 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3402 R"(package p;
3403 interface IFoo {
3404 const long int64_min_oob = -21474836509999999999999999;
3405 }
3406 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003407 typenames_, GetLanguage(), &error));
Devin Moore097a3ab2020-03-11 16:08:44 -07003408 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3409 EXPECT_EQ(AidlError::PARSE_ERROR, error);
Will McVickera4e5b132019-10-03 13:52:21 -07003410}
3411
Devin Moore7b8d5c92020-03-17 14:14:08 -07003412TEST_P(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
Devin Moore097a3ab2020-03-11 16:08:44 -07003413 AidlError error;
Devin Mooredf93ebb2020-03-25 14:03:35 -07003414 const string expected_stderr =
Jooyung Han29813842020-12-08 01:28:03 +09003415 "ERROR: p/TestEnum.aidl:5.1-36: Invalid type specifier for an int32 literal: byte\n"
Devin Mooredf93ebb2020-03-25 14:03:35 -07003416 "ERROR: p/TestEnum.aidl:5.1-36: Enumerator type differs from enum backing type.\n";
3417 CaptureStderr();
Daniel Normanb28684e2019-10-17 15:31:39 -07003418 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3419 R"(package p;
3420 @Backing(type="byte")
3421 enum TestEnum {
3422 FOO = 127,
3423 BAR,
3424 }
3425 )",
Devin Moore7b8d5c92020-03-17 14:14:08 -07003426 typenames_, GetLanguage(), &error));
Devin Mooredf93ebb2020-03-25 14:03:35 -07003427 EXPECT_EQ(expected_stderr, GetCapturedStderr());
Devin Moore097a3ab2020-03-11 16:08:44 -07003428 EXPECT_EQ(AidlError::BAD_TYPE, error);
Daniel Normanb28684e2019-10-17 15:31:39 -07003429}
3430
Devin Mooredecaf292020-04-30 09:16:40 -07003431TEST_P(AidlTest, UnsupportedBackingAnnotationParam) {
3432 AidlError error;
3433 const string expected_stderr =
3434 "ERROR: p/TestEnum.aidl:2.1-51: Parameter foo not supported for annotation Backing. It must "
Devin Mooredecaf292020-04-30 09:16:40 -07003435 "be one of: type\n";
3436 CaptureStderr();
3437 EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3438 R"(package p;
3439 @Backing(foo="byte")
3440 enum TestEnum {
3441 FOO = 1,
3442 BAR,
3443 }
3444 )",
3445 typenames_, GetLanguage(), &error));
3446 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3447 EXPECT_EQ(AidlError::BAD_TYPE, error);
3448}
3449
Jooyung Han5721a232020-12-24 04:34:55 +09003450TEST_P(AidlTest, BackingAnnotationRequireTypeParameter) {
3451 const string expected_stderr = "ERROR: Enum.aidl:1.1-9: Missing 'type' on @Backing.\n";
3452 CaptureStderr();
3453 EXPECT_EQ(nullptr, Parse("Enum.aidl", "@Backing enum Enum { FOO }", typenames_, GetLanguage()));
3454 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3455}
3456
Jooyung Han66813932020-10-23 13:24:44 +09003457TEST_F(AidlTest, SupportJavaOnlyImmutableAnnotation) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003458 io_delegate_.SetFileContents("Foo.aidl",
3459 "@JavaOnlyImmutable parcelable Foo { int a; Bar b; List<Bar> c; "
3460 "Map<String, Baz> d; Bar[] e; }");
3461 io_delegate_.SetFileContents("Bar.aidl", "@JavaOnlyImmutable parcelable Bar { String a; }");
3462 io_delegate_.SetFileContents("Baz.aidl",
3463 "@JavaOnlyImmutable @JavaOnlyStableParcelable parcelable Baz;");
Jeongik Cha36f76c32020-07-28 00:25:52 +09003464 Options options = Options::From("aidl --lang=java -I . Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003465 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jeongik Cha36f76c32020-07-28 00:25:52 +09003466}
3467
Jooyung Han66813932020-10-23 13:24:44 +09003468TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableParcelable) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003469 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
Jeongik Cha36f76c32020-07-28 00:25:52 +09003470 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
Jooyung Hand4057c42020-10-23 13:28:22 +09003471 string expected_error =
Jooyung Han59af9cc2020-10-25 21:44:14 +09003472 "ERROR: Foo.aidl:1.40-44: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
3473 "named 'bar'.\n";
3474 CaptureStderr();
3475 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
Steven Moreland4e059132021-08-11 13:36:30 -07003476 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han59af9cc2020-10-25 21:44:14 +09003477 EXPECT_EQ(expected_error, GetCapturedStderr());
3478}
3479
Jooyung Han09e551c2021-05-11 11:44:48 +09003480TEST_F(AidlTest, JavaOnlyImmutableParcelableWithEnumFields) {
3481 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
3482 io_delegate_.SetFileContents("Bar.aidl", "enum Bar { FOO }");
3483 CaptureStderr();
3484 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
Steven Moreland4e059132021-08-11 13:36:30 -07003485 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han09e551c2021-05-11 11:44:48 +09003486 EXPECT_EQ("", GetCapturedStderr());
3487}
3488
Jooyung Han59af9cc2020-10-25 21:44:14 +09003489TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableUnion) {
3490 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable union Foo { Bar bar; }");
3491 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
3492 string expected_error =
3493 "ERROR: Foo.aidl:1.35-39: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
Jooyung Hand4057c42020-10-23 13:28:22 +09003494 "named 'bar'.\n";
3495 CaptureStderr();
Jeongik Cha36f76c32020-07-28 00:25:52 +09003496 Options options = Options::From("aidl --lang=java Foo.aidl -I .");
Steven Moreland4e059132021-08-11 13:36:30 -07003497 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Hand4057c42020-10-23 13:28:22 +09003498 EXPECT_EQ(expected_error, GetCapturedStderr());
Jeongik Cha36f76c32020-07-28 00:25:52 +09003499}
3500
Jooyung Han66813932020-10-23 13:24:44 +09003501TEST_F(AidlTest, ImmutableParcelableCannotBeInOut) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003502 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
Jooyung Han15fd6c62020-10-23 13:54:46 +09003503 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(inout Foo foo); }");
3504 string expected_error =
3505 "ERROR: IBar.aidl:1.35-39: 'foo' can't be an inout parameter because @JavaOnlyImmutable can "
3506 "only be an in parameter.\n";
3507 CaptureStderr();
Jeongik Cha36f76c32020-07-28 00:25:52 +09003508 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
Steven Moreland4e059132021-08-11 13:36:30 -07003509 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han15fd6c62020-10-23 13:54:46 +09003510 EXPECT_EQ(expected_error, GetCapturedStderr());
Jeongik Cha36f76c32020-07-28 00:25:52 +09003511}
3512
Jooyung Han66813932020-10-23 13:24:44 +09003513TEST_F(AidlTest, ImmutableParcelableCannotBeOut) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003514 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
Jooyung Han15fd6c62020-10-23 13:54:46 +09003515 io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(out Foo foo); }");
3516 string expected_error =
3517 "ERROR: IBar.aidl:1.33-37: 'foo' can't be an out parameter because @JavaOnlyImmutable can "
3518 "only be an in parameter.\n";
3519 CaptureStderr();
Jeongik Cha36f76c32020-07-28 00:25:52 +09003520 Options options = Options::From("aidl --lang=java IBar.aidl -I .");
Steven Moreland4e059132021-08-11 13:36:30 -07003521 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han15fd6c62020-10-23 13:54:46 +09003522 EXPECT_EQ(expected_error, GetCapturedStderr());
Jeongik Cha36f76c32020-07-28 00:25:52 +09003523}
3524
Jooyung Han66813932020-10-23 13:24:44 +09003525TEST_F(AidlTest, ImmutableParcelableFieldNameRestriction) {
Jeongik Chad0a10272020-08-06 16:33:36 +09003526 io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; int A; }");
Jeongik Cha91180252020-07-31 15:43:11 +09003527 Options options = Options::From("aidl --lang=java Foo.aidl");
3528 const string expected_stderr =
Jooyung Han59af9cc2020-10-25 21:44:14 +09003529 "ERROR: Foo.aidl:1.47-49: 'Foo' has duplicate field name 'A' after capitalizing the first "
3530 "letter\n";
Jeongik Cha91180252020-07-31 15:43:11 +09003531 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003532 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jeongik Cha91180252020-07-31 15:43:11 +09003533 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3534}
Devin Moore53fc99c2020-08-12 08:07:52 -07003535
Jooyung Hanfe086af2021-01-16 03:44:47 +09003536TEST_P(AidlTest, UnionInUnion) {
3537 import_paths_.insert(".");
3538 io_delegate_.SetFileContents("Bar.aidl", "union Bar { int n = 42; long l; }");
3539 CaptureStderr();
3540 EXPECT_NE(nullptr, Parse("Foo.aidl", "union Foo { Bar b; int n; }", typenames_, GetLanguage()));
3541 EXPECT_THAT("", GetCapturedStderr());
3542}
3543
Jooyung Hanfe89f122020-10-14 03:49:18 +09003544TEST_P(AidlTest, UnionRejectsEmptyDecl) {
3545 const string method = "package a; union Foo {}";
3546 const string expected_stderr = "ERROR: a/Foo.aidl:1.17-21: The union 'Foo' has no fields.\n";
3547 CaptureStderr();
3548 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3549 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3550}
3551
3552TEST_P(AidlTest, UnionRejectsParcelableHolder) {
3553 const string method = "package a; union Foo { ParcelableHolder x; }";
3554 const string expected_stderr =
3555 "ERROR: a/Foo.aidl:1.40-42: A union can't have a member of ParcelableHolder 'x'\n";
3556 CaptureStderr();
3557 EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3558 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3559}
3560
Jooyung Han53fb4242020-12-17 16:03:49 +09003561TEST_P(AidlTest, UnionRejectsFirstEnumWithNoDefaults) {
3562 import_paths_.insert(".");
3563 io_delegate_.SetFileContents("a/Enum.aidl", "package a; enum Enum { FOO, BAR }");
3564 const string expected_err = "The union's first member should have a useful default value.";
3565 CaptureStderr();
3566 EXPECT_EQ(nullptr,
3567 Parse("a/Foo.aidl", "package a; union Foo { a.Enum e; }", typenames_, GetLanguage()));
3568 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_err));
3569}
3570
Devin Moore53fc99c2020-08-12 08:07:52 -07003571TEST_P(AidlTest, GenericStructuredParcelable) {
3572 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T, U> { int a; int A; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09003573 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Devin Moore53fc99c2020-08-12 08:07:52 -07003574 const string expected_stderr = "";
3575 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003576 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Devin Moore53fc99c2020-08-12 08:07:52 -07003577 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3578}
3579
Jooyung Han3f347ca2020-12-01 12:41:50 +09003580TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
3581 io_delegate_.SetFileContents("Foo.aidl",
3582 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
3583 Options options =
Jooyung Han9435e9a2021-01-06 10:16:31 +09003584 Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::CPP) + " -o out -h out");
Jooyung Han3f347ca2020-12-01 12:41:50 +09003585 const string expected_stderr = "";
3586 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003587 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han3f347ca2020-12-01 12:41:50 +09003588 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3589
3590 string code;
3591 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
3592 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
3593const ::android::String16& Foo<T,U>::s() {
3594 static const ::android::String16 value(::android::String16(""));
3595 return value;
3596})--"));
3597}
3598
3599TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
3600 io_delegate_.SetFileContents("Foo.aidl",
3601 "parcelable Foo<T, U> { int a; const String s = \"\"; }");
3602 Options options =
Jooyung Han9435e9a2021-01-06 10:16:31 +09003603 Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::NDK) + " -o out -h out");
Jooyung Han3f347ca2020-12-01 12:41:50 +09003604 const string expected_stderr = "";
3605 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003606 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han3f347ca2020-12-01 12:41:50 +09003607 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3608
3609 string code;
3610 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
3611 EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
3612const char* Foo<T, U>::s = "";
3613)--"));
3614}
3615
Jooyung Han8c9a4e12020-10-26 15:39:54 +09003616TEST_F(AidlTest, NestedTypeArgs) {
3617 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
Steven Moreland6c07b832020-10-29 23:39:53 +00003618 io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");
3619
3620 io_delegate_.SetFileContents("a/Foo.aidl",
3621 "package a; import a.Bar; import a.Baz; parcelable Foo { "
3622 "Baz<Bar<Bar<String[]>>[], Bar<String>> barss; }");
Jooyung Han8c9a4e12020-10-26 15:39:54 +09003623 Options options = Options::From("aidl a/Foo.aidl -I . -o out --lang=java");
3624 const string expected_stderr = "";
3625 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003626 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han8c9a4e12020-10-26 15:39:54 +09003627 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3628
3629 string code;
3630 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
Steven Moreland6c07b832020-10-29 23:39:53 +00003631 EXPECT_THAT(code,
3632 testing::HasSubstr(
3633 "a.Baz<a.Bar<a.Bar<java.lang.String[]>>[],a.Bar<java.lang.String>> barss;"));
3634}
3635
3636TEST_F(AidlTest, DoubleArrayError) {
3637 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][] a; }");
3638
3639 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3640 const string expected_stderr =
3641 "ERROR: a/Bar.aidl:1.28-37: Can only have one dimensional arrays.\n";
3642 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003643 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Steven Moreland6c07b832020-10-29 23:39:53 +00003644 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3645}
3646
3647TEST_F(AidlTest, DoubleGenericError) {
3648 io_delegate_.SetFileContents("a/Bar.aidl",
3649 "package a; parcelable Bar { List<String><String> a; }");
3650
3651 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3652 const string expected_stderr =
3653 "ERROR: a/Bar.aidl:1.28-33: Can only specify one set of type parameters.\n";
3654 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003655 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Steven Moreland6c07b832020-10-29 23:39:53 +00003656 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3657}
3658
3659TEST_F(AidlTest, ArrayBeforeGenericError) {
3660 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { List[]<String> a; }");
3661
3662 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
Steven Moreland6c07b832020-10-29 23:39:53 +00003663 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003664 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han97c324a2021-02-15 16:09:51 +09003665 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("syntax error, unexpected '<'"));
3666}
3667
3668TEST_F(AidlTest, NullableArraysAreNotSupported) {
3669 io_delegate_.SetFileContents("a/Bar.aidl",
3670 "package a; parcelable Bar { String @nullable [] a; }");
3671
3672 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3673 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003674 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han97c324a2021-02-15 16:09:51 +09003675 EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("Annotations for arrays are not supported."));
3676}
3677
3678TEST_F(AidlTest, ListOfNullablesAreNotSupported) {
3679 io_delegate_.SetFileContents("a/Bar.aidl",
3680 "package a; parcelable Bar { List<@nullable String> a; }");
3681
3682 Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3683 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003684 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han97c324a2021-02-15 16:09:51 +09003685 EXPECT_THAT(GetCapturedStderr(),
3686 testing::HasSubstr("Annotations for type arguments are not supported."));
Jooyung Han8c9a4e12020-10-26 15:39:54 +09003687}
3688
Jooyung Han14004ed2020-10-16 03:49:57 +09003689struct GenericAidlTest : ::testing::Test {
3690 FakeIoDelegate io_delegate_;
3691 void Compile(string cmd) {
Steven Moreland6c07b832020-10-29 23:39:53 +00003692 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { Bar<Baz<Qux>> x; }");
Jooyung Han14004ed2020-10-16 03:49:57 +09003693 io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar<T> { }");
3694 io_delegate_.SetFileContents("Baz.aidl", "parcelable Baz<T> { }");
3695 io_delegate_.SetFileContents("Qux.aidl", "parcelable Qux { }");
3696
3697 Options options = Options::From(cmd);
3698 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003699 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han14004ed2020-10-16 03:49:57 +09003700 EXPECT_EQ("", GetCapturedStderr());
3701 }
3702};
3703
3704TEST_F(GenericAidlTest, ImportGenericParameterTypesCPP) {
3705 Compile("aidl Foo.aidl --lang=cpp -I . -o out -h out");
3706 string code;
3707 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
3708 EXPECT_THAT(code, testing::HasSubstr("#include <Bar.h>"));
3709 EXPECT_THAT(code, testing::HasSubstr("#include <Baz.h>"));
3710 EXPECT_THAT(code, testing::HasSubstr("#include <Qux.h>"));
3711}
3712
3713TEST_F(GenericAidlTest, ImportGenericParameterTypesNDK) {
3714 Compile("aidl Foo.aidl --lang=ndk -I . -o out -h out");
3715 string code;
3716 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
3717 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Bar.h>"));
3718 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Baz.h>"));
3719 EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Qux.h>"));
3720}
3721
Devin Moore53fc99c2020-08-12 08:07:52 -07003722TEST_P(AidlTest, RejectGenericStructuredParcelabelRepeatedParam) {
3723 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { int a; int A; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09003724 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Devin Moore53fc99c2020-08-12 08:07:52 -07003725 const string expected_stderr =
3726 "ERROR: Foo.aidl:1.11-15: Every type parameter should be unique.\n";
3727 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003728 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore53fc99c2020-08-12 08:07:52 -07003729 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3730}
3731
3732TEST_P(AidlTest, RejectGenericStructuredParcelableField) {
3733 io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { T a; int A; }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09003734 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Devin Moore53fc99c2020-08-12 08:07:52 -07003735 const string expected_stderr = "ERROR: Foo.aidl:1.22-24: Failed to resolve 'T'\n";
3736 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003737 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Devin Moore53fc99c2020-08-12 08:07:52 -07003738 EXPECT_EQ(expected_stderr, GetCapturedStderr());
3739}
3740
Jooyung Han7a308842020-10-27 19:06:49 +09003741TEST_P(AidlTest, LongCommentWithinConstExpression) {
3742 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { FOO = (1 << 1) /* comment */ | 0x0 }");
Jooyung Han9435e9a2021-01-06 10:16:31 +09003743 Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
Jooyung Han7a308842020-10-27 19:06:49 +09003744 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003745 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han7a308842020-10-27 19:06:49 +09003746 EXPECT_EQ("", GetCapturedStderr());
3747}
3748
Jeongik Chaef44e622020-10-23 16:00:52 +09003749TEST_F(AidlTest, RejectUntypdeListAndMapInUnion) {
3750 io_delegate_.SetFileContents("a/Foo.aidl", "package a; union Foo { List l; Map m; }");
3751 Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
3752 std::string expectedErr =
3753 "ERROR: a/Foo.aidl:1.28-30: "
3754 "Encountered an untyped List or Map. The use of untyped List/Map is "
3755 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3756 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3757 "ERROR: a/Foo.aidl:1.35-37: "
3758 "Encountered an untyped List or Map. The use of untyped List/Map is "
3759 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3760 "the receiving side. Consider switching to an array or a generic List/Map.\n";
3761 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003762 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jeongik Chaef44e622020-10-23 16:00:52 +09003763 EXPECT_EQ(expectedErr, GetCapturedStderr());
3764}
3765
3766TEST_F(AidlTest, RejectUntypdeListAndMapInUnstructuredParcelable) {
Jooyung Hanea2147c2020-10-21 18:16:56 +09003767 io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { List l; Map m; }");
3768 Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
Jeongik Chaef44e622020-10-23 16:00:52 +09003769 std::string expectedErr =
3770 "ERROR: a/Foo.aidl:1.33-35: "
3771 "Encountered an untyped List or Map. The use of untyped List/Map is "
3772 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3773 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3774 "ERROR: a/Foo.aidl:1.40-42: "
3775 "Encountered an untyped List or Map. The use of untyped List/Map is "
3776 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3777 "the receiving side. Consider switching to an array or a generic List/Map.\n";
Jooyung Hanea2147c2020-10-21 18:16:56 +09003778 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003779 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jeongik Chaef44e622020-10-23 16:00:52 +09003780 EXPECT_EQ(expectedErr, GetCapturedStderr());
3781}
Jooyung Hanea2147c2020-10-21 18:16:56 +09003782
Jeongik Chaef44e622020-10-23 16:00:52 +09003783TEST_F(AidlTest, RejectNestedUntypedListAndMap) {
3784 io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<T>;");
3785 io_delegate_.SetFileContents(
3786 "a/Foo.aidl", "package a; import a.Bar; parcelable Foo { Bar<List> a; Bar<Map> b; }");
3787 Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
3788 std::string expectedErr =
3789 "ERROR: a/Foo.aidl:1.52-54: "
3790 "Encountered an untyped List or Map. The use of untyped List/Map is "
3791 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3792 "the receiving side. Consider switching to an array or a generic List/Map.\n"
3793 "ERROR: a/Foo.aidl:1.64-66: "
3794 "Encountered an untyped List or Map. The use of untyped List/Map is "
3795 "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3796 "the receiving side. Consider switching to an array or a generic List/Map.\n";
3797 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07003798 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jeongik Chaef44e622020-10-23 16:00:52 +09003799 EXPECT_EQ(expectedErr, GetCapturedStderr());
Jooyung Hanea2147c2020-10-21 18:16:56 +09003800}
3801
Jooyung Han690f5842020-12-04 13:02:04 +09003802TEST_F(AidlTest, EnumWithDefaults_Java) {
3803 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3804 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3805package p;
3806import p.Enum;
3807parcelable Foo {
3808 Enum e = Enum.BAR;
3809})");
3810 CaptureStderr();
3811 auto options = Options::From("aidl -I a --lang java -o out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003812 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003813 auto err = GetCapturedStderr();
3814 EXPECT_EQ("", err);
3815
3816 string code;
3817 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.java", &code));
Jooyung Han2d833612020-12-17 15:59:27 +09003818 EXPECT_THAT(code, testing::HasSubstr("byte e = p.Enum.BAR"));
Jooyung Han690f5842020-12-04 13:02:04 +09003819}
3820
3821TEST_F(AidlTest, EnumWithDefaults_Cpp) {
3822 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3823 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3824package p;
3825import p.Enum;
3826parcelable Foo {
3827 Enum e = Enum.BAR;
3828})");
3829 CaptureStderr();
3830 auto options = Options::From("aidl -I a --lang cpp -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003831 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003832 auto err = GetCapturedStderr();
3833 EXPECT_EQ("", err);
3834
3835 string code;
3836 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.h", &code));
3837 EXPECT_THAT(code, testing::HasSubstr("::p::Enum e = ::p::Enum(::p::Enum::BAR);"));
3838}
3839
3840TEST_F(AidlTest, EnumWithDefaults_Ndk) {
3841 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3842 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3843package p;
3844import p.Enum;
3845parcelable Foo {
3846 Enum e = Enum.BAR;
3847})");
3848 CaptureStderr();
3849 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003850 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003851 auto err = GetCapturedStderr();
3852 EXPECT_EQ("", err);
3853
3854 string code;
3855 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
3856 EXPECT_THAT(code, testing::HasSubstr("::aidl::p::Enum e = ::aidl::p::Enum::BAR;"));
3857}
3858
3859TEST_F(AidlTest, EnumWithDefaults_Rust) {
3860 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3861 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3862package p;
3863import p.Enum;
3864parcelable Foo {
3865 int n = 42;
3866 Enum e = Enum.BAR;
3867})");
3868 CaptureStderr();
3869 auto options = Options::From("aidl -I a --lang rust -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003870 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003871 auto err = GetCapturedStderr();
3872 EXPECT_EQ("", err);
3873
3874 string code;
3875 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.rs", &code));
3876 EXPECT_THAT(code, testing::HasSubstr(R"(
3877 fn default() -> Self {
3878 Self {
3879 n: 42,
3880 e: crate::mangled::_1_p_4_Enum::BAR,
3881 }
3882 })"));
3883}
3884
3885TEST_P(AidlTest, EnumeratorIsConstantValue_DefaultValue) {
3886 import_paths_.insert("a");
3887 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
3888 CaptureStderr();
3889 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
3890package p;
3891import p.Enum;
3892parcelable Foo {
3893 int e = Enum.FOO | Enum.BAR;
3894})",
3895 typenames_, GetLanguage());
3896 auto err = GetCapturedStderr();
3897 EXPECT_EQ("", err);
3898 EXPECT_TRUE(type);
3899 const auto& fields = type->AsStructuredParcelable()->GetFields();
3900 EXPECT_EQ("int e = 3", fields[0]->ToString());
3901}
3902
3903TEST_P(AidlTest, EnumeratorIsConstantValue_CanDefineOtherEnumerator) {
3904 CaptureStderr();
3905 const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
3906@Backing(type="int")
3907enum Foo {
3908 STANDARD_SHIFT = 16,
3909 STANDARD_BT709 = 1 << STANDARD_SHIFT,
3910 STANDARD_BT601_625 = 2 << STANDARD_SHIFT,
3911}
3912)",
3913 typenames_, GetLanguage());
3914 auto err = GetCapturedStderr();
3915 EXPECT_EQ("", err);
3916 EXPECT_TRUE(type);
3917 const auto& enum_type = type->AsEnumDeclaration();
3918 string code;
Jooyung Han1f56b702021-02-11 13:16:15 +09003919 auto writer = CodeWriter::ForString(&code);
3920 DumpVisitor visitor(*writer);
3921 visitor.Visit(*enum_type);
3922 writer->Close();
Jooyung Han690f5842020-12-04 13:02:04 +09003923 EXPECT_EQ(R"--(@Backing(type="int")
3924enum Foo {
3925 STANDARD_SHIFT = 16,
3926 STANDARD_BT709 = 65536,
3927 STANDARD_BT601_625 = 131072,
3928}
3929)--",
3930 code);
3931}
3932
3933TEST_F(AidlTest, EnumDefaultShouldBeEnumerators) {
3934 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
3935 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3936package p;
3937import p.Enum;
3938parcelable Foo {
3939 Enum e = Enum.FOO | Enum.BAR;
3940})");
3941 CaptureStderr();
3942 auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003943 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003944 auto err = GetCapturedStderr();
3945 EXPECT_EQ("ERROR: a/p/Foo.aidl:5.11-20: Invalid value (Enum.FOO|Enum.BAR) for enum p.Enum\n",
3946 err);
3947}
3948
Jooyung Han361cd102021-05-24 11:30:10 +09003949TEST_F(AidlTest, EnumDefaultShouldBeEnumerators_RejectsNumericValue) {
3950 io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
3951 io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3952package p;
3953import p.Enum;
3954parcelable Foo {
3955 Enum e = 1;
3956})");
3957 CaptureStderr();
3958 auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003959 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han361cd102021-05-24 11:30:10 +09003960 EXPECT_THAT(GetCapturedStderr(), HasSubstr("Invalid value (1) for enum p.Enum"));
3961}
3962
Jooyung Han690f5842020-12-04 13:02:04 +09003963TEST_P(AidlTest, DefaultWithEmptyArray) {
3964 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; parcelable Foo { p.Bar[] bars = {}; }");
3965 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; parcelable Bar { }");
3966 CaptureStderr();
Jooyung Han9435e9a2021-01-06 10:16:31 +09003967 auto options =
3968 Options::From("aidl -I a --lang " + to_string(GetLanguage()) + " -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003969 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003970 auto err = GetCapturedStderr();
3971 EXPECT_EQ("", err);
3972}
3973
3974TEST_P(AidlTest, RejectRefsInAnnotation) {
3975 io_delegate_.SetFileContents("a/p/IFoo.aidl",
3976 "package p; interface IFoo {\n"
3977 " const String ANNOTATION = \"@Annotation\";\n"
3978 " @JavaPassthrough(annotation=ANNOTATION) void foo();\n"
3979 "}");
3980 CaptureStderr();
Jooyung Han9435e9a2021-01-06 10:16:31 +09003981 auto options =
3982 Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out a/p/IFoo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003983 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003984 auto err = GetCapturedStderr();
3985 EXPECT_EQ(
3986 "ERROR: a/p/IFoo.aidl:3.31-41: Value must be a constant expression but contains reference to "
3987 "ANNOTATION.\n",
3988 err);
3989}
3990
3991TEST_F(AidlTest, DefaultWithEnumValues) {
3992 io_delegate_.SetFileContents(
3993 "a/p/Foo.aidl",
3994 "package p; import p.Bar; parcelable Foo { Bar[] bars = { Bar.FOO, Bar.FOO }; }");
3995 io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; enum Bar { FOO, BAR }");
3996 CaptureStderr();
3997 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07003998 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han690f5842020-12-04 13:02:04 +09003999 auto err = GetCapturedStderr();
4000 EXPECT_EQ("", err);
4001 string code;
4002 EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
4003 EXPECT_THAT(
4004 code, testing::HasSubstr(
4005 "std::vector<::aidl::p::Bar> bars = {::aidl::p::Bar::FOO, ::aidl::p::Bar::FOO};"));
4006}
4007
Jooyung Han14259392020-12-07 10:00:08 +09004008TEST_F(AidlTest, RejectsCircularReferencingEnumerators) {
4009 io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; enum Foo { A = B, B }");
4010 CaptureStderr();
4011 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07004012 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han14259392020-12-07 10:00:08 +09004013 auto err = GetCapturedStderr();
Jooyung Hanb9d60e02021-05-21 07:54:17 +09004014 EXPECT_EQ("ERROR: a/p/Foo.aidl:1.26-28: Found a circular reference: B -> A -> B\n", err);
Jooyung Han14259392020-12-07 10:00:08 +09004015}
4016
4017TEST_F(AidlTest, RejectsCircularReferencingConsts) {
4018 io_delegate_.SetFileContents("a/p/Foo.aidl",
4019 "package p; parcelable Foo { const int A = A + 1; }");
4020 CaptureStderr();
4021 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07004022 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han14259392020-12-07 10:00:08 +09004023 auto err = GetCapturedStderr();
Jooyung Han29813842020-12-08 01:28:03 +09004024 EXPECT_EQ("ERROR: a/p/Foo.aidl:1.42-44: Found a circular reference: A -> A\n", err);
4025}
4026
4027TEST_F(AidlTest, RecursiveReferences) {
4028 io_delegate_.SetFileContents("a/p/Foo.aidl",
4029 "package p; parcelable Foo { const int A = p.Bar.A + 1; }");
4030 io_delegate_.SetFileContents("a/p/Bar.aidl",
4031 "package p; parcelable Bar { const int A = p.Baz.A + 1; }");
4032 io_delegate_.SetFileContents("a/p/Baz.aidl", "package p; parcelable Baz { const int A = 1; }");
4033 CaptureStderr();
4034 auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
Steven Moreland4e059132021-08-11 13:36:30 -07004035 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han29813842020-12-08 01:28:03 +09004036 EXPECT_EQ("", GetCapturedStderr());
4037}
4038
Jooyung Hanb9d60e02021-05-21 07:54:17 +09004039TEST_P(AidlTest, CircularReferenceWithFullyQualified) {
4040 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = Foo.A }");
4041 auto options =
4042 Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Foo.aidl");
4043 const string err = "ERROR: Foo.aidl:1.15-21: Found a circular reference: Foo.A -> Foo.A\n";
4044 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004045 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Hanb9d60e02021-05-21 07:54:17 +09004046 EXPECT_EQ(err, GetCapturedStderr());
4047}
4048
4049TEST_P(AidlTest, ConstRefsCanPointToTheSameValue) {
4050 io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = 0 }");
4051 // this demonstrates the case that "Foo.A" const-ref node is visited twice by B and C.
4052 io_delegate_.SetFileContents("Bar.aidl", "enum Bar { A = Foo.A, B = A, C = A }");
4053 auto options =
4054 Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Bar.aidl");
4055 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004056 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Hanb9d60e02021-05-21 07:54:17 +09004057 EXPECT_EQ("", GetCapturedStderr());
4058}
4059
Jooyung Hane9f5b272021-01-07 00:18:11 +09004060TEST_P(AidlTest, UnknownConstReference) {
4061 io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { UnknownType field = UNKNOWN_REF; }");
4062 auto options =
4063 Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
4064 const string err =
4065 "ERROR: Foo.aidl:1.18-30: Failed to resolve 'UnknownType'\n"
4066 "ERROR: Foo.aidl:1.38-50: Can't find UNKNOWN_REF in Foo\n"
4067 "ERROR: Foo.aidl:1.38-50: Unknown reference 'UNKNOWN_REF'\n";
4068 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004069 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Hane9f5b272021-01-07 00:18:11 +09004070 EXPECT_EQ(err, GetCapturedStderr());
4071}
4072
Jooyung Han29813842020-12-08 01:28:03 +09004073TEST_P(AidlTest, JavaCompatibleBuiltinTypes) {
4074 string contents = R"(
4075import android.os.IBinder;
4076import android.os.IInterface;
4077interface IFoo {}
4078 )";
4079 EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
Jooyung Han14259392020-12-07 10:00:08 +09004080}
4081
Jooyung Han888c5bc2020-12-22 17:28:47 +09004082TEST_P(AidlTest, WarningInterfaceName) {
4083 io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004084 auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
Jooyung Han888c5bc2020-12-22 17:28:47 +09004085 " -Weverything -o out -h out p/Foo.aidl");
4086 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004087 EXPECT_TRUE(compile_aidl(options, io_delegate_));
Jooyung Han808a2a02020-12-28 16:46:54 +09004088 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 +09004089 GetCapturedStderr());
4090}
4091
4092TEST_P(AidlTest, ErrorInterfaceName) {
4093 io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
Jooyung Han9435e9a2021-01-06 10:16:31 +09004094 auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
Jooyung Han888c5bc2020-12-22 17:28:47 +09004095 " -Weverything -Werror -o out -h out p/Foo.aidl");
4096 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004097 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han808a2a02020-12-28 16:46:54 +09004098 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 +09004099 GetCapturedStderr());
4100}
4101
Jiyong Park9f4c3822021-04-07 20:36:45 +09004102TEST_F(AidlTest, RejectsIncorrectOutputFilePathOnLegacyCppInput) {
4103 const std::string input_file = "base/p/q/IFoo.aidl";
4104 const std::string header_dir = "out/";
4105 const std::string output_file = "out/base/p/q/IFoo.cpp";
4106 const std::string package = "p.q"; // not base.p.q
4107 io_delegate_.SetFileContents(input_file, "package " + package + "; interface IFoo {}");
4108
4109 auto options = Options::From({"aidl-cpp", input_file, header_dir, output_file});
4110 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004111 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jiyong Park9f4c3822021-04-07 20:36:45 +09004112 EXPECT_THAT(
4113 GetCapturedStderr(),
4114 testing::StartsWith(
4115 "ERROR: base/p/q/IFoo.aidl:1.13-23: Output file is expected to be at out/p/q/IFoo.cpp, "
4116 "but is out/base/p/q/IFoo.cpp."));
4117}
4118
Jooyung Hanb7a60ec2021-01-21 13:47:59 +09004119TEST_F(AidlTest, FormatCommentsForJava) {
4120 using android::aidl::FormatCommentsForJava;
4121
4122 struct TestCase {
4123 vector<Comment> comments;
4124 string formatted;
4125 };
4126 vector<TestCase> testcases = {
4127 {{}, ""},
4128 {{{"// line comments\n"}}, "// line comments\n"},
4129 {{{"// @hide \n"}}, "// @hide \n"},
4130 // Transform the last block comment as Javadoc.
4131 {{{"/*\n"
4132 " * Hello, world!\n"
4133 " */"}},
4134 "/**\n"
4135 " * Hello, world!\n"
4136 " */"},
4137 {{{"/* @hide */"}}, "/** @hide */"},
4138 {{{"/**\n"
4139 " @param foo ...\n"
4140 "*/"}},
4141 "/**\n"
4142 " @param foo ...\n"
4143 "*/"},
4144 {{{"/* @hide */"}, {"/* @hide */"}}, "/* @hide *//** @hide */"},
4145 {{{"/* @deprecated first */"}, {"/* @deprecated second */"}},
4146 "/* @deprecated first *//** @deprecated second */"},
4147 {{{"/* @deprecated */"}, {"/** @param foo */"}}, "/* @deprecated *//** @param foo */"},
4148 // Line comments are printed as they are
4149 {{{"/* @deprecated */"}, {"// line comments\n"}}, "/* @deprecated */// line comments\n"},
4150 };
4151 for (const auto& [input, formatted] : testcases) {
4152 EXPECT_EQ(formatted, FormatCommentsForJava(input));
4153 }
4154}
4155
Jooyung Han2d6b5c42021-01-09 01:01:06 +09004156TEST_F(AidlTest, HideIsNotForArgs) {
4157 io_delegate_.SetFileContents("IFoo.aidl",
4158 "interface IFoo {\n"
4159 " void foo(in @Hide int x);\n"
4160 "}");
4161 auto options = Options::From("aidl --lang=java IFoo.aidl");
4162 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004163 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han2d6b5c42021-01-09 01:01:06 +09004164 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@Hide is not available"));
4165}
4166
4167TEST_F(AidlTest, SuppressWarningsIsNotForArgs) {
4168 io_delegate_.SetFileContents(
4169 "IFoo.aidl",
4170 "interface IFoo {\n"
4171 " void foo(in @SuppressWarnings(value=\"inout-parameter\") int x);\n"
4172 "}");
4173 auto options = Options::From("aidl --lang=java IFoo.aidl");
4174 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004175 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Han2d6b5c42021-01-09 01:01:06 +09004176 EXPECT_THAT(GetCapturedStderr(), HasSubstr("@SuppressWarnings is not available"));
4177}
4178
Jooyung Hanfa181932021-06-12 07:56:53 +09004179TEST_F(AidlTest, VoidCantBeUsedInMethodParameterType) {
4180 io_delegate_.SetFileContents("p/IFoo.aidl", "interface IFoo{ void j(void n);}");
4181 auto options = Options::From("aidl --lang=java -o out p/IFoo.aidl");
4182 CaptureStderr();
Steven Moreland4e059132021-08-11 13:36:30 -07004183 EXPECT_FALSE(compile_aidl(options, io_delegate_));
Jooyung Hanfa181932021-06-12 07:56:53 +09004184 EXPECT_THAT(GetCapturedStderr(), HasSubstr("'void' is an invalid type for the parameter 'n'"));
4185}
4186
Jooyung Hanfd3be322020-12-13 09:11:06 +09004187struct TypeParam {
Jooyung Hane87cdd02020-12-11 16:47:35 +09004188 string kind;
4189 string literal;
4190};
4191
Jooyung Hanfd3be322020-12-13 09:11:06 +09004192const TypeParam kTypeParams[] = {
Jooyung Hancea89002021-02-15 17:04:04 +09004193 {"primitive", "int"}, {"primitiveArray", "int[]"},
4194 {"String", "String"}, {"StringArray", "String[]"},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004195 {"IBinder", "IBinder"}, {"ParcelFileDescriptor", "ParcelFileDescriptor"},
4196 {"parcelable", "Foo"}, {"enum", "a.Enum"},
4197 {"union", "a.Union"}, {"interface", "a.IBar"},
4198};
4199
4200const std::map<std::string, std::string> kListSupportExpectations = {
4201 {"cpp_primitive", "A generic type cannot have any primitive type parameters."},
4202 {"java_primitive", "A generic type cannot have any primitive type parameters."},
4203 {"ndk_primitive", "A generic type cannot have any primitive type parameters."},
4204 {"rust_primitive", "A generic type cannot have any primitive type parameters."},
Jooyung Hancea89002021-02-15 17:04:04 +09004205 {"cpp_primitiveArray", "List of arrays is not supported."},
4206 {"java_primitiveArray", "List of arrays is not supported."},
4207 {"ndk_primitiveArray", "List of arrays is not supported."},
4208 {"rust_primitiveArray", "List of arrays is not supported."},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004209 {"cpp_String", ""},
4210 {"java_String", ""},
4211 {"ndk_String", ""},
4212 {"rust_String", ""},
Jooyung Hancea89002021-02-15 17:04:04 +09004213 {"cpp_StringArray", "List of arrays is not supported."},
4214 {"java_StringArray", "List of arrays is not supported."},
4215 {"ndk_StringArray", "List of arrays is not supported."},
4216 {"rust_StringArray", "List of arrays is not supported."},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004217 {"cpp_IBinder", ""},
4218 {"java_IBinder", ""},
4219 {"ndk_IBinder", "List<IBinder> is not supported. List in NDK doesn't support IBinder."},
4220 {"rust_IBinder", ""},
Jooyung Han55f96ad2020-12-13 10:08:33 +09004221 {"cpp_ParcelFileDescriptor", ""},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004222 {"java_ParcelFileDescriptor", ""},
4223 {"ndk_ParcelFileDescriptor", ""},
4224 {"rust_ParcelFileDescriptor", ""},
Jooyung Han55f96ad2020-12-13 10:08:33 +09004225 {"cpp_interface", "List<a.IBar> is not supported."},
4226 {"java_interface", "List<a.IBar> is not supported."},
4227 {"ndk_interface", "List<a.IBar> is not supported."},
4228 {"rust_interface", "List<a.IBar> is not supported."},
4229 {"cpp_parcelable", ""},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004230 {"java_parcelable", ""},
4231 {"ndk_parcelable", ""},
4232 {"rust_parcelable", ""},
4233 {"cpp_enum", "A generic type cannot have any primitive type parameters."},
4234 {"java_enum", "A generic type cannot have any primitive type parameters."},
4235 {"ndk_enum", "A generic type cannot have any primitive type parameters."},
4236 {"rust_enum", "A generic type cannot have any primitive type parameters."},
Jooyung Han55f96ad2020-12-13 10:08:33 +09004237 {"cpp_union", ""},
Jooyung Hane87cdd02020-12-11 16:47:35 +09004238 {"java_union", ""},
4239 {"ndk_union", ""},
4240 {"rust_union", ""},
4241};
4242
Jooyung Hand236e552020-12-13 09:21:27 +09004243const std::map<std::string, std::string> kArraySupportExpectations = {
4244 {"cpp_primitive", ""},
4245 {"java_primitive", ""},
4246 {"ndk_primitive", ""},
4247 {"rust_primitive", ""},
Jooyung Hancea89002021-02-15 17:04:04 +09004248 {"cpp_primitiveArray", "Can only have one dimensional arrays."},
4249 {"java_primitiveArray", "Can only have one dimensional arrays."},
4250 {"ndk_primitiveArray", "Can only have one dimensional arrays."},
4251 {"rust_primitiveArray", "Can only have one dimensional arrays."},
Jooyung Hand236e552020-12-13 09:21:27 +09004252 {"cpp_String", ""},
4253 {"java_String", ""},
4254 {"ndk_String", ""},
4255 {"rust_String", ""},
Jooyung Hancea89002021-02-15 17:04:04 +09004256 {"cpp_StringArray", "Can only have one dimensional arrays."},
4257 {"java_StringArray", "Can only have one dimensional arrays."},
4258 {"ndk_StringArray", "Can only have one dimensional arrays."},
4259 {"rust_StringArray", "Can only have one dimensional arrays."},
Jooyung Hand236e552020-12-13 09:21:27 +09004260 {"cpp_IBinder", ""},
4261 {"java_IBinder", ""},
4262 {"ndk_IBinder", "The ndk backend does not support array of IBinder"},
4263 {"rust_IBinder", "The rust backend does not support array of IBinder"},
4264 {"cpp_ParcelFileDescriptor", ""},
4265 {"java_ParcelFileDescriptor", ""},
4266 {"ndk_ParcelFileDescriptor", ""},
4267 {"rust_ParcelFileDescriptor", ""},
4268 {"cpp_interface", "Binder type cannot be an array"},
4269 {"java_interface", "Binder type cannot be an array"},
4270 {"ndk_interface", "Binder type cannot be an array"},
4271 {"rust_interface", "Binder type cannot be an array"},
4272 {"cpp_parcelable", ""},
4273 {"java_parcelable", ""},
4274 {"ndk_parcelable", ""},
4275 {"rust_parcelable", ""},
4276 {"cpp_enum", ""},
4277 {"java_enum", ""},
4278 {"ndk_enum", ""},
4279 {"rust_enum", ""},
4280 {"cpp_union", ""},
4281 {"java_union", ""},
4282 {"ndk_union", ""},
4283 {"rust_union", ""},
4284};
4285
Jooyung Hanfd3be322020-12-13 09:11:06 +09004286class AidlTypeParamTest : public testing::TestWithParam<std::tuple<Options::Language, TypeParam>> {
Jooyung Hane87cdd02020-12-11 16:47:35 +09004287 public:
Jooyung Hanfd3be322020-12-13 09:11:06 +09004288 void Run(const std::string& generic_type_decl,
4289 const std::map<std::string, std::string>& expectations) {
Jooyung Hane87cdd02020-12-11 16:47:35 +09004290 const auto& param = GetParam();
Jooyung Han9435e9a2021-01-06 10:16:31 +09004291 const auto& lang = to_string(std::get<0>(param));
Jooyung Hane87cdd02020-12-11 16:47:35 +09004292 const auto& kind = std::get<1>(param).kind;
4293
4294 FakeIoDelegate io;
4295 io.SetFileContents("a/IBar.aidl", "package a; interface IBar { }");
4296 io.SetFileContents("a/Enum.aidl", "package a; enum Enum { A }");
4297 io.SetFileContents("a/Union.aidl", "package a; union Union { int a; }");
Jooyung Hanfd3be322020-12-13 09:11:06 +09004298 std::string decl = fmt::format(generic_type_decl, std::get<1>(param).literal);
4299 io.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { " + decl + " f; }");
Jooyung Hane87cdd02020-12-11 16:47:35 +09004300
4301 const auto options =
4302 Options::From(fmt::format("aidl -I . --lang={} a/Foo.aidl -o out -h out", lang));
4303 CaptureStderr();
4304 compile_aidl(options, io);
Jooyung Hanfd3be322020-12-13 09:11:06 +09004305 auto it = expectations.find(lang + "_" + kind);
4306 EXPECT_TRUE(it != expectations.end());
Jooyung Hane87cdd02020-12-11 16:47:35 +09004307 const string err = GetCapturedStderr();
4308 if (it->second.empty()) {
4309 EXPECT_EQ("", err);
4310 } else {
4311 EXPECT_THAT(err, testing::HasSubstr(it->second));
4312 }
4313 }
4314};
4315
4316INSTANTIATE_TEST_SUITE_P(
Jooyung Hanfd3be322020-12-13 09:11:06 +09004317 AidlTestSuite, AidlTypeParamTest,
Jooyung Hane87cdd02020-12-11 16:47:35 +09004318 testing::Combine(testing::Values(Options::Language::CPP, Options::Language::JAVA,
4319 Options::Language::NDK, Options::Language::RUST),
Jooyung Hanfd3be322020-12-13 09:11:06 +09004320 testing::ValuesIn(kTypeParams)),
4321 [](const testing::TestParamInfo<std::tuple<Options::Language, TypeParam>>& info) {
Jooyung Han9435e9a2021-01-06 10:16:31 +09004322 return to_string(std::get<0>(info.param)) + "_" + std::get<1>(info.param).kind;
Jooyung Hane87cdd02020-12-11 16:47:35 +09004323 });
4324
Jooyung Hanfd3be322020-12-13 09:11:06 +09004325TEST_P(AidlTypeParamTest, ListSupportedTypes) {
4326 Run("List<{}>", kListSupportExpectations);
4327}
Jooyung Hane87cdd02020-12-11 16:47:35 +09004328
Jooyung Hand236e552020-12-13 09:21:27 +09004329TEST_P(AidlTypeParamTest, ArraySupportedTypes) {
4330 Run("{}[]", kArraySupportExpectations);
4331}
4332
Christopher Wiley90be4e32015-10-20 14:55:25 -07004333} // namespace aidl
4334} // namespace android