|  | // 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)); | 
|  | } | 
|  | } |