blob: 979eb9c31b070633b044ec053163e565a416a0fc [file] [log] [blame]
// Copyright (c) 2021, 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.ir.desugar.nest;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexType;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class Nest {
private final DexClass hostClass;
private final List<DexClass> members;
private final List<DexType> missingMembers;
private Nest(DexClass hostClass, List<DexClass> members, List<DexType> missingMembers) {
this.hostClass = hostClass;
this.members = members;
this.missingMembers = missingMembers;
}
public static Nest create(AppView<?> appView, DexClass clazz) {
return create(appView, clazz, null);
}
public static Nest create(
AppView<?> appView, DexClass clazz, Consumer<DexClass> missingHostConsumer) {
assert clazz.isInANest();
DexClass hostClass = clazz.isNestHost() ? clazz : appView.definitionFor(clazz.getNestHost());
if (hostClass == null) {
// Missing nest host means the class is considered as not being part of a nest.
if (missingHostConsumer != null) {
missingHostConsumer.accept(clazz);
}
return null;
}
List<DexClass> members = new ArrayList<>(hostClass.getNestMembersClassAttributes().size());
List<DexType> missingMembers = new ArrayList<>();
hostClass.forEachNestMember(
memberType -> {
DexClass memberClass = appView.definitionFor(memberType);
if (memberClass != null) {
members.add(memberClass);
} else {
missingMembers.add(memberType);
}
});
return new Nest(hostClass, members, missingMembers);
}
public Iterable<DexClasspathClass> getClasspathMembers() {
return Iterables.transform(
Iterables.filter(members, DexClass::isClasspathClass), DexClass::asClasspathClass);
}
public DexClass getHostClass() {
return hostClass;
}
public List<DexClass> getMembers() {
return members;
}
public List<DexType> getMissingMembers() {
return missingMembers;
}
public boolean hasLibraryMember() {
return Iterables.any(members, DexClass::isLibraryClass);
}
public boolean hasMissingMembers() {
return !missingMembers.isEmpty();
}
}