summaryrefslogtreecommitdiff
path: root/tools/aapt2/link/TableMerger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/link/TableMerger.cpp')
-rw-r--r--tools/aapt2/link/TableMerger.cpp61
1 files changed, 49 insertions, 12 deletions
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index e819f51a5634..d777e22fa4b7 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -101,8 +101,18 @@ static bool MergeType(IAaptContext* context, const Source& src, ResourceTableTyp
return true;
}
-static bool MergeEntry(IAaptContext* context, const Source& src, bool overlay,
- ResourceEntry* dst_entry, ResourceEntry* src_entry) {
+static bool MergeEntry(IAaptContext* context, const Source& src,
+ ResourceEntry* dst_entry, ResourceEntry* src_entry,
+ bool strict_visibility) {
+ if (strict_visibility
+ && dst_entry->visibility.level != Visibility::Level::kUndefined
+ && src_entry->visibility.level != dst_entry->visibility.level) {
+ context->GetDiagnostics()->Error(
+ DiagMessage(src) << "cannot merge resource '" << dst_entry->name << "' with conflicting visibilities: "
+ << "public and private");
+ return false;
+ }
+
// Copy over the strongest visibility.
if (src_entry->visibility.level > dst_entry->visibility.level) {
// Only copy the ID if the source is public, or else the ID is meaningless.
@@ -124,17 +134,35 @@ static bool MergeEntry(IAaptContext* context, const Source& src, bool overlay,
dst_entry->allow_new = std::move(src_entry->allow_new);
}
- if (src_entry->overlayable) {
- if (dst_entry->overlayable && !overlay) {
- context->GetDiagnostics()->Error(DiagMessage(src_entry->overlayable.value().source)
- << "duplicate overlayable declaration for resource '"
- << src_entry->name << "'");
- context->GetDiagnostics()->Error(DiagMessage(dst_entry->overlayable.value().source)
- << "previous declaration here");
- return false;
+ for (auto& src_overlayable : src_entry->overlayable_declarations) {
+ for (auto& dst_overlayable : dst_entry->overlayable_declarations) {
+ // An overlayable resource cannot be declared twice with the same policy
+ if (src_overlayable.policy == dst_overlayable.policy) {
+ context->GetDiagnostics()->Error(DiagMessage(src_overlayable.source)
+ << "duplicate overlayable declaration for resource '"
+ << src_entry->name << "'");
+ context->GetDiagnostics()->Error(DiagMessage(dst_overlayable.source)
+ << "previous declaration here");
+ return false;
+ }
+
+ // An overlayable resource cannot be declared once with a policy and without a policy because
+ // the policy becomes unused
+ if (!src_overlayable.policy || !dst_overlayable.policy) {
+ context->GetDiagnostics()->Error(DiagMessage(src_overlayable.source)
+ << "overlayable resource '" << src_entry->name
+ << "' declared once with a policy and once with no "
+ << "policy");
+ context->GetDiagnostics()->Error(DiagMessage(dst_overlayable.source)
+ << "previous declaration here");
+ return false;
+ }
}
- dst_entry->overlayable = std::move(src_entry->overlayable);
}
+
+ dst_entry->overlayable_declarations.insert(dst_entry->overlayable_declarations.end(),
+ src_entry->overlayable_declarations.begin(),
+ src_entry->overlayable_declarations.end());
return true;
}
@@ -234,7 +262,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
continue;
}
- if (!MergeEntry(context_, src, overlay, dst_entry, src_entry.get())) {
+ if (!MergeEntry(context_, src, dst_entry, src_entry.get(), options_.strict_visibility)) {
error = true;
continue;
}
@@ -271,8 +299,17 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
dst_config_value->value = std::move(new_file_ref);
} else {
+ Maybe<std::string> original_comment = (dst_config_value->value)
+ ? dst_config_value->value->GetComment() : Maybe<std::string>();
+
dst_config_value->value = std::unique_ptr<Value>(
src_config_value->value->Clone(&master_table_->string_pool));
+
+ // Keep the comment from the original resource and ignore all comments from overlaying
+ // resources
+ if (overlay && original_comment) {
+ dst_config_value->value->SetComment(original_comment.value());
+ }
}
}
}