aboutsummaryrefslogtreecommitdiff
path: root/aidl_checkapi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'aidl_checkapi.cpp')
-rw-r--r--aidl_checkapi.cpp25
1 files changed, 16 insertions, 9 deletions
diff --git a/aidl_checkapi.cpp b/aidl_checkapi.cpp
index 5a9cb23f..72577ca6 100644
--- a/aidl_checkapi.cpp
+++ b/aidl_checkapi.cpp
@@ -195,15 +195,6 @@ static bool are_compatible_parcelables(const AidlStructuredParcelable& older,
const auto& new_field = new_fields.at(i);
compatible &= are_compatible_types(old_field->GetType(), new_field->GetType());
- // Note: unlike method argument names, field name change is an incompatible
- // change, otherwise, we can't detect
- // parcelable Point {int x; int y;} -> parcelable Point {int y; int x;}
- if (old_field->GetName() != new_field->GetName()) {
- AIDL_ERROR(newer) << "Renamed field: " << old_field->GetName() << " to "
- << new_field->GetName() << ".";
- compatible = false;
- }
-
const string old_value = old_field->ValueString(AidlConstantValueDecorator);
const string new_value = new_field->ValueString(AidlConstantValueDecorator);
if (old_value != new_value) {
@@ -212,6 +203,22 @@ static bool are_compatible_parcelables(const AidlStructuredParcelable& older,
}
}
+ // Reordering of fields is an incompatible change.
+ for (size_t i = 0; i < new_fields.size(); i++) {
+ const auto& new_field = new_fields.at(i);
+ auto found = std::find_if(old_fields.begin(), old_fields.end(), [&new_field](const auto& f) {
+ return new_field->GetName() == f->GetName();
+ });
+ if (found != old_fields.end()) {
+ size_t old_index = std::distance(old_fields.begin(), found);
+ if (old_index != i) {
+ AIDL_ERROR(new_field) << "Reordered " << new_field->GetName() << " from " << old_index
+ << " to " << i << ".";
+ compatible = false;
+ }
+ }
+ }
+
for (size_t i = old_fields.size(); i < new_fields.size(); i++) {
const auto& new_field = new_fields.at(i);
if (!new_field->GetDefaultValue() && !has_usable_nil_type(new_field->GetType())) {