blob: b7f61581058881721092e3128844ea70f82958a5 [file] [log] [blame]
// Copyright (c) 2019, 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.features;
import com.android.tools.r8.FeatureSplit;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.Sets;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class FeatureSplitConfiguration {
private final List<FeatureSplit> featureSplits;
private final Map<String, FeatureSplit> javaTypeToFeatureSplitMapping = new HashMap<>();
public FeatureSplitConfiguration(List<FeatureSplit> featureSplits, Reporter reporter) {
this.featureSplits = featureSplits;
for (FeatureSplit featureSplit : featureSplits) {
for (ProgramResourceProvider programResourceProvider :
featureSplit.getProgramResourceProviders()) {
try {
for (ProgramResource programResource : programResourceProvider.getProgramResources()) {
for (String classDescriptor : programResource.getClassDescriptors()) {
javaTypeToFeatureSplitMapping.put(
DescriptorUtils.descriptorToJavaType(classDescriptor), featureSplit);
}
}
} catch (ResourceException e) {
throw reporter.fatalError(e.getMessage());
}
}
}
}
public Map<FeatureSplit, Set<DexProgramClass>> getFeatureSplitClasses(
Set<DexProgramClass> classes, ClassNameMapper mapper) {
Map<FeatureSplit, Set<DexProgramClass>> result = new IdentityHashMap<>();
for (DexProgramClass programClass : classes) {
String originalClassName =
DescriptorUtils.descriptorToJavaType(programClass.type.toDescriptorString(), mapper);
FeatureSplit featureSplit = javaTypeToFeatureSplitMapping.get(originalClassName);
if (featureSplit != null) {
result.computeIfAbsent(featureSplit, f -> Sets.newIdentityHashSet()).add(programClass);
}
}
return result;
}
public boolean inSameFeatureOrBase(DexMethod a, DexMethod b) {
return inSameFeatureOrBase(a.holder, b.holder);
}
public boolean inSameFeatureOrBase(DexType a, DexType b) {
assert a.isClassType() && b.isClassType();
if (javaTypeToFeatureSplitMapping.isEmpty()) {
return true;
}
// TODO(141451259): Consider doing the mapping from DexType to Feature (with support in mapper)
return javaTypeToFeatureSplitMapping.get(
DescriptorUtils.descriptorToJavaType(a.toDescriptorString()))
== javaTypeToFeatureSplitMapping.get(
DescriptorUtils.descriptorToJavaType(b.toDescriptorString()));
}
public List<FeatureSplit> getFeatureSplits() {
return featureSplits;
}
}