Merge "Fix a bug in DexAnnotationDirectory.equals."
diff --git a/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java b/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java
index 3c3c2b9..9583e9c 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassAndMemberPublicizer.java
@@ -4,19 +4,6 @@
package com.android.tools.r8.graph;
public abstract class ClassAndMemberPublicizer {
-
- private static void publicizeAllMethods(DexEncodedMethod[] methods) {
- for (DexEncodedMethod method : methods) {
- method.accessFlags.promoteNonPrivateToPublic();
- }
- }
-
- private static void publicizeAllFields(DexEncodedField[] fields) {
- for (DexEncodedField field : fields) {
- field.accessFlags.promoteToPublic();
- }
- }
-
/**
* Marks all package private and protected methods and fields as public.
* <p>
@@ -25,10 +12,8 @@
public static DexApplication run(DexApplication application) {
for (DexClass clazz : application.classes()) {
clazz.accessFlags.promoteToPublic();
- publicizeAllFields(clazz.staticFields());
- publicizeAllFields(clazz.instanceFields());
- publicizeAllMethods(clazz.directMethods());
- publicizeAllMethods(clazz.virtualMethods());
+ clazz.forEachMethod( method -> method.accessFlags.promoteNonPrivateToPublic());
+ clazz.forEachField( field -> field.accessFlags.promoteToPublic());
}
return application;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java b/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
index 6887d0f..4277324 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
@@ -48,10 +48,6 @@
}
}
- public DexProgramClass getDexProgramClass() {
- return clazz;
- }
-
public DexAnnotationSet getClazzAnnotations() {
return clazz.annotations;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 5b1b0f3..b28f06c 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -95,6 +95,15 @@
return result;
}
+ public void forEachField(Consumer<DexEncodedField> consumer) {
+ for (DexEncodedField field : staticFields()) {
+ consumer.accept(field);
+ }
+ for (DexEncodedField field : instanceFields()) {
+ consumer.accept(field);
+ }
+ }
+
public DexEncodedField[] staticFields() {
return MoreObjects.firstNonNull(staticFields, NO_FIELDS);
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 36d732d..04e34a5 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -50,95 +50,95 @@
public static final DexType catchAllType = new DexType(new DexString("CATCH_ALL"));
private static final Set<DexItem> internalSentinels = ImmutableSet.of(catchAllType);
- public DexString booleanDescriptor = createString("Z");
- public DexString byteDescriptor = createString("B");
- public DexString charDescriptor = createString("C");
- public DexString doubleDescriptor = createString("D");
- public DexString floatDescriptor = createString("F");
- public DexString intDescriptor = createString("I");
- public DexString longDescriptor = createString("J");
- public DexString shortDescriptor = createString("S");
- public DexString voidDescriptor = createString("V");
+ public final DexString booleanDescriptor = createString("Z");
+ public final DexString byteDescriptor = createString("B");
+ public final DexString charDescriptor = createString("C");
+ public final DexString doubleDescriptor = createString("D");
+ public final DexString floatDescriptor = createString("F");
+ public final DexString intDescriptor = createString("I");
+ public final DexString longDescriptor = createString("J");
+ public final DexString shortDescriptor = createString("S");
+ public final DexString voidDescriptor = createString("V");
- public DexString boxedBooleanDescriptor = createString("Ljava/lang/Boolean;");
- public DexString boxedByteDescriptor = createString("Ljava/lang/Byte;");
- public DexString boxedCharDescriptor = createString("Ljava/lang/Character;");
- public DexString boxedDoubleDescriptor = createString("Ljava/lang/Double;");
- public DexString boxedFloatDescriptor = createString("Ljava/lang/Float;");
- public DexString boxedIntDescriptor = createString("Ljava/lang/Integer;");
- public DexString boxedLongDescriptor = createString("Ljava/lang/Long;");
- public DexString boxedShortDescriptor = createString("Ljava/lang/Short;");
- public DexString boxedNumberDescriptor = createString("Ljava/lang/Number;");
+ public final DexString boxedBooleanDescriptor = createString("Ljava/lang/Boolean;");
+ public final DexString boxedByteDescriptor = createString("Ljava/lang/Byte;");
+ public final DexString boxedCharDescriptor = createString("Ljava/lang/Character;");
+ public final DexString boxedDoubleDescriptor = createString("Ljava/lang/Double;");
+ public final DexString boxedFloatDescriptor = createString("Ljava/lang/Float;");
+ public final DexString boxedIntDescriptor = createString("Ljava/lang/Integer;");
+ public final DexString boxedLongDescriptor = createString("Ljava/lang/Long;");
+ public final DexString boxedShortDescriptor = createString("Ljava/lang/Short;");
+ public final DexString boxedNumberDescriptor = createString("Ljava/lang/Number;");
- public DexString unboxBooleanMethodName = createString("booleanValue");
- public DexString unboxByteMethodName = createString("byteValue");
- public DexString unboxCharMethodName = createString("charValue");
- public DexString unboxShortMethodName = createString("shortValue");
- public DexString unboxIntMethodName = createString("intValue");
- public DexString unboxLongMethodName = createString("longValue");
- public DexString unboxFloatMethodName = createString("floatValue");
- public DexString unboxDoubleMethodName = createString("doubleValue");
+ public final DexString unboxBooleanMethodName = createString("booleanValue");
+ public final DexString unboxByteMethodName = createString("byteValue");
+ public final DexString unboxCharMethodName = createString("charValue");
+ public final DexString unboxShortMethodName = createString("shortValue");
+ public final DexString unboxIntMethodName = createString("intValue");
+ public final DexString unboxLongMethodName = createString("longValue");
+ public final DexString unboxFloatMethodName = createString("floatValue");
+ public final DexString unboxDoubleMethodName = createString("doubleValue");
- public DexString valueOfMethodName = createString("valueOf");
+ public final DexString valueOfMethodName = createString("valueOf");
- public DexString getClassMethodName = createString("getClass");
- public DexString ordinalMethodName = createString("ordinal");
+ public final DexString getClassMethodName = createString("getClass");
+ public final DexString ordinalMethodName = createString("ordinal");
public final DexString desiredAssertionStatusMethodName = createString("desiredAssertionStatus");
public final DexString assertionsDisabled = createString("$assertionsDisabled");
- public DexString stringDescriptor = createString("Ljava/lang/String;");
- public DexString objectDescriptor = createString("Ljava/lang/Object;");
- public DexString classDescriptor = createString("Ljava/lang/Class;");
- public DexString enumDescriptor = createString("Ljava/lang/Enum;");
- public DexString annotationDescriptor = createString("Ljava/lang/annotation/Annotation;");
- public DexString throwableDescriptor = createString("Ljava/lang/Throwable;");
- public DexString objectsDescriptor = createString("Ljava/util/Objects;");
+ public final DexString stringDescriptor = createString("Ljava/lang/String;");
+ public final DexString objectDescriptor = createString("Ljava/lang/Object;");
+ public final DexString classDescriptor = createString("Ljava/lang/Class;");
+ public final DexString enumDescriptor = createString("Ljava/lang/Enum;");
+ public final DexString annotationDescriptor = createString("Ljava/lang/annotation/Annotation;");
+ public final DexString throwableDescriptor = createString("Ljava/lang/Throwable;");
+ public final DexString objectsDescriptor = createString("Ljava/util/Objects;");
- public DexString constructorMethodName = createString(Constants.INSTANCE_INITIALIZER_NAME);
- public DexString classConstructorMethodName = createString(Constants.CLASS_INITIALIZER_NAME);
+ public final DexString constructorMethodName = createString(Constants.INSTANCE_INITIALIZER_NAME);
+ public final DexString classConstructorMethodName = createString(Constants.CLASS_INITIALIZER_NAME);
- public DexString thisName = createString("this");
+ public final DexString thisName = createString("this");
- private DexString charArrayDescriptor = createString("[C");
- private DexType charArrayType = createType(charArrayDescriptor);
- public DexString throwableArrayDescriptor = createString("[Ljava/lang/Throwable;");
+ private final DexString charArrayDescriptor = createString("[C");
+ private final DexType charArrayType = createType(charArrayDescriptor);
+ public final DexString throwableArrayDescriptor = createString("[Ljava/lang/Throwable;");
- public DexType booleanType = createType(booleanDescriptor);
- public DexType byteType = createType(byteDescriptor);
- public DexType charType = createType(charDescriptor);
- public DexType doubleType = createType(doubleDescriptor);
- public DexType floatType = createType(floatDescriptor);
- public DexType intType = createType(intDescriptor);
- public DexType longType = createType(longDescriptor);
- public DexType shortType = createType(shortDescriptor);
- public DexType voidType = createType(voidDescriptor);
+ public final DexType booleanType = createType(booleanDescriptor);
+ public final DexType byteType = createType(byteDescriptor);
+ public final DexType charType = createType(charDescriptor);
+ public final DexType doubleType = createType(doubleDescriptor);
+ public final DexType floatType = createType(floatDescriptor);
+ public final DexType intType = createType(intDescriptor);
+ public final DexType longType = createType(longDescriptor);
+ public final DexType shortType = createType(shortDescriptor);
+ public final DexType voidType = createType(voidDescriptor);
- public DexType boxedBooleanType = createType(boxedBooleanDescriptor);
- public DexType boxedByteType = createType(boxedByteDescriptor);
- public DexType boxedCharType = createType(boxedCharDescriptor);
- public DexType boxedDoubleType = createType(boxedDoubleDescriptor);
- public DexType boxedFloatType = createType(boxedFloatDescriptor);
- public DexType boxedIntType = createType(boxedIntDescriptor);
- public DexType boxedLongType = createType(boxedLongDescriptor);
- public DexType boxedShortType = createType(boxedShortDescriptor);
- public DexType boxedNumberType = createType(boxedNumberDescriptor);
+ public final DexType boxedBooleanType = createType(boxedBooleanDescriptor);
+ public final DexType boxedByteType = createType(boxedByteDescriptor);
+ public final DexType boxedCharType = createType(boxedCharDescriptor);
+ public final DexType boxedDoubleType = createType(boxedDoubleDescriptor);
+ public final DexType boxedFloatType = createType(boxedFloatDescriptor);
+ public final DexType boxedIntType = createType(boxedIntDescriptor);
+ public final DexType boxedLongType = createType(boxedLongDescriptor);
+ public final DexType boxedShortType = createType(boxedShortDescriptor);
+ public final DexType boxedNumberType = createType(boxedNumberDescriptor);
- public DexType stringType = createType(stringDescriptor);
- public DexType objectType = createType(objectDescriptor);
- public DexType enumType = createType(enumDescriptor);
- public DexType annotationType = createType(annotationDescriptor);
- public DexType throwableType = createType(throwableDescriptor);
+ public final DexType stringType = createType(stringDescriptor);
+ public final DexType objectType = createType(objectDescriptor);
+ public final DexType enumType = createType(enumDescriptor);
+ public final DexType annotationType = createType(annotationDescriptor);
+ public final DexType throwableType = createType(throwableDescriptor);
- public DexType stringBuilderType = createType("Ljava/lang/StringBuilder;");
- public DexType stringBufferType = createType("Ljava/lang/StringBuffer;");
+ public final DexType stringBuilderType = createType("Ljava/lang/StringBuilder;");
+ public final DexType stringBufferType = createType("Ljava/lang/StringBuffer;");
- public StringBuildingMethods stringBuilderMethods = new StringBuildingMethods(stringBuilderType);
- public StringBuildingMethods stringBufferMethods = new StringBuildingMethods(stringBufferType);
- public ObjectsMethods objectsMethods = new ObjectsMethods();
- public ObjectMethods objectMethods = new ObjectMethods();
- public LongMethods longMethods = new LongMethods();
- public ThrowableMethods throwableMethods = new ThrowableMethods();
- public ClassMethods classMethods = new ClassMethods();
+ public final StringBuildingMethods stringBuilderMethods = new StringBuildingMethods(stringBuilderType);
+ public final StringBuildingMethods stringBufferMethods = new StringBuildingMethods(stringBufferType);
+ public final ObjectsMethods objectsMethods = new ObjectsMethods();
+ public final ObjectMethods objectMethods = new ObjectMethods();
+ public final LongMethods longMethods = new LongMethods();
+ public final ThrowableMethods throwableMethods = new ThrowableMethods();
+ public final ClassMethods classMethods = new ClassMethods();
// Dex system annotations.
// See https://source.android.com/devices/tech/dalvik/dex-format.html#system-annotation
@@ -161,7 +161,7 @@
public class LongMethods {
- public DexMethod compare;
+ public final DexMethod compare;
private LongMethods() {
compare = createMethod(boxedLongDescriptor,
@@ -184,11 +184,11 @@
public class ObjectMethods {
- public DexMethod getClass;
+ public final DexMethod getClass;
private ObjectMethods() {
- getClass = createMethod(objectsDescriptor,
- getClassMethodName, classDescriptor, new DexString[]{});
+ getClass = createMethod(objectsDescriptor, getClassMethodName, classDescriptor,
+ DexString.EMPTY_ARRAY);
}
}
@@ -208,27 +208,27 @@
private ClassMethods() {
desiredAssertionStatus = createMethod(classDescriptor,
- desiredAssertionStatusMethodName, booleanDescriptor, new DexString[]{});
+ desiredAssertionStatusMethodName, booleanDescriptor, DexString.EMPTY_ARRAY);
}
}
public class StringBuildingMethods {
- public DexMethod appendBoolean;
- public DexMethod appendChar;
- public DexMethod appendCharArray;
- public DexMethod appendSubCharArray;
- public DexMethod appendCharSequence;
- public DexMethod appendSubCharSequence;
- public DexMethod appendInt;
- public DexMethod appendDouble;
- public DexMethod appendFloat;
- public DexMethod appendLong;
- public DexMethod appendObject;
- public DexMethod appendString;
- public DexMethod appendStringBuffer;
- public DexMethod toString;
+ public final DexMethod appendBoolean;
+ public final DexMethod appendChar;
+ public final DexMethod appendCharArray;
+ public final DexMethod appendSubCharArray;
+ public final DexMethod appendCharSequence;
+ public final DexMethod appendSubCharSequence;
+ public final DexMethod appendInt;
+ public final DexMethod appendDouble;
+ public final DexMethod appendFloat;
+ public final DexMethod appendLong;
+ public final DexMethod appendObject;
+ public final DexMethod appendString;
+ public final DexMethod appendStringBuffer;
+ public final DexMethod toString;
private StringBuildingMethods(DexType receiver) {
DexType sbufType = createType(createString("Ljava/lang/StringBuffer;"));
@@ -236,7 +236,6 @@
DexString append = createString("append");
DexString toStringMethodName = createString("toString");
-
appendBoolean = createMethod(receiver, createProto(receiver, booleanType), append);
appendChar = createMethod(receiver, createProto(receiver, charType), append);
appendCharArray = createMethod(receiver, createProto(receiver, charArrayType), append);
@@ -282,7 +281,7 @@
synchronized private DexString canonicalizeString(String key) {
assert key != null;
- return strings.computeIfAbsent(key, k -> new DexString(k));
+ return strings.computeIfAbsent(key, DexString::new);
}
public DexString createString(int size, byte[] content) {
@@ -382,56 +381,31 @@
public AdvanceLine createAdvanceLine(int delta) {
synchronized (advanceLines) {
- AdvanceLine result = advanceLines.get(delta);
- if (result == null) {
- result = new AdvanceLine(delta);
- advanceLines.put(delta, result);
- }
- return result;
+ return advanceLines.computeIfAbsent(delta, AdvanceLine::new);
}
}
public AdvancePC createAdvancePC(int delta) {
synchronized (advancePCs) {
- AdvancePC result = advancePCs.get(delta);
- if (result == null) {
- result = new AdvancePC(delta);
- advancePCs.put(delta, result);
- }
- return result;
+ return advancePCs.computeIfAbsent(delta, AdvancePC::new);
}
}
public Default createDefault(int value) {
synchronized (defaults) {
- Default result = defaults.get(value);
- if (result == null) {
- result = new Default(value);
- defaults.put(value, result);
- }
- return result;
+ return defaults.computeIfAbsent(value, Default::new);
}
}
public EndLocal createEndLocal(int registerNum) {
synchronized (endLocals) {
- EndLocal result = endLocals.get(registerNum);
- if (result == null) {
- result = new EndLocal(registerNum);
- endLocals.put(registerNum, result);
- }
- return result;
+ return endLocals.computeIfAbsent(registerNum, EndLocal::new);
}
}
public RestartLocal createRestartLocal(int registerNum) {
synchronized (restartLocals) {
- RestartLocal result = restartLocals.get(registerNum);
- if (result == null) {
- result = new RestartLocal(registerNum);
- restartLocals.put(registerNum, result);
- }
- return result;
+ return restartLocals.computeIfAbsent(registerNum, RestartLocal::new);
}
}
@@ -445,12 +419,7 @@
public SetFile createSetFile(DexString fileName) {
synchronized (setFiles) {
- SetFile result = setFiles.get(fileName);
- if (result == null) {
- result = new SetFile(fileName);
- setFiles.put(fileName, result);
- }
- return result;
+ return setFiles.computeIfAbsent(fileName, SetFile::new);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
index f4406c0..9c76d74 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* Call graph representation.
@@ -82,16 +83,6 @@
}
@Override
- public int hashCode() {
- return method.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return this == obj;
- }
-
- @Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("MethodNode for: ");
@@ -139,7 +130,6 @@
return (value != null) && value.contains(callee);
}
- private List<Node> leaves = null;
private Set<DexEncodedMethod> singleCallSite = Sets.newIdentityHashSet();
private Set<DexEncodedMethod> doubleCallSite = Sets.newIdentityHashSet();
@@ -159,7 +149,6 @@
graph.breakCycles();
assert graph.breakCycles() == 0; // This time the cycles should be gone.
graph.fillCallSiteSets(appInfo);
- graph.fillInitialLeaves();
return graph;
}
@@ -195,16 +184,6 @@
}
}
- private void fillInitialLeaves() {
- assert leaves == null;
- leaves = new ArrayList<>();
- for (Node node : nodes.values()) {
- if (node.isLeaf()) {
- leaves.add(node);
- }
- }
- }
-
private static boolean allMethodsExists(DexApplication application, CallGraph graph) {
for (DexProgramClass clazz : application.classes()) {
clazz.forEachMethod( method -> { assert graph.nodes.get(method) != null; });
@@ -213,28 +192,10 @@
}
/**
- * Remove all leaves (nodes with an call (outgoing) degree of 0).
- *
- * @return List of {@link DexEncodedMethod} of the leaves removed.
- */
- private List<DexEncodedMethod> removeLeaves() {
- List<DexEncodedMethod> result = new ArrayList<>();
- List<Node> newLeaves = new ArrayList<>();
- for (Node leaf : leaves) {
- assert nodes.containsKey(leaf.method) && nodes.get(leaf.method).callees.isEmpty();
- remove(leaf, newLeaves);
- result.add(leaf.method);
- }
- leaves = newLeaves;
- return result;
- }
-
- /**
- * Pick the next set of leaves (nodes with an call (outgoing) degree of 0) if any.
+ * Extract the next set of leaves (nodes with an call (outgoing) degree of 0) if any.
* <p>
- * If the graph has no leaves then some cycles in the graph will be broken to create a set of
- * leaves. See {@link #breakCycles} on how cycles are broken. This ensures that at least one
- * leave is returned if the graph is not empty.
+ * All nodes in the graph are extracted if called repeatedly until null is returned.
+ * Please note that there are no cycles in this graph (see {@link #breakCycles}).
* <p>
*
* @return List of {@link DexEncodedMethod}.
@@ -243,13 +204,16 @@
if (isEmpty()) {
return null;
}
- List<DexEncodedMethod> leaves = removeLeaves();
- assert leaves.size() > 0;
- leaves.forEach( leaf -> { assert !leaf.isProcessed(); });
- return leaves;
+ // First identify all leaves before removing them from the graph.
+ List<Node> leaves = nodes.values().stream().filter(Node::isLeaf).collect(Collectors.toList());
+ leaves.forEach( leaf -> {
+ leaf.callers.forEach( caller -> caller.callees.remove(leaf));
+ nodes.remove(leaf.method);
+ });
+ return leaves.stream().map( leaf -> leaf.method).collect(Collectors.toList());
}
- private int traverse(Node node, HashSet<Node> stack, HashSet<Node> marked) {
+ private int traverse(Node node, Set<Node> stack, Set<Node> marked) {
int numberOfCycles = 0;
if (!marked.contains(node)) {
assert !stack.contains(node);
@@ -268,7 +232,8 @@
// We have a cycle; break it by removing node->callee.
toBeRemoved.add(callee);
callee.callers.remove(node);
- breakers.computeIfAbsent(node.method, ignore -> new HashSet<>()).add(callee.method);
+ breakers.computeIfAbsent(node.method,
+ ignore -> Sets.newIdentityHashSet()).add(callee.method);
} else {
numberOfCycles += traverse(callee, stack, marked);
}
@@ -287,8 +252,8 @@
// Break cycles in this call graph by removing edges causing cycles.
// The remove edges are stored in @breakers.
int numberOfCycles = 0;
- HashSet<Node> stack = new HashSet<>();
- HashSet<Node> marked = new HashSet<>();
+ Set<Node> stack = Sets.newIdentityHashSet();
+ Set<Node> marked = Sets.newIdentityHashSet();
for(Node node : nodes.values()) {
numberOfCycles += traverse(node, stack, marked);
}
@@ -311,18 +276,6 @@
callee.invokeCount++;
}
- private void remove(Node node, List<Node> leaves) {
- assert node != null;
- for (Node caller : node.callers) {
- boolean removed = caller.callees.remove(node);
- if (caller.isLeaf()) {
- leaves.add(caller);
- }
- assert removed;
- }
- nodes.remove(node.method);
- }
-
public boolean isEmpty() {
return nodes.size() == 0;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
index 3ab231c..4cd44ef 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -107,25 +107,19 @@
keep.ensureValid(minificationEnabled);
for (DexProgramClass clazz : appInfo.classes()) {
clazz.annotations = stripAnnotations(clazz.annotations, this::filterAnnotations);
- processMethods(clazz.virtualMethods());
- processMethods(clazz.directMethods());
- processFields(clazz.staticFields());
- processFields(clazz.instanceFields());
+ clazz.forEachMethod(this::processMethod);
+ clazz.forEachField(this::processField);
}
}
- private void processMethods(DexEncodedMethod[] methods) {
- for (DexEncodedMethod method : methods) {
- method.annotations = stripAnnotations(method.annotations, this::filterAnnotations);
- method.parameterAnnotations = stripAnnotations(method.parameterAnnotations,
- this::filterParameterAnnotations);
- }
+ private void processMethod(DexEncodedMethod method) {
+ method.annotations = stripAnnotations(method.annotations, this::filterAnnotations);
+ method.parameterAnnotations = stripAnnotations(method.parameterAnnotations,
+ this::filterParameterAnnotations);
}
- private void processFields(DexEncodedField[] fields) {
- for (DexEncodedField field : fields) {
+ private void processField(DexEncodedField field) {
field.annotations = stripAnnotations(field.annotations, this::filterAnnotations);
- }
}
private DexAnnotationSetRefList stripAnnotations(DexAnnotationSetRefList annotations,
diff --git a/src/main/java/com/android/tools/r8/shaking/DiscardedChecker.java b/src/main/java/com/android/tools/r8/shaking/DiscardedChecker.java
index 75b7495..a7a27fe 100644
--- a/src/main/java/com/android/tools/r8/shaking/DiscardedChecker.java
+++ b/src/main/java/com/android/tools/r8/shaking/DiscardedChecker.java
@@ -24,25 +24,19 @@
public void run() {
for (DexProgramClass clazz : application.classes()) {
- if (checkDiscarded.contains(clazz)) {
- report(clazz);
- }
- processSubItems(clazz.directMethods());
- processSubItems(clazz.virtualMethods());
- processSubItems(clazz.staticFields());
- processSubItems(clazz.instanceFields());
+ checkItem(clazz);
+ clazz.forEachMethod(this::checkItem);
+ clazz.forEachField(this::checkItem);
}
if (fail) {
throw new CompilationError("Discard checks failed.");
}
}
- private void processSubItems(DexItem[] items) {
- Arrays.stream(items).filter(checkDiscarded::contains).forEach(this::report);
- }
-
- private void report(DexItem item) {
- System.err.println("Item " + item.toSourceString() + " was not discarded.");
- fail = true;
+ private void checkItem(DexItem item) {
+ if (checkDiscarded.contains(item)) {
+ System.err.println("Item " + item.toSourceString() + " was not discarded.");
+ fail = true;
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java b/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
index 4b978e2..8a7ee43 100644
--- a/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
@@ -150,20 +150,11 @@
addMainDexType(type);
// Super and interfaces are live, no need to add them.
traceAnnotationsDirectDendencies(clazz.annotations);
- for (DexEncodedField field : clazz.instanceFields()) {
- addMainDexType(field.field.type);
- }
- for (DexEncodedField field : clazz.staticFields()) {
- addMainDexType(field.field.type);
- }
- for (DexEncodedMethod method : clazz.directMethods()) {
+ clazz.forEachField( field -> addMainDexType(field.field.type));
+ clazz.forEachMethod( method -> {
traceMethodDirectDependencies(method.method);
method.registerReachableDefinitions(codeDirectReferenceCollector);
- }
- for (DexEncodedMethod method : clazz.virtualMethods()) {
- traceMethodDirectDependencies(method.method);
- method.registerReachableDefinitions(codeDirectReferenceCollector);
- }
+ });
}
}