@JavaDerive(equals=true)
@JavaDerive(equals=true) on a parcelable or an union produces equals and
hashCode implementations for the Java backend.
equals is implemented by calling Objects.deepEquals for each pairs of
the two objects.
hashCode is implemented by converting the fields into Object[] and pass
it to Objects.deepHashCode.
Bug: 161442291
Test: aidl_unittests
Test: atest aidl_integration_test
Change-Id: I28edd08a9ca49cc2883cbc225358796785beed73
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 0c69d39..35d5edd 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -622,6 +622,68 @@
EXPECT_THAT(java_out, testing::HasSubstr(expected_to_string_method));
}
+TEST_F(AidlTest, ParcelableSupportJavaDeriveEquals) {
+ io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
+ @JavaDerive(equals=true) parcelable Foo { int a; float b; })");
+ CaptureStderr();
+ Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
+ EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
+ EXPECT_EQ("", GetCapturedStderr());
+
+ const std::string expected = R"--(
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if (other == null) return false;
+ if (!(other instanceof Foo)) return false;
+ Foo that = (Foo)other;
+ if (!java.util.Objects.deepEquals(a, that.a)) return false;
+ if (!java.util.Objects.deepEquals(b, that.b)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return java.util.Arrays.deepHashCode(java.util.Arrays.asList(a, b).toArray());
+ }
+)--";
+
+ string java_out;
+ EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
+ EXPECT_THAT(java_out, testing::HasSubstr(expected));
+}
+
+TEST_F(AidlTest, UnionSupportJavaDeriveEquals) {
+ io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
+ @JavaDerive(equals=true) union Foo { int a; int[] b; })");
+ CaptureStderr();
+ Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
+ EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
+ EXPECT_EQ("", GetCapturedStderr());
+
+ const std::string expected = R"--(
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if (other == null) return false;
+ if (!(other instanceof Foo)) return false;
+ Foo that = (Foo)other;
+ if (_tag != that._tag) return false;
+ if (!java.util.Objects.deepEquals(_value, that._value)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return java.util.Arrays.deepHashCode(java.util.Arrays.asList(_tag, _value).toArray());
+ }
+)--";
+
+ string java_out;
+ EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
+ EXPECT_THAT(java_out, testing::HasSubstr(expected));
+}
+
TEST_F(AidlTest, RejectsJavaDeriveAnnotation) {
{
io_delegate_.SetFileContents("a/Foo.aidl",