Skip to content

Commit

Permalink
Mark merged field final if all input fields are final
Browse files Browse the repository at this point in the history
Summary: If all the input fields are `final`, we keep them as final in the merged class. There seems to be a growing trend that Kotlin code tends to mark fields with `final` by default.

Reviewed By: NTillmann

Differential Revision: D56374098

fbshipit-source-id: 11309a1ed8b3bfac93e99d638a9cccc0beaf9b67
  • Loading branch information
Wei Zhang (Devinfra) authored and facebook-github-bot committed Apr 24, 2024
1 parent dd268f1 commit dc2977b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
24 changes: 21 additions & 3 deletions service/class-merging/ClassAssemblingUtils.cpp
Expand Up @@ -104,11 +104,12 @@ DexClass* create_class(const DexType* type,
return cls;
}

std::vector<DexField*> create_merger_fields(
const DexType* owner, const std::vector<DexField*>& mergeable_fields) {
std::vector<DexField*> create_merger_fields(const DexType* owner,
const FieldsMap& fields_map) {
std::vector<DexField*> res;
const auto& mergeable_fields = fields_map.begin()->second;
size_t cnt = 0;
for (const auto f : mergeable_fields) {
for (const auto* f : mergeable_fields) {
auto type = f->get_type();
std::string name;
if (type == type::_byte() || type == type::_char() ||
Expand Down Expand Up @@ -147,6 +148,23 @@ std::vector<DexField*> create_merger_fields(
cnt++;
}

std::vector<bool> acc_final_map(mergeable_fields.size(), true);
for (const auto& fmap : fields_map) {
const auto& fields = fmap.second;
for (size_t i = 0; i < fields.size(); i++) {
redex_assert(acc_final_map.size() > i);
acc_final_map[i] = acc_final_map.at(i) && is_final(fields[i]);
}
}

for (size_t i = 0; i < res.size(); i++) {
redex_assert(acc_final_map.size() > i);
if (acc_final_map[i]) {
set_final(res.at(i));
TRACE(CLMG, 5, "marking merger field final %s", SHOW(res.at(i)));
}
}

TRACE(CLMG, 8, " created merger fields %zu ", res.size());
return res;
}
Expand Down
4 changes: 2 additions & 2 deletions service/class-merging/ClassAssemblingUtils.h
Expand Up @@ -21,8 +21,8 @@ struct ModelSpec;
constexpr const char* INTERNAL_TYPE_TAG_FIELD_NAME = "$t";
constexpr const char* EXTERNAL_TYPE_TAG_FIELD_NAME = "mTypeTag";

std::vector<DexField*> create_merger_fields(
const DexType* owner, const std::vector<DexField*>& mergeable_fields);
std::vector<DexField*> create_merger_fields(const DexType* owner,
const FieldsMap& fields_map);

void cook_merger_fields_lookup(
const std::vector<DexField*>& new_fields,
Expand Down
7 changes: 3 additions & 4 deletions service/class-merging/ModelMerger.cpp
Expand Up @@ -504,10 +504,9 @@ const std::vector<DexField*> ModelMerger::empty_fields =
std::vector<DexField*>();

void ModelMerger::update_merger_fields(const MergerType& merger) {
auto merger_fields =
merger.has_fields()
? create_merger_fields(merger.type, merger.field_map.begin()->second)
: empty_fields;
auto merger_fields = merger.has_fields()
? create_merger_fields(merger.type, merger.field_map)
: empty_fields;
m_merger_fields[merger.type] = merger_fields;
}

Expand Down

0 comments on commit dc2977b

Please sign in to comment.