blob: 80180f6b1a109a016048927aecfd637bc07344f0 [file] [log] [blame]
// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.horizontalclassmerging;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMergerGraphLens.Builder;
import java.util.LinkedHashMap;
import java.util.Map;
public class ClassStaticFieldsMerger {
private final Builder lensBuilder;
private final MergeGroup group;
private final Map<DexField, DexEncodedField> targetFields = new LinkedHashMap<>();
private final DexItemFactory dexItemFactory;
public ClassStaticFieldsMerger(
AppView<?> appView, HorizontalClassMergerGraphLens.Builder lensBuilder, MergeGroup group) {
this.lensBuilder = lensBuilder;
this.group = group;
// Add mappings for all target fields.
group
.getTarget()
.staticFields()
.forEach(field -> targetFields.put(field.getReference(), field));
this.dexItemFactory = appView.dexItemFactory();
}
private boolean isFresh(DexField fieldReference) {
return !targetFields.containsKey(fieldReference);
}
private void addField(DexEncodedField field) {
DexField oldFieldReference = field.getReference();
DexField templateReference =
field.getReference().withHolder(group.getTarget().getType(), dexItemFactory);
DexField newFieldReference =
dexItemFactory.createFreshFieldNameWithHolderSuffix(
templateReference, field.getHolderType(), this::isFresh);
field = field.toTypeSubstitutedField(newFieldReference);
targetFields.put(newFieldReference, field);
lensBuilder.recordNewFieldSignature(oldFieldReference, newFieldReference);
}
public void addFields(DexProgramClass toMerge) {
toMerge.staticFields().forEach(this::addField);
}
public void merge(DexProgramClass clazz) {
clazz.setStaticFields(targetFields.values().toArray(DexEncodedField.EMPTY_ARRAY));
}
}