aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Zerny <zerny@google.com>2021-03-18 09:13:05 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-03-18 09:13:05 +0000
commit9b0e8ba143aa6d1cc2ff04ade59156a2a2b2f0b3 (patch)
treea514fba63a38dad79ec63f81f58c6edba4fcfe54
parent22e2b2c473aff864309be995b715608dd83c0034 (diff)
parentc4e4ae59b83f3d913c34c55e90000a4756cfe65f (diff)
downloadr8-9b0e8ba143aa6d1cc2ff04ade59156a2a2b2f0b3.tar.gz
Add mapping information for compiler synthesized classes. am: c4e4ae59b8
Original change: undetermined Change-Id: I4afea1da07795abcf753dfe63b39d5f629174ebd
-rw-r--r--src/main/java/com/android/tools/r8/naming/MemberNaming.java2
-rw-r--r--src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java45
-rw-r--r--src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java11
-rw-r--r--src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java9
-rw-r--r--src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java66
-rw-r--r--src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java24
-rw-r--r--src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java22
-rw-r--r--src/test/java/com/android/tools/r8/utils/codeinspector/Subject.java7
8 files changed, 169 insertions, 17 deletions
diff --git a/src/main/java/com/android/tools/r8/naming/MemberNaming.java b/src/main/java/com/android/tools/r8/naming/MemberNaming.java
index 51c3272ef..4a50244a2 100644
--- a/src/main/java/com/android/tools/r8/naming/MemberNaming.java
+++ b/src/main/java/com/android/tools/r8/naming/MemberNaming.java
@@ -172,7 +172,7 @@ public class MemberNaming {
public static final NoSignature NO_SIGNATURE = new NoSignature();
- public NoSignature() {
+ private NoSignature() {
super("NO SIGNATURE");
}
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java
new file mode 100644
index 000000000..b0a13baee
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java
@@ -0,0 +1,45 @@
+// 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.naming.mappinginformation;
+
+import com.android.tools.r8.DiagnosticsHandler;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+public class CompilerSynthesizedMappingInformation extends MappingInformation {
+
+ public static final String ID = "com.android.tools.r8.synthesized";
+
+ public CompilerSynthesizedMappingInformation() {
+ super(NO_LINE_NUMBER);
+ }
+
+ @Override
+ public boolean isCompilerSynthesizedMappingInformation() {
+ return true;
+ }
+
+ @Override
+ public CompilerSynthesizedMappingInformation asCompilerSynthesizedMappingInformation() {
+ return this;
+ }
+
+ @Override
+ public boolean allowOther(MappingInformation information) {
+ return !information.isCompilerSynthesizedMappingInformation();
+ }
+
+ @Override
+ public String serialize() {
+ JsonObject result = new JsonObject();
+ result.add(MAPPING_ID_KEY, new JsonPrimitive(ID));
+ return result.toString();
+ }
+
+ public static CompilerSynthesizedMappingInformation deserialize(
+ JsonObject object, DiagnosticsHandler diagnosticsHandler, int lineNumber) {
+ return new CompilerSynthesizedMappingInformation();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java
index c1c5105db..cb0708fdc 100644
--- a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java
@@ -50,6 +50,14 @@ public abstract class MappingInformation {
return null;
}
+ public boolean isCompilerSynthesizedMappingInformation() {
+ return false;
+ }
+
+ public CompilerSynthesizedMappingInformation asCompilerSynthesizedMappingInformation() {
+ return null;
+ }
+
public abstract boolean allowOther(MappingInformation information);
public static MappingInformation fromJsonObject(
@@ -75,6 +83,9 @@ public abstract class MappingInformation {
return MethodSignatureChangedInformation.build(object, diagnosticsHandler, lineNumber);
case FileNameInformation.ID:
return FileNameInformation.build(object, diagnosticsHandler, lineNumber);
+ case CompilerSynthesizedMappingInformation.ID:
+ return CompilerSynthesizedMappingInformation.deserialize(
+ object, diagnosticsHandler, lineNumber);
default:
diagnosticsHandler.info(MappingInformationDiagnostics.noHandlerFor(lineNumber, idString));
return null;
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index 47ccd9159..f8ad5bbba 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -47,6 +47,7 @@ import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.Range;
+import com.android.tools.r8.naming.mappinginformation.CompilerSynthesizedMappingInformation;
import com.android.tools.r8.naming.mappinginformation.FileNameInformation;
import com.android.tools.r8.retrace.internal.RetraceUtils;
import com.android.tools.r8.shaking.KeepInfoCollection;
@@ -274,6 +275,8 @@ public class LineNumberOptimizer {
ClassNameMapper.Builder classNameMapperBuilder = ClassNameMapper.builder();
// Collect which files contain which classes that need to have their line numbers optimized.
for (DexProgramClass clazz : application.classes()) {
+ boolean isSyntheticClass = appView.getSyntheticItems().isSyntheticClass(clazz);
+
IdentityHashMap<DexString, List<DexEncodedMethod>> methodsByRenamedName =
groupMethodsByRenamedName(appView.graphLens(), namingLens, clazz);
@@ -299,6 +302,12 @@ public class LineNumberOptimizer {
}
}
+ if (isSyntheticClass) {
+ onDemandClassNamingBuilder
+ .get()
+ .addMappingInformation(new CompilerSynthesizedMappingInformation());
+ }
+
// If the class is renamed add it to the classNamingBuilder.
addClassToClassNaming(originalType, renamedClassName, onDemandClassNamingBuilder);
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java b/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java
index aa543c88f..41d1c3f02 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java
@@ -5,15 +5,23 @@
package com.android.tools.r8.retrace;
import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileNameAndLineNumber;
+import static com.android.tools.r8.references.Reference.classFromClass;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isCompilerSynthesized;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.naming.retrace.StackTrace;
+import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
+import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -48,22 +56,48 @@ public class RetraceLambdaTest extends TestBase {
.run(parameters.getRuntime(), Main.class)
.assertFailureWithErrorThatMatches(containsString("Hello World!"))
.inspectStackTrace(
- stackTrace -> {
- assertThat(
- stackTrace,
- isSameExceptForFileNameAndLineNumber(
- StackTrace.builder()
- .addWithoutFileNameAndLineNumber(Main.class, JAVAC_LAMBDA_METHOD)
- // TODO(b/172014416): Support a D8 mapping and prune the synthetic.
- .applyIf(
- parameters.isDexRuntime(),
- b ->
- b.addWithoutFileNameAndLineNumber(
- SyntheticItemsTestUtils.syntheticLambdaClass(Main.class, 0),
- "run"))
- .addWithoutFileNameAndLineNumber(Main.class, "runIt")
- .addWithoutFileNameAndLineNumber(Main.class, "main")
- .build()));
+ stackTrace ->
+ assertThat(
+ stackTrace,
+ isSameExceptForFileNameAndLineNumber(
+ StackTrace.builder()
+ .addWithoutFileNameAndLineNumber(Main.class, JAVAC_LAMBDA_METHOD)
+ // TODO(b/172014416): Support a D8 mapping and prune the synthetic.
+ .applyIf(
+ parameters.isDexRuntime(),
+ b ->
+ b.addWithoutFileNameAndLineNumber(
+ SyntheticItemsTestUtils.syntheticLambdaClass(Main.class, 0),
+ "run"))
+ .addWithoutFileNameAndLineNumber(Main.class, "runIt")
+ .addWithoutFileNameAndLineNumber(Main.class, "main")
+ .build())));
+ }
+
+ @Test
+ public void testMappingInformation() throws Exception {
+ assumeTrue("R8/CF does not desugar", parameters.isDexRuntime());
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addKeepAttributeSourceFile()
+ .addKeepAttributeLineNumberTable()
+ .noTreeShaking()
+ .noMinification()
+ .setMinApi(parameters.getApiLevel())
+ .run(parameters.getRuntime(), Main.class)
+ .assertFailureWithErrorThatMatches(containsString("Hello World!"))
+ .inspectFailure(
+ inspector -> {
+ Collection<ClassReference> inputs =
+ ImmutableList.of(classFromClass(MyRunner.class), classFromClass(Main.class));
+ for (FoundClassSubject clazz : inspector.allClasses()) {
+ if (inputs.contains(clazz.getFinalReference())) {
+ assertThat(clazz, not(isCompilerSynthesized()));
+ } else {
+ assertThat(clazz, isCompilerSynthesized());
+ }
+ }
+ assertEquals(inputs.size() + 1, inspector.allClasses().size());
});
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index be358de26..176310868 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -26,7 +26,9 @@ import com.android.tools.r8.naming.ClassNamingForNameMapper;
import com.android.tools.r8.naming.MemberNaming;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.naming.MemberNaming.NoSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
+import com.android.tools.r8.naming.mappinginformation.MappingInformation;
import com.android.tools.r8.naming.signature.GenericSignatureParser;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
@@ -44,6 +46,7 @@ import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -412,6 +415,27 @@ public class FoundClassSubject extends ClassSubject {
}
@Override
+ public boolean isCompilerSynthesized() {
+ if (naming == null) {
+ return false;
+ }
+ Map<Signature, List<MappingInformation>> additionalMappings = naming.getAdditionalMappings();
+ if (additionalMappings == null) {
+ return false;
+ }
+ List<MappingInformation> infos = additionalMappings.get(NoSignature.NO_SIGNATURE);
+ if (infos == null) {
+ return false;
+ }
+ for (MappingInformation info : infos) {
+ if (info.isCompilerSynthesizedMappingInformation()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
public boolean isLocalClass() {
return dexClass.isLocalClass();
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java b/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
index 28f0b9c0e..e7db18c9b 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
@@ -218,6 +218,28 @@ public class Matchers {
};
}
+ public static Matcher<Subject> isCompilerSynthesized() {
+ return new TypeSafeMatcher<Subject>() {
+ @Override
+ protected boolean matchesSafely(Subject subject) {
+ return subject.isPresent() && subject.isCompilerSynthesized();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(" compiler synthesized");
+ }
+
+ @Override
+ public void describeMismatchSafely(final Subject subject, Description description) {
+ description
+ .appendText(type(subject) + " ")
+ .appendValue(name(subject))
+ .appendText(" was not");
+ }
+ };
+ }
+
public static Matcher<ClassSubject> hasDefaultConstructor() {
return new TypeSafeMatcher<ClassSubject>() {
@Override
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/Subject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/Subject.java
index 05d83b78e..29bc90bdf 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/Subject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/Subject.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.utils.codeinspector;
+import com.android.tools.r8.errors.Unimplemented;
+
public abstract class Subject {
public abstract boolean isPresent();
@@ -11,4 +13,9 @@ public abstract class Subject {
public abstract boolean isRenamed();
public abstract boolean isSynthetic();
+
+ public boolean isCompilerSynthesized() {
+ throw new Unimplemented(
+ "Predicate not yet supported on Subject: " + getClass().getSimpleName());
+ }
}