blob: ba5d775ec8fd0105e513246398be52110c2f02a4 [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.DexClass;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.IteratorUtils;
import com.google.common.collect.Iterables;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class MergeGroup implements Collection<DexProgramClass> {
public static class Metadata {}
private final LinkedList<DexProgramClass> classes;
private DexField classIdField;
private DexProgramClass target = null;
private Metadata metadata = null;
public MergeGroup() {
this.classes = new LinkedList<>();
}
public MergeGroup(DexProgramClass clazz) {
this();
add(clazz);
}
public MergeGroup(Iterable<DexProgramClass> classes) {
this();
Iterables.addAll(this.classes, classes);
}
public void applyMetadataFrom(MergeGroup group) {
if (metadata == null) {
metadata = group.metadata;
}
}
@Override
public boolean add(DexProgramClass clazz) {
return classes.add(clazz);
}
public boolean add(MergeGroup group) {
return classes.addAll(group.getClasses());
}
@Override
public boolean addAll(Collection<? extends DexProgramClass> classes) {
return this.classes.addAll(classes);
}
@Override
public void clear() {
classes.clear();
}
@Override
public boolean contains(Object o) {
return classes.contains(o);
}
@Override
public boolean containsAll(Collection<?> collection) {
return classes.containsAll(collection);
}
public void forEachSource(Consumer<DexProgramClass> consumer) {
assert hasTarget();
for (DexProgramClass clazz : classes) {
if (clazz != target) {
consumer.accept(clazz);
}
}
}
public LinkedList<DexProgramClass> getClasses() {
return classes;
}
public boolean hasClassIdField() {
return classIdField != null;
}
public DexField getClassIdField() {
assert hasClassIdField();
return classIdField;
}
public void setClassIdField(DexField classIdField) {
this.classIdField = classIdField;
}
public Iterable<DexProgramClass> getSources() {
assert hasTarget();
return Iterables.filter(classes, clazz -> clazz != target);
}
public DexType getSuperType() {
assert IterableUtils.allIdentical(classes, DexClass::getSuperType);
return getClasses().getFirst().getSuperType();
}
public boolean hasTarget() {
return target != null;
}
public DexProgramClass getTarget() {
return target;
}
public void setTarget(DexProgramClass target) {
assert classes.contains(target);
this.target = target;
}
public boolean isTrivial() {
return size() < 2;
}
public boolean isNonTrivial() {
return !isTrivial();
}
@Override
public boolean isEmpty() {
return classes.isEmpty();
}
public boolean isClassGroup() {
return !isInterfaceGroup();
}
public boolean isInterfaceGroup() {
assert !isEmpty();
assert IterableUtils.allIdentical(getClasses(), DexClass::isInterface);
return getClasses().getFirst().isInterface();
}
@Override
public Iterator<DexProgramClass> iterator() {
return classes.iterator();
}
@Override
public int size() {
return classes.size();
}
@Override
public boolean remove(Object o) {
return classes.remove(o);
}
@Override
public boolean removeAll(Collection<?> collection) {
return classes.removeAll(collection);
}
public DexProgramClass removeFirst(Predicate<DexProgramClass> predicate) {
return IteratorUtils.removeFirst(iterator(), predicate);
}
@Override
public boolean removeIf(Predicate<? super DexProgramClass> predicate) {
return classes.removeIf(predicate);
}
public DexProgramClass removeLast() {
return classes.removeLast();
}
@Override
public boolean retainAll(Collection<?> collection) {
return collection.retainAll(collection);
}
@Override
public Object[] toArray() {
return classes.toArray();
}
@Override
public <T> T[] toArray(T[] ts) {
return classes.toArray(ts);
}
}