union: java backend
union is a parcelable which can hold only a single field with a tag.
Example:
union Union {
int n;
String s;
}
In Java, you can instantiate it with
- default constructor: init with first field
- value constructor: Union.n(42) or Union.s("abc")
You can query "tag" before getting the contents from it.
It also supports getter/setter.
Example:
void foo(Union u) {
if (u.getTag() == Union.n) { // query
int n = u.getN(); // getter
...
}
u.setS("abc"); // setter
}
Bug: 150948558
Test: atest aidl_integration_test
Change-Id: I5c2d87e09462c0d3c6617d73fdf0e49c281d551e
diff --git a/aidl_checkapi.cpp b/aidl_checkapi.cpp
index 0f2f4b0..f20b5ca 100644
--- a/aidl_checkapi.cpp
+++ b/aidl_checkapi.cpp
@@ -182,8 +182,8 @@
return specifier.IsNullable();
}
-static bool are_compatible_parcelables(const AidlStructuredParcelable& older,
- const AidlStructuredParcelable& newer) {
+template <typename ParcelableType>
+static bool are_compatible_parcelables(const ParcelableType& older, const ParcelableType& newer) {
const auto& old_fields = older.GetFields();
const auto& new_fields = newer.GetFields();
if (old_fields.size() > new_fields.size()) {
@@ -370,6 +370,16 @@
}
compatible &= are_compatible_parcelables(*(old_type->AsStructuredParcelable()),
*(new_type->AsStructuredParcelable()));
+ } else if (old_type->AsUnionDeclaration() != nullptr) {
+ if (new_type->AsUnionDeclaration() == nullptr) {
+ AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
+ << " is changed from " << old_type->GetPreprocessDeclarationName()
+ << " to " << new_type->GetPreprocessDeclarationName();
+ compatible = false;
+ continue;
+ }
+ compatible &= are_compatible_parcelables(*(old_type->AsUnionDeclaration()),
+ *(new_type->AsUnionDeclaration()));
} else if (old_type->AsEnumDeclaration() != nullptr) {
if (new_type->AsEnumDeclaration() == nullptr) {
AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()