Merge "Remove enclosing method attrs that reference pruned items."
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 61161bb..48c2cde 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -4,12 +4,12 @@
package com.android.tools.r8;
import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graphinfo.GraphConsumer;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.MainDexClasses;
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java b/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
index a1a2837..a55033a 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graphinfo.GraphConsumer;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.ProguardConfigurationParser;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 5c82a50..c1664a6 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
@@ -19,7 +20,6 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graphinfo.GraphConsumer;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.optimize.EnumOrdinalMapCollector;
import com.android.tools.r8.ir.optimize.MethodPoolCollection;
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index e533101..39630f3 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -5,8 +5,8 @@
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graphinfo.GraphConsumer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.origin.StandardOutOrigin;
diff --git a/src/main/java/com/android/tools/r8/graphinfo/AnnotationGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/AnnotationGraphNode.java
similarity index 94%
rename from src/main/java/com/android/tools/r8/graphinfo/AnnotationGraphNode.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/AnnotationGraphNode.java
index c317293..5242510 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/AnnotationGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/AnnotationGraphNode.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
import com.android.tools.r8.Keep;
diff --git a/src/main/java/com/android/tools/r8/graphinfo/ClassGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/ClassGraphNode.java
similarity index 94%
rename from src/main/java/com/android/tools/r8/graphinfo/ClassGraphNode.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/ClassGraphNode.java
index 41bd498..edbffbe 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/ClassGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/ClassGraphNode.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
import com.android.tools.r8.Keep;
import com.android.tools.r8.references.ClassReference;
diff --git a/src/main/java/com/android/tools/r8/graphinfo/FieldGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/FieldGraphNode.java
similarity index 94%
rename from src/main/java/com/android/tools/r8/graphinfo/FieldGraphNode.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/FieldGraphNode.java
index 9ae9a5b..b091613 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/FieldGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/FieldGraphNode.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
import com.android.tools.r8.Keep;
import com.android.tools.r8.references.FieldReference;
diff --git a/src/main/java/com/android/tools/r8/graphinfo/GraphConsumer.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphConsumer.java
similarity index 91%
rename from src/main/java/com/android/tools/r8/graphinfo/GraphConsumer.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/GraphConsumer.java
index 8c124e5..3c7bda1 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/GraphConsumer.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphConsumer.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
import com.android.tools.r8.KeepForSubclassing;
diff --git a/src/main/java/com/android/tools/r8/graphinfo/GraphEdgeInfo.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphEdgeInfo.java
similarity index 95%
rename from src/main/java/com/android/tools/r8/graphinfo/GraphEdgeInfo.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/GraphEdgeInfo.java
index c0b3f3b..0c838ac 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/GraphEdgeInfo.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphEdgeInfo.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
public class GraphEdgeInfo {
diff --git a/src/main/java/com/android/tools/r8/graphinfo/GraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphNode.java
similarity index 92%
rename from src/main/java/com/android/tools/r8/graphinfo/GraphNode.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/GraphNode.java
index f248978..b99485a 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/GraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphNode.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
import com.android.tools.r8.Keep;
diff --git a/src/main/java/com/android/tools/r8/graphinfo/KeepRuleGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/KeepRuleGraphNode.java
similarity index 97%
rename from src/main/java/com/android/tools/r8/graphinfo/KeepRuleGraphNode.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/KeepRuleGraphNode.java
index 05a6e3d..7eb55a8 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/KeepRuleGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/KeepRuleGraphNode.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
import com.android.tools.r8.Keep;
import com.android.tools.r8.origin.Origin;
diff --git a/src/main/java/com/android/tools/r8/graphinfo/MethodGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/MethodGraphNode.java
similarity index 94%
rename from src/main/java/com/android/tools/r8/graphinfo/MethodGraphNode.java
rename to src/main/java/com/android/tools/r8/experimental/graphinfo/MethodGraphNode.java
index 494ddd4..94fe8e7 100644
--- a/src/main/java/com/android/tools/r8/graphinfo/MethodGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/MethodGraphNode.java
@@ -1,7 +1,7 @@
// Copyright (c) 2018, 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.graphinfo;
+package com.android.tools.r8.experimental.graphinfo;
import com.android.tools.r8.Keep;
import com.android.tools.r8.references.MethodReference;
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLense.java
index 1c74f79..247a5fe 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLense.java
@@ -424,14 +424,30 @@
return this == getIdentityLense();
}
- public <T extends DexDefinition> boolean assertDefinitionNotModified(Iterable<T> items) {
- for (DexDefinition item : items) {
- DexReference dexReference = item.toReference();
- DexReference lookupedReference = lookupReference(dexReference);
+ public <T extends DexDefinition> boolean assertDefinitionsNotModified(Iterable<T> definitions) {
+ for (DexDefinition definition : definitions) {
+ DexReference reference = definition.toReference();
// We allow changes to bridge methods as these get retargeted even if they are kept.
boolean isBridge =
- item.isDexEncodedMethod() && item.asDexEncodedMethod().accessFlags.isBridge();
- assert isBridge || dexReference == lookupedReference;
+ definition.isDexEncodedMethod() && definition.asDexEncodedMethod().accessFlags.isBridge();
+ assert isBridge || lookupReference(reference) == reference;
+ }
+ return true;
+ }
+
+ public <T extends DexReference> boolean assertReferencesNotModified(Iterable<T> references) {
+ for (DexReference reference : references) {
+ if (reference.isDexField()) {
+ DexField field = reference.asDexField();
+ assert getRenamedFieldSignature(field) == field;
+ } else if (reference.isDexMethod()) {
+ DexMethod method = reference.asDexMethod();
+ assert getRenamedMethodSignature(method) == method;
+ } else {
+ assert reference.isDexType();
+ DexType type = reference.asDexType();
+ assert lookupType(type) == type;
+ }
}
return true;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/CollectingGraphConsumer.java b/src/main/java/com/android/tools/r8/shaking/CollectingGraphConsumer.java
index 774a93a..27bdd95 100644
--- a/src/main/java/com/android/tools/r8/shaking/CollectingGraphConsumer.java
+++ b/src/main/java/com/android/tools/r8/shaking/CollectingGraphConsumer.java
@@ -3,9 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graphinfo.GraphConsumer;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo;
-import com.android.tools.r8.graphinfo.GraphNode;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo;
+import com.android.tools.r8.experimental.graphinfo.GraphNode;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 2ca33b0..95f077d 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -11,6 +11,15 @@
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.experimental.graphinfo.AnnotationGraphNode;
+import com.android.tools.r8.experimental.graphinfo.ClassGraphNode;
+import com.android.tools.r8.experimental.graphinfo.FieldGraphNode;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo.EdgeKind;
+import com.android.tools.r8.experimental.graphinfo.GraphNode;
+import com.android.tools.r8.experimental.graphinfo.KeepRuleGraphNode;
+import com.android.tools.r8.experimental.graphinfo.MethodGraphNode;
import com.android.tools.r8.graph.AppInfo.ResolutionResult;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
@@ -37,15 +46,6 @@
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.KeyedDexItem;
import com.android.tools.r8.graph.PresortedComparable;
-import com.android.tools.r8.graphinfo.AnnotationGraphNode;
-import com.android.tools.r8.graphinfo.ClassGraphNode;
-import com.android.tools.r8.graphinfo.FieldGraphNode;
-import com.android.tools.r8.graphinfo.GraphConsumer;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo.EdgeKind;
-import com.android.tools.r8.graphinfo.GraphNode;
-import com.android.tools.r8.graphinfo.KeepRuleGraphNode;
-import com.android.tools.r8.graphinfo.MethodGraphNode;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Invoke.Type;
@@ -2111,26 +2111,32 @@
this.callSites = previous.callSites;
this.brokenSuperInvokes = lense.rewriteMethodsConservatively(previous.brokenSuperInvokes);
this.prunedTypes = rewriteItems(previous.prunedTypes, lense::lookupType);
- assert lense.assertDefinitionNotModified(previous.noSideEffects.keySet());
+ assert lense.assertDefinitionsNotModified(previous.noSideEffects.keySet());
this.noSideEffects = previous.noSideEffects;
- assert lense.assertDefinitionNotModified(previous.assumedValues.keySet());
+ assert lense.assertDefinitionsNotModified(previous.assumedValues.keySet());
this.assumedValues = previous.assumedValues;
- assert lense.assertDefinitionNotModified(
- previous.alwaysInline.stream().map(this::definitionFor).filter(Objects::nonNull)
+ assert lense.assertDefinitionsNotModified(
+ previous.alwaysInline.stream()
+ .map(this::definitionFor)
+ .filter(Objects::nonNull)
.collect(Collectors.toList()));
this.alwaysInline = previous.alwaysInline;
this.forceInline = lense.rewriteMethodsWithRenamedSignature(previous.forceInline);
this.neverInline = lense.rewriteMethodsWithRenamedSignature(previous.neverInline);
- assert lense.assertDefinitionNotModified(
- previous.neverMerge.stream().map(this::definitionFor).filter(Objects::nonNull)
+ assert lense.assertDefinitionsNotModified(
+ previous.neverMerge.stream()
+ .map(this::definitionFor)
+ .filter(Objects::nonNull)
.collect(Collectors.toList()));
this.neverClassInline = rewriteItems(previous.neverClassInline, lense::lookupType);
this.neverMerge = previous.neverMerge;
this.identifierNameStrings =
lense.rewriteReferencesConservatively(previous.identifierNameStrings);
// Switchmap classes should never be affected by renaming.
- assert lense.assertDefinitionNotModified(
- previous.switchMaps.keySet().stream().map(this::definitionFor).filter(Objects::nonNull)
+ assert lense.assertDefinitionsNotModified(
+ previous.switchMaps.keySet().stream()
+ .map(this::definitionFor)
+ .filter(Objects::nonNull)
.collect(Collectors.toList()));
this.switchMaps = previous.switchMaps;
this.ordinalsMaps = rewriteKeys(previous.ordinalsMaps, lense::lookupType);
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepReason.java b/src/main/java/com/android/tools/r8/shaking/KeepReason.java
index 82737a6..16d78a7 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepReason.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepReason.java
@@ -3,12 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo.EdgeKind;
+import com.android.tools.r8.experimental.graphinfo.GraphNode;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItem;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo.EdgeKind;
-import com.android.tools.r8.graphinfo.GraphNode;
// TODO(herhut): Canonicalize reason objects.
public abstract class KeepReason {
@@ -50,7 +50,7 @@
}
public static KeepReason fieldReferencedIn(DexEncodedMethod method) {
- return new ReferenedFrom(method);
+ return new ReferencedFrom(method);
}
public static KeepReason referencedInAnnotation(DexItem holder) {
@@ -219,9 +219,9 @@
}
}
- private static class ReferenedFrom extends BasedOnOtherMethod {
+ private static class ReferencedFrom extends BasedOnOtherMethod {
- private ReferenedFrom(DexEncodedMethod method) {
+ private ReferencedFrom(DexEncodedMethod method) {
super(method);
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 33ee223..8d2c1b9 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -81,6 +81,10 @@
// TODO(b/37137994): -outjars should be reported as errors, not just as warnings!
"outjars");
+ private static final List<String> WARNED_OPTIONAL_SINGLE_ARG_OPTIONS = ImmutableList.of(
+ // TODO(b/121340442): we may support this later.
+ "dump");
+
private static final List<String> WARNED_FLAG_OPTIONS = ImmutableList.of(
// TODO(b/73707846): add support -addconfigurationdebugging
"addconfigurationdebugging");
@@ -416,7 +420,11 @@
if (option == null) {
option = Iterables.find(WARNED_SINGLE_ARG_OPTIONS, this::skipOptionWithSingleArg, null);
if (option == null) {
- return false;
+ option = Iterables.find(
+ WARNED_OPTIONAL_SINGLE_ARG_OPTIONS, this::skipOptionWithOptionalSingleArg, null);
+ if (option == null) {
+ return false;
+ }
}
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 0d69178..45ca1af 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -608,28 +608,67 @@
timing.begin("fixup");
GraphLense result = new TreeFixer().fixupTypeReferences(mergingGraphLense);
timing.end();
- assert result.assertDefinitionNotModified(
- appInfo
- .alwaysInline
- .stream()
+ assert result.assertDefinitionsNotModified(
+ appInfo.alwaysInline.stream()
.map(appInfo::definitionFor)
.filter(Objects::nonNull)
.collect(Collectors.toList()));
- assert result.assertDefinitionNotModified(appInfo.noSideEffects.keySet());
- // TODO(christofferqa): Enable this assert.
- // assert result.assertNotModified(appInfo.pinnedItems);
- assert verifyGraphLense(graphLense);
+ assert verifyGraphLense(result);
return result;
}
private boolean verifyGraphLense(GraphLense graphLense) {
+ assert graphLense.assertDefinitionsNotModified(appInfo.noSideEffects.keySet());
+
+ // Note that the method assertReferencesNotModified() relies on getRenamedFieldSignature() and
+ // getRenamedMethodSignature() instead of lookupField() and lookupMethod(). This is important
+ // for this check to succeed, since it is not guaranteed that calling lookupMethod() with a
+ // pinned method will return the method itself.
+ //
+ // Consider the following example.
+ //
+ // class A {
+ // public void method() {}
+ // }
+ // class B extends A {
+ // @Override
+ // public void method() {}
+ // }
+ // class C extends B {
+ // @Override
+ // public void method() {}
+ // }
+ //
+ // If A.method() is pinned, then A cannot be merged into B, but B can still be merged into C.
+ // Now, if there is an invoke-super instruction in C that hits B.method(), then this needs to
+ // be rewritten into an invoke-direct instruction. In particular, there could be an instruction
+ // `invoke-super A.method` in C. This would hit B.method(). Therefore, the graph lens records
+ // that `invoke-super A.method` instructions, which are in one of the methods from C, needs to
+ // be rewritten to `invoke-direct C.method$B`. This is valid even though A.method() is actually
+ // pinned, because this rewriting does not affect A.method() in any way.
+ assert graphLense.assertReferencesNotModified(appInfo.pinnedItems);
+
for (DexProgramClass clazz : appInfo.classes()) {
for (DexEncodedMethod encodedMethod : clazz.methods()) {
DexMethod method = encodedMethod.method;
DexMethod originalMethod = graphLense.getOriginalMethodSignature(method);
+ DexMethod renamedMethod = graphLense.getRenamedMethodSignature(originalMethod);
- // Must be able to map back.
- assert method == graphLense.getRenamedMethodSignature(originalMethod);
+ // Must be able to map back and forth.
+ if (encodedMethod.hasCode() && encodedMethod.getCode() instanceof SynthesizedBridgeCode) {
+ // For virtual methods, the vertical class merger creates two methods in the sub class
+ // in order to deal with invoke-super instructions (one that is private and one that is
+ // virtual). Therefore, it is not possible to go back and forth. Instead, we check that
+ // the two methods map back to the same original method, and that the original method
+ // can be mapped to the implementation method.
+ DexMethod implementationMethod =
+ ((SynthesizedBridgeCode) encodedMethod.getCode()).invocationTarget;
+ DexMethod originalImplementationMethod = graphLense.getOriginalMethodSignature(method);
+ assert originalMethod == originalImplementationMethod;
+ assert implementationMethod == renamedMethod;
+ } else {
+ assert method == renamedMethod;
+ }
// Verify that all types are up-to-date. After vertical class merging, there should be no
// more references to types that have been merged into another type.
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
index 6b66465..20a05ab 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
@@ -222,16 +222,32 @@
Map<DexType, DexType> mergedClasses,
DexItemFactory dexItemFactory,
Map<DexProto, DexProto> cache) {
+ assert !signature.holder.isArrayType();
DexType newHolder = mergedClasses.getOrDefault(signature.holder, signature.holder);
DexProto newProto =
dexItemFactory.applyClassMappingToProto(
- signature.proto, type -> mergedClasses.getOrDefault(type, type), cache);
+ signature.proto,
+ type -> getTypeAfterClassMerging(type, mergedClasses, dexItemFactory),
+ cache);
if (signature.holder.equals(newHolder) && signature.proto.equals(newProto)) {
return signature;
}
return dexItemFactory.createMethod(newHolder, newProto, signature.name);
}
+ private static DexType getTypeAfterClassMerging(
+ DexType type, Map<DexType, DexType> mergedClasses, DexItemFactory dexItemFactory) {
+ if (type.isArrayType()) {
+ DexType baseType = type.toBaseType(dexItemFactory);
+ DexType newBaseType = mergedClasses.getOrDefault(baseType, baseType);
+ if (newBaseType != baseType) {
+ return type.replaceBaseType(newBaseType, dexItemFactory);
+ }
+ return type;
+ }
+ return mergedClasses.getOrDefault(type, type);
+ }
+
public boolean hasMappingForSignatureInContext(DexType context, DexMethod signature) {
Map<DexMethod, GraphLenseLookupResult> virtualToDirectMethodMap =
contextualVirtualToDirectMethodMaps.get(context);
diff --git a/src/main/java/com/android/tools/r8/shaking/WhyAreYouKeepingConsumer.java b/src/main/java/com/android/tools/r8/shaking/WhyAreYouKeepingConsumer.java
index 11f2131..0572e88 100644
--- a/src/main/java/com/android/tools/r8/shaking/WhyAreYouKeepingConsumer.java
+++ b/src/main/java/com/android/tools/r8/shaking/WhyAreYouKeepingConsumer.java
@@ -4,14 +4,14 @@
package com.android.tools.r8.shaking;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graphinfo.ClassGraphNode;
-import com.android.tools.r8.graphinfo.FieldGraphNode;
-import com.android.tools.r8.graphinfo.GraphConsumer;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo.EdgeKind;
-import com.android.tools.r8.graphinfo.GraphNode;
-import com.android.tools.r8.graphinfo.KeepRuleGraphNode;
-import com.android.tools.r8.graphinfo.MethodGraphNode;
+import com.android.tools.r8.experimental.graphinfo.ClassGraphNode;
+import com.android.tools.r8.experimental.graphinfo.FieldGraphNode;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo.EdgeKind;
+import com.android.tools.r8.experimental.graphinfo.GraphNode;
+import com.android.tools.r8.experimental.graphinfo.KeepRuleGraphNode;
+import com.android.tools.r8.experimental.graphinfo.MethodGraphNode;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.position.TextPosition;
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 388cac3..90b9e18 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -14,11 +14,11 @@
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InvalidDebugInfoException;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graphinfo.GraphConsumer;
import com.android.tools.r8.ir.optimize.Inliner;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.ProguardConfiguration;
diff --git a/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java b/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java
index 6d0ef5a..c5e44a3 100644
--- a/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java
+++ b/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java
@@ -49,13 +49,16 @@
Path mainDexList = temp.getRoot().toPath().resolve("maindexlist.txt");
FileUtils.writeTextFile(mainDexList, "desugaringwithmissingclasstest1/Main.class");
+ // It is important to place the api usage sample jar after the current classpath because we want
+ // to find D8/R8 classes before the ones in the jar, otherwise renamed classes and fields cannot
+ // be found.
+ String classPath = System.getProperty("java.class.path") + File.pathSeparator + jar.toString();
List<String> command =
ImmutableList.<String>builder()
.addAll(
ImmutableList.of(
ToolHelper.getJavaExecutable(),
- "-cp",
- jar.toString() + File.pathSeparator + System.getProperty("java.class.path"),
+ "-cp", classPath,
main,
// Compiler arguments.
"--output",
diff --git a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
index d8d983f..35dafae 100644
--- a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
+++ b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
@@ -283,7 +283,7 @@
.put(
"lang.ClassLoader.getSystemResourceAsStreamLjava_lang_String.ClassLoader_getSystemResourceAsStream_A01",
anyDexVm())
- .put("lang.ClassLoader.getPackages.ClassLoader_getPackages_A01", any())
+ .put("lang.ClassLoader.getPackages.ClassLoader_getPackages_A01", anyDexVm())
.put(
"lang.ClassLoader.setClassAssertionStatusLjava_lang_StringZ.ClassLoader_setClassAssertionStatus_A01",
any())
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 8c4f682..8afe46b 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.R8Command.Builder;
import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.TestBase.R8Mode;
-import com.android.tools.r8.graphinfo.GraphConsumer;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java
index c7a8ef2..b8c4b47 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java
@@ -22,7 +22,6 @@
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
-import org.junit.Ignore;
import org.junit.Test;
public class KotlinLambdaMergingTest extends AbstractR8KotlinTestBase {
@@ -455,7 +454,6 @@
});
}
- @Ignore("b/121107286: assertion failure in VerticalClassMerger#verifyGraphLense")
@Test
public void testSingleton() throws Exception {
final String mainClassName = "lambdas_singleton.MainKt";
diff --git a/src/test/java/com/android/tools/r8/maindexlist/whyareyoukeeping/MainDexListWhyAreYouKeeping.java b/src/test/java/com/android/tools/r8/maindexlist/whyareyoukeeping/MainDexListWhyAreYouKeeping.java
index 3eed543..0acd733 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/whyareyoukeeping/MainDexListWhyAreYouKeeping.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/whyareyoukeeping/MainDexListWhyAreYouKeeping.java
@@ -12,7 +12,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graphinfo.GraphConsumer;
+import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.shaking.WhyAreYouKeepingConsumer;
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index de10b45..ff84486 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -1851,6 +1851,30 @@
}
@Test
+ public void parse_dump_withoutFile() throws Exception {
+ Path proguardConfig = writeTextToTempFile(
+ "-dump"
+ );
+ ProguardConfigurationParser parser =
+ new ProguardConfigurationParser(new DexItemFactory(), reporter);
+ parser.parse(proguardConfig);
+ checkDiagnostics(handler.warnings, proguardConfig, 1, 1,
+ "Ignoring", "-dump");
+ }
+
+ @Test
+ public void parse_dump_withFile() throws Exception {
+ Path proguardConfig = writeTextToTempFile(
+ "-dump class_files.txt"
+ );
+ ProguardConfigurationParser parser =
+ new ProguardConfigurationParser(new DexItemFactory(), reporter);
+ parser.parse(proguardConfig);
+ checkDiagnostics(handler.warnings, proguardConfig, 1, 1,
+ "Ignoring", "-dump");
+ }
+
+ @Test
public void parse_android() throws Exception {
Path proguardConfig = writeTextToTempFile(
"-android"
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/applymapping/IfRuleWithApplyMappingTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/applymapping/IfRuleWithApplyMappingTest.java
index 871f76d..49679c4 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/applymapping/IfRuleWithApplyMappingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/applymapping/IfRuleWithApplyMappingTest.java
@@ -9,28 +9,22 @@
import static org.junit.Assert.assertThat;
import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.nio.file.Path;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
+import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
public class IfRuleWithApplyMappingTest extends TestBase {
- @ClassRule
- public static TemporaryFolder tempFolder = ToolHelper.getTemporaryFolderForTest();
-
private static Path mappingFile;
- @BeforeClass
- public static void setup() throws Exception {
+ @Before
+ public void setup() throws Exception {
// Mapping file that describes that Runnable has been renamed to A.
- mappingFile = tempFolder.newFolder().toPath().resolve("mapping.txt");
+ mappingFile = temp.newFolder().toPath().resolve("mapping.txt");
FileUtils.writeTextFile(
mappingFile, Runnable.class.getTypeName() + " -> " + A.class.getTypeName() + ":");
}
@@ -45,7 +39,7 @@
"-keep class " + IfRuleWithApplyMappingTestClass.class.getTypeName() + " {",
" public void method(" + Runnable.class.getTypeName() + ");",
"}",
- "-applymapping " + mappingFile)
+ "-applymapping " + mappingFile.toAbsolutePath())
.compile()
.inspect(this::inspect);
}
@@ -61,7 +55,7 @@
"-keep class " + IfRuleWithApplyMappingTestClass.class.getTypeName() + " {",
" public void method(" + Runnable.class.getTypeName() + ");",
"}",
- "-applymapping " + mappingFile)
+ "-applymapping " + mappingFile.toAbsolutePath())
.compile()
.inspect(this::inspect);
}
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptMethodTest.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptMethodTest.java
index 689d3b6..35083c7 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptMethodTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptMethodTest.java
@@ -19,6 +19,9 @@
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
class Main {
@@ -37,9 +40,19 @@
}
}
+@RunWith(Parameterized.class)
public class KeptMethodTest extends TestBase {
- final Backend backend = Backend.DEX;
+ private final Backend backend;
+
+ @Parameters(name = "{0}")
+ public static Backend[] data() {
+ return Backend.values();
+ }
+
+ public KeptMethodTest(Backend backend) {
+ this.backend = backend;
+ }
@Test
public void testKeptMethod()
diff --git a/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java b/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java
index 454d1f5..b138e50 100644
--- a/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java
@@ -4,11 +4,11 @@
package com.android.tools.r8.utils.graphinspector;
import com.android.tools.r8.errors.Unimplemented;
-import com.android.tools.r8.graphinfo.ClassGraphNode;
-import com.android.tools.r8.graphinfo.FieldGraphNode;
-import com.android.tools.r8.graphinfo.GraphEdgeInfo;
-import com.android.tools.r8.graphinfo.GraphNode;
-import com.android.tools.r8.graphinfo.MethodGraphNode;
+import com.android.tools.r8.experimental.graphinfo.ClassGraphNode;
+import com.android.tools.r8.experimental.graphinfo.FieldGraphNode;
+import com.android.tools.r8.experimental.graphinfo.GraphEdgeInfo;
+import com.android.tools.r8.experimental.graphinfo.GraphNode;
+import com.android.tools.r8.experimental.graphinfo.MethodGraphNode;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;