Merge commit '2bc4198a912b1e155340f4054984ca26fd27bb31' into dev-release
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
index 8af5714..c1107e6 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
@@ -319,6 +319,10 @@
"third_party",
"binary_compatibility_tests",
"compiler_api_tests.tar.gz.sha1").toFile())
+ val dagger = ThirdPartyDependency(
+ "dagger",
+ Paths.get("third_party", "dagger", "2.41", "dagger-2.41.jar").toFile(),
+ Paths.get("third_party", "dagger", "2.41.tar.gz.sha1").toFile())
val ddmLib = ThirdPartyDependency(
"ddmlib",
Paths.get("third_party", "ddmlib", "ddmlib.jar").toFile(),
@@ -338,6 +342,11 @@
Paths.get("third_party", "openjdk", "openjdk-rt-1.8.tar.gz.sha1").toFile()
)
val jdks = getJdks()
+ val jdk11Test = ThirdPartyDependency(
+ "jdk-11-test",
+ Paths.get("third_party", "openjdk", "jdk-11-test", "Makefile").toFile(),
+ Paths.get("third_party", "openjdk", "jdk-11-test.tar.gz.sha1").toFile()
+ )
val jdwpTests = ThirdPartyDependency(
"jdwp-tests",
Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar").toFile(),
diff --git a/d8_r8/library_desugar/build.gradle.kts b/d8_r8/library_desugar/build.gradle.kts
new file mode 100644
index 0000000..7483d80
--- /dev/null
+++ b/d8_r8/library_desugar/build.gradle.kts
@@ -0,0 +1,34 @@
+// Copyright (c) 2023, 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.
+
+// import java.nio.file.Paths
+// import net.ltgt.gradle.errorprone.errorprone
+
+plugins {
+ `kotlin-dsl`
+ id("dependencies-plugin")
+}
+
+java {
+ sourceSets.main.configure {
+ java.srcDir(getRoot().resolveAll("src", "library_desugar", "java"))
+ output.resourcesDir = getRoot().resolveAll("build", "classes", "library_desugar_conversions")
+ }
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+}
+
+dependencies {
+}
+
+tasks {
+ withType<JavaCompile> {
+ options.setFork(true)
+ options.forkOptions.memoryMaximumSize = "3g"
+ options.forkOptions.jvmArgs = listOf(
+ "-Xss256m",
+ // Set the bootclass path so compilation is consistent with 1.8 target compatibility.
+ "-Xbootclasspath/a:third_party/openjdk/openjdk-rt-1.8/rt.jar")
+ }
+}
\ No newline at end of file
diff --git a/d8_r8/library_desugar/gradle.properties b/d8_r8/library_desugar/gradle.properties
new file mode 100644
index 0000000..1de43f9
--- /dev/null
+++ b/d8_r8/library_desugar/gradle.properties
@@ -0,0 +1,17 @@
+# Copyright (c) 2023, 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.
+
+org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx3g -Dkotlin.js.compiler.legacy.force_enabled=true
+systemProp.file.encoding=UTF-8
+
+# Enable new incremental compilation
+kotlin.incremental.useClasspathSnapshot=true
+
+org.gradle.parallel=true
+org.gradle.caching=true
+
+# Do not download any jdks or detect them. We provide them.
+org.gradle.java.installations.auto-detect=false
+org.gradle.java.installations.auto-download=false
diff --git a/d8_r8/library_desugar/settings.gradle.kts b/d8_r8/library_desugar/settings.gradle.kts
new file mode 100644
index 0000000..e60eee4
--- /dev/null
+++ b/d8_r8/library_desugar/settings.gradle.kts
@@ -0,0 +1,5 @@
+// Copyright (c) 2023, 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.
+
+rootProject.name = "library_desugar"
diff --git a/d8_r8/settings.gradle.kts b/d8_r8/settings.gradle.kts
index 9907334..77ad2e0 100644
--- a/d8_r8/settings.gradle.kts
+++ b/d8_r8/settings.gradle.kts
@@ -54,6 +54,7 @@
// We need to include src/main as a composite-build otherwise our test-modules
// will compete with the test to compile the source files.
includeBuild(root.resolve("main"))
+includeBuild(root.resolve("library_desugar"))
includeBuild(root.resolve("test"))
// Include r8lib as standalone to have a nice separation between source artifacts and r8 compiled
diff --git a/d8_r8/test_modules/tests_java_8/build.gradle.kts b/d8_r8/test_modules/tests_java_8/build.gradle.kts
index f7e52e5..669b394 100644
--- a/d8_r8/test_modules/tests_java_8/build.gradle.kts
+++ b/d8_r8/test_modules/tests_java_8/build.gradle.kts
@@ -55,7 +55,12 @@
val thirdPartyRuntimeDependenciesTask = ensureThirdPartyDependencies(
"runtimeDeps",
- listOf(ThirdPartyDeps.compilerApi, ThirdPartyDeps.jacoco, ThirdPartyDeps.java8Runtime)
+ listOf(
+ ThirdPartyDeps.compilerApi,
+ ThirdPartyDeps.dagger,
+ ThirdPartyDeps.jacoco,
+ ThirdPartyDeps.java8Runtime,
+ ThirdPartyDeps.jdk11Test)
+ ThirdPartyDeps.androidJars
+ ThirdPartyDeps.androidVMs
+ ThirdPartyDeps.jdks
diff --git a/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java b/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
index 62531ba..625b127 100644
--- a/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
+++ b/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ir.analysis.type.ArrayTypeElement;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
+import com.android.tools.r8.utils.AndroidApiLevelUtils;
import com.google.common.collect.Iterables;
public class DexTypeUtils {
@@ -15,7 +16,7 @@
AppView<? extends AppInfoWithClassHierarchy> appView, Iterable<DexType> types) {
TypeElement join =
TypeElement.join(Iterables.transform(types, type -> type.toTypeElement(appView)), appView);
- return toDexType(appView, join);
+ return findApiSafeUpperBound(appView, toDexType(appView, join));
}
public static DexType toDexType(
@@ -39,4 +40,23 @@
}
return dexItemFactory.objectType;
}
+
+ public static DexType findApiSafeUpperBound(
+ AppView<? extends AppInfoWithClassHierarchy> appView, DexType type) {
+ DexItemFactory factory = appView.dexItemFactory();
+ if (type.toBaseType(factory).isPrimitiveType()) {
+ return type;
+ }
+ DexClass clazz = appView.definitionFor(type.isArrayType() ? type.toBaseType(factory) : type);
+ if (clazz == null) {
+ assert false : "We should not have found an upper bound if the hierarchy is missing";
+ return type;
+ }
+ if (!clazz.isLibraryClass()
+ || AndroidApiLevelUtils.isApiSafeForReference(clazz.asLibraryClass(), appView)) {
+ return type;
+ }
+ // Always just return the object type since this is safe for all api versions.
+ return factory.objectType;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java
index e5ad61c..f1092d4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java
@@ -99,6 +99,7 @@
abstract AndroidApiLevel run() throws Exception;
+ // TODO(b/289365156): Move this out.
private static String getFallBackAndroidJarPath(AndroidApiLevel apiLevel) {
String jar =
apiLevel == AndroidApiLevel.MASTER
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java b/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java
index 2323d03..809fd77 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java
@@ -517,11 +517,19 @@
void write(ChainableStringConsumer consumer) {
consumer.accept(originalName).accept(" -> ").accept(renamedName).accept(":\n");
+ String spacing = " ";
+
// Print all additional mapping information.
additionalMappingInfo.forEach(info -> consumer.accept("# " + info.serialize()).accept("\n"));
// Print field member namings.
- forAllFieldNamingSorted(m -> consumer.accept(" ").accept(m.toString()).accept("\n"));
+ forAllFieldNamingSorted(
+ fieldMember -> {
+ consumer.accept(spacing).accept(fieldMember.toString()).accept("\n");
+ for (MappingInformation info : fieldMember.getAdditionalMappingInformation()) {
+ consumer.accept(spacing + " # ").accept(info.serialize()).accept("\n");
+ }
+ });
// Sort MappedRanges by sequence number to restore construction order (original Proguard-map
// input).
@@ -531,9 +539,9 @@
}
mappedRangesSorted.sort(Comparator.comparingInt(range -> range.sequenceNumber));
for (MappedRange range : mappedRangesSorted) {
- consumer.accept(" ").accept(range.toString()).accept("\n");
+ consumer.accept(spacing).accept(range.toString()).accept("\n");
for (MappingInformation info : range.getAdditionalMappingInformation()) {
- consumer.accept(" # ").accept(info.serialize()).accept("\n");
+ consumer.accept(spacing + " # ").accept(info.serialize()).accept("\n");
}
}
}
diff --git a/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java b/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
index e4fc96d..8be5e9a 100644
--- a/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
+++ b/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
@@ -865,38 +865,40 @@
assert verifyAllOutlineCallSitesAreEqualTo(outlineCallSite, computedMappedRangeForOutlines);
ComputedMappedRangeForOutline computedMappedRangeForOutline =
ListUtils.first(computedMappedRangeForOutlines);
- Int2IntSortedMap newPositionMap =
- new Int2IntLinkedOpenHashMap(outlineCallSite.getPositions().size());
- visitOutlineMappedPositions(
- outlineCallSite,
- computedMappedRangeForOutline.current.getOriginalSignature(),
- positionInfo -> {
- int newIndex = firstAvailableRange.getAndIncrement();
- Range newMinifiedRange = new Range(newIndex, newIndex);
- MappedRange outerMostOutlineCallsiteFrame =
- ListUtils.last(positionInfo.mappedRanges());
- for (MappedRange inlineMappedRangeInOutlinePosition : positionInfo.mappedRanges()) {
- if (inlineMappedRangeInOutlinePosition != outerMostOutlineCallsiteFrame) {
- composedRanges.add(
- inlineMappedRangeInOutlinePosition.withMinifiedRange(newMinifiedRange));
- }
- }
+ Int2IntSortedMap newPositionMap =
+ new Int2IntLinkedOpenHashMap(outlineCallSite.getPositions().size());
+ visitOutlineMappedPositions(
+ outlineCallSite,
+ computedMappedRangeForOutline.current.getOriginalSignature(),
+ positionInfo -> {
+ int newIndex = firstAvailableRange.getAndIncrement();
+ Range newMinifiedRange = new Range(newIndex, newIndex);
+ boolean isCaller = false;
+ for (MappedRange existingMappedRange : positionInfo.mappedRanges()) {
int originalPosition =
- outerMostOutlineCallsiteFrame.getOriginalLineNumber(
+ existingMappedRange.getOriginalLineNumber(
positionInfo.outlineCallsitePosition());
- boolean hasInlineFrames = positionInfo.mappedRanges().size() > 1;
- composedRanges.add(
+ Range newOriginalRange =
+ isCaller
+ ? new Range(originalPosition)
+ : new Range(originalPosition, originalPosition);
+ MappedRange newMappedRange =
new MappedRange(
newMinifiedRange,
- lastComposedRange.signature,
- hasInlineFrames
- ? new Range(originalPosition)
- : new Range(originalPosition, originalPosition),
- lastComposedRange.getRenamedName()));
- newPositionMap.put(positionInfo.outlinePosition(), newIndex);
- outlineCallSite.setPositionsInternal(newPositionMap);
- });
- }
+ existingMappedRange.getOriginalSignature(),
+ newOriginalRange,
+ lastComposedRange.getRenamedName());
+ if (!existingMappedRange.getAdditionalMappingInformation().isEmpty()) {
+ newMappedRange.setAdditionalMappingInformationInternal(
+ existingMappedRange.getAdditionalMappingInformation());
+ }
+ composedRanges.add(newMappedRange);
+ isCaller = true;
+ }
+ newPositionMap.put(positionInfo.outlinePosition(), newIndex);
+ });
+ outlineCallSite.setPositionsInternal(newPositionMap);
+ }
}
private boolean verifyAllOutlineCallSitesAreEqualTo(
diff --git a/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java b/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java
index 702ed59..97d77be 100644
--- a/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java
+++ b/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java
@@ -4,6 +4,9 @@
package com.android.tools.r8.retrace;
+import com.android.tools.r8.Keep;
+
+@Keep
public class IllegalClassNameLookupException extends RuntimeException {
private final String typeName;
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java b/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java
index 9ffa613..ba04547 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java
@@ -5,7 +5,9 @@
package com.android.tools.r8.retrace;
import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.Keep;
+@Keep
public interface MappingSupplierAsync<T extends MappingSupplierAsync<T>>
extends MappingSupplierBase<T> {
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
index 98ed799..eaa21d3 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
@@ -85,7 +85,7 @@
memberNamings,
memberNaming -> memberNaming.getResidualSignature().equals(fieldSignature));
}
- return memberNamings;
+ return memberNamings.isEmpty() ? null : memberNamings;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
index ac45d92..c7f09b8 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
@@ -95,7 +95,9 @@
@Override
public boolean isEmpty() {
- return memberNamings == null || memberNamings.isEmpty();
+ return memberNamings == null
+ || memberNamings.isEmpty()
+ || (memberNamings.size() == 1 && memberNamings.get(0).getSecond() == null);
}
public static class ElementImpl implements RetraceFieldElement {
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 41c295f..03a8229 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1718,8 +1718,9 @@
// Allow 4 instructions when using LIR regardless of backend.
if (options.testing.useLir) {
// TODO(b/288226522): We should reevaluate this for size and other inputs as it regresses
- // compared to DEX code with limit 5. This is set to 4 to avoid discard errors in chrome.
- return 4;
+ // compared to DEX code with limit 5 for tivi. This is set to 5 to avoid discard errors
+ // in chrome. Using 5 also improves size for chrome compared to a lower value.
+ return 5;
}
// Allow 3 instructions when generating to class files.
if (options.isGeneratingClassFiles()) {
diff --git a/src/main/java/com/android/tools/r8/utils/RetracerForCodePrinting.java b/src/main/java/com/android/tools/r8/utils/RetracerForCodePrinting.java
index fe301df..1b772b7 100644
--- a/src/main/java/com/android/tools/r8/utils/RetracerForCodePrinting.java
+++ b/src/main/java/com/android/tools/r8/utils/RetracerForCodePrinting.java
@@ -11,8 +11,10 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.IndexedDexItem;
import com.android.tools.r8.naming.ClassNameMapper;
+import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.retrace.RetraceClassElement;
import com.android.tools.r8.retrace.RetraceElement;
+import com.android.tools.r8.retrace.RetraceFieldResult;
import com.android.tools.r8.retrace.RetraceMethodResult;
import com.android.tools.r8.retrace.RetraceResult;
import com.android.tools.r8.retrace.RetracedFieldReference;
@@ -117,8 +119,16 @@
if (retracer == null) {
return noRetraceString.apply(field);
}
+ FieldReference fieldReference = field.asFieldReference();
+ RetraceFieldResult retraceFieldResult = retracer.retraceField(fieldReference);
+ if (retraceFieldResult.isEmpty()) {
+ retraceFieldResult =
+ retracer
+ .retraceClass(fieldReference.getHolderClass())
+ .lookupField(fieldReference.getFieldName());
+ }
return joinAmbiguousResults(
- retracer.retraceField(field.asFieldReference()),
+ retraceFieldResult,
element -> {
if (element.isUnknown()) {
return unknownToString.apply(element.getField());
diff --git a/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java b/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java
index 487ac5f..c3780fb 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java
@@ -193,7 +193,9 @@
DexField originalField = appView.graphLens().getOriginalFieldSignature(dexField);
DexField residualField =
appView.getNamingLens().lookupField(dexField, appView.dexItemFactory());
- if (residualField.name != originalField.name || originalField.holder != originalType) {
+ if (residualField.name != originalField.name
+ || residualField.getType() != originalField.getType()
+ || originalField.holder != originalType) {
FieldSignature originalSignature =
FieldSignature.fromDexField(originalField, originalField.holder != originalType);
FieldSignature residualSignature = FieldSignature.fromDexField(residualField);
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index a81451f..842b6a8 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -19,21 +19,17 @@
import com.android.tools.r8.AssertionsConfiguration.AssertionTransformationScope;
import com.android.tools.r8.D8CommandParser.OrderedClassFileResourceProvider;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.profile.startup.profile.StartupProfile;
-import com.android.tools.r8.profile.startup.profile.StartupProfileRule;
import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.startup.StartupProfileProvider;
-import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.ZipUtils;
import com.google.common.collect.ImmutableList;
@@ -699,7 +695,7 @@
D8Command d8Command =
parse(
"--desugared-lib",
- "src/library_desugar/desugar_jdk_libs.json",
+ LibraryDesugaringSpecification.JDK11.getSpecification().toString(),
"--lib",
ToolHelper.getAndroidJar(AndroidApiLevel.R).toString());
InternalOptions options = getOptionsWithLoadedDesugaredLibraryConfiguration(d8Command, false);
@@ -712,7 +708,7 @@
D8Command d8Command =
parse(
"--desugared-lib",
- "src/library_desugar/desugar_jdk_libs.json",
+ LibraryDesugaringSpecification.JDK11.getSpecification().toString(),
"--lib",
ToolHelper.getAndroidJar(AndroidApiLevel.R).toString(),
"--desugared-lib-pg-conf-output",
@@ -728,7 +724,7 @@
parse(
diagnostics,
"--desugared-lib",
- "src/library_desugar/desugar_jdk_libs.json",
+ LibraryDesugaringSpecification.JDK11.getSpecification().toString(),
"--desugared-lib-pg-conf-output");
fail("Expected parse error");
} catch (CompilationFailedException e) {
diff --git a/src/test/java/com/android/tools/r8/R8CommandTest.java b/src/test/java/com/android/tools/r8/R8CommandTest.java
index a98ad79..d22f197 100644
--- a/src/test/java/com/android/tools/r8/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/R8CommandTest.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.AssertionsConfiguration.AssertionTransformationScope;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.origin.EmbeddedOrigin;
@@ -860,7 +861,7 @@
R8Command r8Command =
parse(
"--desugared-lib",
- "src/library_desugar/desugar_jdk_libs.json",
+ LibraryDesugaringSpecification.JDK11.getSpecification().toString(),
"--lib",
ToolHelper.getAndroidJar(AndroidApiLevel.R).toString());
InternalOptions options = getOptionsWithLoadedDesugaredLibraryConfiguration(r8Command, false);
@@ -873,7 +874,7 @@
R8Command r8Command =
parse(
"--desugared-lib",
- "src/library_desugar/desugar_jdk_libs.json",
+ LibraryDesugaringSpecification.JDK11.getSpecification().toString(),
"--lib",
ToolHelper.getAndroidJar(AndroidApiLevel.R).toString(),
"--desugared-lib-pg-conf-output",
@@ -889,7 +890,7 @@
parse(
diagnostics,
"--desugared-lib",
- "src/library_desugar/desugar_jdk_libs.json",
+ LibraryDesugaringSpecification.JDK11.getSpecification().toString(),
"--desugared-lib-pg-conf-output");
fail("Expected parse error");
} catch (CompilationFailedException e) {
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 8ffd594..1151357 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -111,8 +111,8 @@
return Paths.get(current).getParent().toString() + "/";
}
- public static final String SOURCE_DIR = "src/main/java/";
- public static final String RESOURCES_DIR = "src/main/resources/";
+ public static final String SOURCE_DIR = getProjectRoot() + "src/main/java/";
+ public static final String LIBRARY_DESUGAR_SOURCE_DIR = getProjectRoot() + "src/library_desugar/";
public static final String BUILD_DIR = getProjectRoot() + "build/";
public static final String TEST_MODULE_DIR = getProjectRoot() + "d8_r8/test_modules/";
public static final String GENERATED_TEST_BUILD_DIR = BUILD_DIR + "generated/test/";
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkDependency.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkDependency.java
index 26e9029..ceb6152 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkDependency.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkDependency.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.benchmarks;
+import com.android.tools.r8.ToolHelper;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
@@ -11,12 +12,12 @@
public static BenchmarkDependency getRuntimeJarJava8() {
return new BenchmarkDependency(
- "java8rtjar", "openjdk-rt-1.8", Paths.get("third_party", "openjdk"));
+ "java8rtjar", "openjdk-rt-1.8", Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk"));
}
public static BenchmarkDependency getAndroidJar30() {
return new BenchmarkDependency(
- "android30jar", "lib-v30", Paths.get("third_party", "android_jar"));
+ "android30jar", "lib-v30", Paths.get(ToolHelper.THIRD_PARTY_DIR, "android_jar"));
}
// Nice name of the dependency. Must be a valid dart identifier.
diff --git a/src/test/java/com/android/tools/r8/benchmarks/desugaredlib/LegacyDesugaredLibraryBenchmark.java b/src/test/java/com/android/tools/r8/benchmarks/desugaredlib/LegacyDesugaredLibraryBenchmark.java
index a047c5a..0e86477 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/desugaredlib/LegacyDesugaredLibraryBenchmark.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/desugaredlib/LegacyDesugaredLibraryBenchmark.java
@@ -5,6 +5,7 @@
import com.android.tools.r8.StringResource;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.benchmarks.BenchmarkBase;
import com.android.tools.r8.benchmarks.BenchmarkConfig;
import com.android.tools.r8.benchmarks.BenchmarkDependency;
@@ -26,7 +27,9 @@
private static final BenchmarkDependency androidJar = BenchmarkDependency.getAndroidJar30();
private static final BenchmarkDependency legacyConf =
new BenchmarkDependency(
- "legacyConf", "desugar_jdk_libs_legacy", Paths.get("third_party", "openjdk"));
+ "legacyConf",
+ "desugar_jdk_libs_legacy",
+ Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk"));
public LegacyDesugaredLibraryBenchmark(BenchmarkConfig config, TestParameters parameters) {
super(config, parameters);
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClInitMergeSuperTypeApiLevelTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClInitMergeSuperTypeApiLevelTest.java
new file mode 100644
index 0000000..27890cf
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClInitMergeSuperTypeApiLevelTest.java
@@ -0,0 +1,128 @@
+// Copyright (c) 2023, 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.classmerging.horizontal;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/** This is a regression test for b/289361079. */
+@RunWith(Parameterized.class)
+public class ClInitMergeSuperTypeApiLevelTest extends TestBase {
+
+ @Parameter() public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ private TypeReference getMergeReferenceForApiLevel() {
+ boolean canUseExecutable =
+ parameters.isDexRuntime()
+ && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.O);
+ return Reference.typeFromTypeName(typeName(canUseExecutable ? Executable.class : Object.class));
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ // Emulate a standard AGP setup where we compile with a new android jar on boot classpath.
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST))
+ .addInnerClasses(getClass())
+ .setMinApi(parameters)
+ .addKeepClassAndMembersRules(Main.class)
+ .addHorizontallyMergedClassesInspector(
+ inspector -> inspector.assertClassesMerged(A.class, B.class))
+ .enableInliningAnnotations()
+ .compile()
+ .inspect(
+ inspector -> {
+ ClassSubject clazz = inspector.clazz(A.class);
+ assertThat(clazz, isPresent());
+ MethodSubject init = clazz.uniqueInstanceInitializer();
+ assertThat(init, isPresent());
+ TypeReference mergeTypeRef = getMergeReferenceForApiLevel();
+ assertEquals(mergeTypeRef, init.getParameter(0).getTypeReference());
+ assertTrue(
+ clazz.allFields().stream()
+ .anyMatch(f -> mergeTypeRef.equals(f.getFinalReference().getFieldType())));
+ })
+ .run(parameters.getRuntime(), Main.class)
+ // The test succeeds for some unknown reason.
+ .assertSuccessWithOutputLines(typeName(Main.class));
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) throws Exception {
+ if (System.currentTimeMillis() > 0) {
+ System.out.println(
+ new A(Main.class.getDeclaredConstructor()).newInstance().getClass().getName());
+ } else {
+ System.out.println(
+ new B(Main.class.getDeclaredMethod("main", String[].class))
+ .newInstance()
+ .getClass()
+ .getName());
+ }
+ }
+ }
+
+ public abstract static class Factory {
+
+ abstract Object newInstance() throws Exception;
+ }
+
+ public static class A extends Factory {
+
+ public final Constructor<?> constructor;
+
+ public A(Constructor<?> constructor) {
+ this.constructor = constructor;
+ }
+
+ @Override
+ @NeverInline
+ Object newInstance() throws Exception {
+ return constructor.newInstance();
+ }
+ }
+
+ public static class B extends Factory {
+
+ public final Method method;
+
+ public B(Method method) {
+ this.method = method;
+ }
+
+ @Override
+ @NeverInline
+ Object newInstance() throws Exception {
+ return method.invoke(null);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/GuavaMultiSetSpliteratorTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/GuavaMultiSetSpliteratorTest.java
index 5e75ab4..a8fd859 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/GuavaMultiSetSpliteratorTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/GuavaMultiSetSpliteratorTest.java
@@ -63,6 +63,7 @@
Assume.assumeTrue(parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.L));
}
testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
+ // TODO(b/289363570): Guava should not rely on dagger.
.addProgramFiles(DaggerUtils.getGuavaFromDagger())
.addInnerClasses(getClass())
.addOptionsModification(opt -> opt.ignoreMissingClasses = true)
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
index 202d752..ce9ae53 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
@@ -41,7 +41,8 @@
@RunWith(Parameterized.class)
public class LintFilesTest extends DesugaredLibraryTestBase {
- private static final String ANDROID_JAR_34 = "third_party/android_jar/lib-v34/android.jar";
+ private static final String ANDROID_JAR_34 =
+ ToolHelper.THIRD_PARTY_DIR + "android_jar/lib-v34/android.jar";
private final LibraryDesugaringSpecification libraryDesugaringSpecification;
@@ -170,7 +171,12 @@
new String[] {
libraryDesugaringSpecification.getSpecification().toString(),
jdkLibJar.toString(),
- directory.toString()
+ directory.toString(),
+ // TODO(b/289365156): Should probably not be hardcoded on U.
+ ToolHelper.THIRD_PARTY_DIR
+ + "android_jar/lib-v"
+ + AndroidApiLevel.U.getLevel()
+ + "/android.jar"
});
InternalOptions options = new InternalOptions(new DexItemFactory(), new Reporter());
DesugaredLibrarySpecification desugaredLibrarySpecification =
@@ -213,7 +219,12 @@
"--generate-api-docs",
libraryDesugaringSpecification.getSpecification().toString(),
jdkLibJar.toString(),
- directory2.toString()
+ directory2.toString(),
+ // TODO(b/289365156): Should probably not be hardcoded on U.
+ ToolHelper.THIRD_PARTY_DIR
+ + "android_jar/lib-v"
+ + AndroidApiLevel.U.getLevel()
+ + "/android.jar"
});
List<String> html = Files.readAllLines(directory2.resolve("apis.html"));
// The doc has the same content than the lint data that is tested above, this is just a sanity
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestUtils.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestUtils.java
index b07f7b9..655e117 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestUtils.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestUtils.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.desugar.desugaredlibrary.gson;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import java.io.IOException;
@@ -14,8 +15,12 @@
public abstract class GsonDesugaredLibraryTestUtils {
static final Path GSON_CONFIGURATION =
- Paths.get("src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/gson.cfg");
- static final Path GSON_2_8_1_JAR = Paths.get("third_party/iosched_2019/gson-2.8.1.jar");
+ ToolHelper.getSourceFileForTestClass(GsonDesugaredLibraryTestUtils.class)
+ .getParent()
+ .resolve("gson.cfg");
+ // TODO(b/289363570): GSON should not rely on Iosched.
+ static final Path GSON_2_8_1_JAR =
+ Paths.get(ToolHelper.THIRD_PARTY_DIR, "iosched_2019/gson-2.8.1.jar");
static String uniqueName(
TemporaryFolder temp,
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TestLibraryDesugaringSpecification.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TestLibraryDesugaringSpecification.java
index f909be9..6eabf06 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TestLibraryDesugaringSpecification.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TestLibraryDesugaringSpecification.java
@@ -33,9 +33,10 @@
private static final String EXTENSION_STRING = "build/libs/java_base_extension.jar";
private static final Path JDK_11_JAVA_BASE_EXTENSION_FILES_DIR =
- Paths.get("third_party/openjdk/jdk-11-test/lib/testlibrary/bootlib/java.base");
+ Paths.get(
+ ToolHelper.THIRD_PARTY_DIR, "openjdk/jdk-11-test/lib/testlibrary/bootlib/java.base");
private static final Path JDK_11_TESTLIBRARY_FILES_DIR =
- Paths.get("third_party/openjdk/jdk-11-test/lib/testlibrary/jdk");
+ Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk/jdk-11-test/lib/testlibrary/jdk");
public static Path EXTENSION_PATH;
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
index 7f89255..b82ba3e 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
@@ -181,7 +181,7 @@
this(
name,
ImmutableSet.of(desugarJdkLibs, ToolHelper.getDesugarLibConversions(legacy)),
- Paths.get("src/library_desugar/" + specificationPath),
+ Paths.get(ToolHelper.LIBRARY_DESUGAR_SOURCE_DIR + specificationPath),
ImmutableSet.of(ToolHelper.getAndroidJar(androidJarLevel)),
descriptor,
"");
diff --git a/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineCallSiteInlinedTest.java b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineCallSiteInlinedTest.java
index 2e55faf..df61bf9 100644
--- a/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineCallSiteInlinedTest.java
+++ b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineCallSiteInlinedTest.java
@@ -55,52 +55,48 @@
"com.android.tools.r8.D8Command -> com.android.tools.r8.D8Command:",
"# {'id':'sourceFile','fileName':'SourceFile'}",
" 1:724:foo.internal.MapConsumer lambda$bar$0(foo.StringConsumer):0:723"
- + " -> lambda$bar$0$com-android-tools-r8-D8Command",
+ + " -> lambda$bar$0$new",
" 1:724:foo.internal.MapConsumer"
- + " lambda$bar$0$com-android-tools-r8-D8Command(foo.StringConsumer):0"
- + " -> lambda$bar$0$com-android-tools-r8-D8Command",
+ + " lambda$bar$0$new(foo.StringConsumer):0"
+ + " -> lambda$bar$0$new",
" # {'id':'com.android.tools.r8.synthesized'}");
private static final String mappingResult =
StringUtils.unixLines(
"# {'id':'com.android.tools.r8.mapping','version':'2.2'}",
"com.android.tools.r8.D8Command -> com.android.tools.r8.D8Command:",
"# {'id':'sourceFile','fileName':'D8Command.java'}",
- // TODO(b/288117378): This 1:1 range corresponds to position 0 in the residual of R8. This
- // should probably not have the `getParseFlagsInformation` inline frame.
" 1:1:java.util.List getParseFlagsInformation():592:592 -> getParseFlagsInformation",
+ // The following two frames is the preamble it is mapping to position 0. There is no
+ // positional information in mappingFoo, so the right thing here is to use the original
+ // signature from mappingBar/residual signature from mappingFoo.
" 1:1:foo.internal.MapConsumer lambda$bar$0(foo.StringConsumer):0:0 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
+ + " lambda$bar$0$new",
" 1:1:foo.internal.MapConsumer"
- + " lambda$bar$0$com-android-tools-r8-D8Command(foo.StringConsumer):0:0 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
+ + " lambda$bar$0$new(foo.StringConsumer):0:0 -> lambda$bar$0$new",
" # {'id':'com.android.tools.r8.synthesized'}",
- " 2:2:foo.MapConsumer lambda$bar$0(foo.StringConsumer):0:0 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
+ // This frame is the outline position in mappingFoo.
+ " 2:2:foo.MapConsumer lambda$bar$0(foo.StringConsumer):0:0 -> lambda$bar$0$new",
" # {'id':'com.android.tools.r8.residualsignature',"
+ "'signature':'(Lfoo/StringConsumer;)Lfoo/internal/MapConsumer;'}",
" # {'id':'com.android.tools.r8.outlineCallsite',"
+ "'positions':{'23':725,'24':726,'25':727},"
+ "'outline':'Lfoo/SomeClass;outline(JJJ)V'}",
" 2:2:foo.internal.MapConsumer"
- + " lambda$bar$0$com-android-tools-r8-D8Command(foo.StringConsumer):0:0 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
- " 3:724:foo.internal.MapConsumer lambda$bar$0(foo.StringConsumer) ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
- " 3:724:foo.internal.MapConsumer"
- + " lambda$bar$0$com-android-tools-r8-D8Command(foo.StringConsumer):0:0 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
- " 725:725:foo.internal.MapConsumer"
- + " lambda$bar$0$com-android-tools-r8-D8Command(foo.StringConsumer):720:720 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
- " 726:726:foo.PGMapConsumer foo.PGMapConsumer.builder():52:52 -> lambda$bar$0",
- " 726:726:foo.internal.MapConsumer"
- + " lambda$bar$0$com-android-tools-r8-D8Command(foo.StringConsumer):720 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command",
- " 727:727:void foo.PGMapConsumer.<init>():55:55 -> lambda$bar$0",
- " 727:727:foo.PGMapConsumer foo.PGMapConsumer.builder():52 -> lambda$bar$0",
- " 727:727:foo.internal.MapConsumer"
- + " lambda$bar$0$com-android-tools-r8-D8Command(foo.StringConsumer):720 ->"
- + " lambda$bar$0$com-android-tools-r8-D8Command");
+ + " lambda$bar$0$new(foo.StringConsumer):0:0 -> lambda$bar$0$new",
+ // This is the tail before any synthetic outline positions where the only information
+ // is in mappingBar.
+ " 3:724:foo.internal.MapConsumer lambda$bar$0(foo.StringConsumer) -> lambda$bar$0$new",
+ " 3:724:foo.internal.MapConsumer lambda$bar$0$new(foo.StringConsumer):0:0 "
+ + "-> lambda$bar$0$new",
+ // The remaining positions are the synthetic outline positions needed for correct
+ // retracing.
+ " 725:725:foo.MapConsumer lambda$bar$0(foo.StringConsumer):720:720 "
+ + "-> lambda$bar$0$new",
+ " 726:726:foo.PGMapConsumer foo.PGMapConsumer.builder():52:52 -> lambda$bar$0$new",
+ " 726:726:foo.MapConsumer lambda$bar$0(foo.StringConsumer):720 -> lambda$bar$0$new",
+ " 727:727:void foo.PGMapConsumer.<init>():55:55 -> lambda$bar$0$new",
+ " 727:727:foo.PGMapConsumer foo.PGMapConsumer.builder():52 -> lambda$bar$0$new",
+ " 727:727:foo.MapConsumer lambda$bar$0(foo.StringConsumer):720 -> lambda$bar$0$new");
@Test
public void testCompose() throws Exception {
diff --git a/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlinePositionRangeTest.java b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlinePositionRangeTest.java
new file mode 100644
index 0000000..753f3d7
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlinePositionRangeTest.java
@@ -0,0 +1,76 @@
+// Copyright (c) 2023, 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.mappingcompose;
+
+import static com.android.tools.r8.mappingcompose.ComposeTestHelpers.doubleToSingleQuote;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.naming.ClassNameMapper;
+import com.android.tools.r8.naming.MappingComposer;
+import com.android.tools.r8.utils.StringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/** This is a regression test for b/280564959. */
+@RunWith(Parameterized.class)
+public class ComposeOutlinePositionRangeTest extends TestBase {
+
+ @Parameter() public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ private static final String mappingFoo =
+ StringUtils.unixLines(
+ "# { id: 'com.android.tools.r8.mapping', version: '2.2' }",
+ "outline.Class -> a:",
+ " 1:2:int outline():11:12 -> a",
+ " # { 'id':'com.android.tools.r8.outline' }",
+ "outline.Callsite -> x:",
+ " 1:1:int outlineCaller(int):0:0 -> s",
+ " # { 'id':'com.android.tools.r8.outlineCallsite',"
+ + "'positions': { '1': 10, '2': 11 },"
+ + "'outline':'La;a()I' }",
+ " 10:11:int some.inlinee(int):23:24 -> s",
+ " 10:11:int outlineCaller(int):1337 -> s");
+ private static final String mappingBar =
+ StringUtils.unixLines(
+ "# {'id':'com.android.tools.r8.mapping','version':'2.2'}",
+ "a -> b:",
+ " 4:5:int a():1:2 -> m",
+ "x -> y:",
+ " 42:42:int s(int):1:1 -> o");
+ private static final String mappingResult =
+ StringUtils.unixLines(
+ "# {'id':'com.android.tools.r8.mapping','version':'2.2'}",
+ "outline.Callsite -> y:",
+ " 42:42:int outlineCaller(int):0:0 -> o",
+ " # {'id':'com.android.tools.r8.outlineCallsite',"
+ + "'positions':{'4':43,'5':44},"
+ + "'outline':'Lb;m()I'}",
+ " 43:43:int some.inlinee(int):23:23 -> o",
+ " 43:43:int outlineCaller(int):1337 -> o",
+ " 44:44:int some.inlinee(int):24:24 -> o",
+ " 44:44:int outlineCaller(int):1337 -> o",
+ "outline.Class -> b:",
+ " 4:5:int outline():11:12 -> m",
+ " # {'id':'com.android.tools.r8.outline'}");
+
+ @Test
+ public void testCompose() throws Exception {
+ ClassNameMapper mappingForFoo = ClassNameMapper.mapperFromStringWithPreamble(mappingFoo);
+ ClassNameMapper mappingForBar = ClassNameMapper.mapperFromStringWithPreamble(mappingBar);
+ String composed = MappingComposer.compose(mappingForFoo, mappingForBar);
+ assertEquals(mappingResult, doubleToSingleQuote(composed));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineTest.java b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineTest.java
index 48bfdfd..98ba4d5 100644
--- a/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineTest.java
+++ b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineTest.java
@@ -62,7 +62,7 @@
+ "'positions':{'4':43,'5':44},"
+ "'outline':'Lc;m()I'}",
" 43:43:int outlineCaller(int):23:23 -> o",
- " 44:44:int foo.bar.baz.outlineCaller(int):98:98 -> s",
+ " 44:44:int foo.bar.baz.outlineCaller(int):98:98 -> o",
" 44:44:int outlineCaller(int):24 -> o",
"outline.Class -> c:",
" 4:5:int some.inlinee():75:76 -> m",
diff --git a/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineWithIdRangeTest.java b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineWithIdRangeTest.java
index 20b1cb8..e79ad2c 100644
--- a/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineWithIdRangeTest.java
+++ b/src/test/java/com/android/tools/r8/mappingcompose/ComposeOutlineWithIdRangeTest.java
@@ -66,7 +66,7 @@
+ "'positions':{'1':9,'2':10},"
+ "'outline':'Lpackage/new_internal/X;b(JJJ)J'}",
" 8:8:void foo():38:38 -> b",
- " 9:9:void inlineeInOutline():1337:1337 -> a",
+ " 9:9:void inlineeInOutline():1337:1337 -> b",
" 9:9:void foo():42 -> b",
" 10:10:void foo():44:44 -> b",
"package.Class$$ExternalSyntheticOutline0 -> package.new_internal.X:",
diff --git a/src/test/java/com/android/tools/r8/naming/FieldMinificationResidualSignatureTest.java b/src/test/java/com/android/tools/r8/naming/FieldMinificationResidualSignatureTest.java
new file mode 100644
index 0000000..6466424
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/FieldMinificationResidualSignatureTest.java
@@ -0,0 +1,98 @@
+// Copyright (c) 2023, 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;
+
+import static com.android.tools.r8.CollectorsUtils.toSingle;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessagesImpl;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.references.FieldReference;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.retrace.ProguardMapProducer;
+import com.android.tools.r8.retrace.Retracer;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.Box;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class FieldMinificationResidualSignatureTest extends TestBase {
+
+ @Parameter() public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withSystemRuntime().build();
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ Box<FieldReference> minifiedMainField = new Box<>();
+ Box<FieldReference> minifiedBField = new Box<>();
+ String proguardMap =
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .setMinApi(AndroidApiLevel.B)
+ .addKeepMainRule(Main.class)
+ .addKeepAllClassesRuleWithAllowObfuscation()
+ .compile()
+ .inspect(
+ inspector -> {
+ minifiedMainField.set(
+ inspector.clazz(Main.class).allFields().get(0).getFinalReference());
+ minifiedBField.set(
+ inspector.clazz(B.class).allFields().get(0).getFinalReference());
+ })
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("Hello World!")
+ .proguardMap();
+ Retracer retracer =
+ Retracer.createDefault(
+ ProguardMapProducer.fromString(proguardMap), new TestDiagnosticMessagesImpl());
+ assertEquals(
+ Reference.fieldFromField(Main.class.getDeclaredField("a")),
+ retracer.retraceField(minifiedMainField.get()).stream()
+ .map(rfe -> rfe.getField().asKnown().getFieldReference())
+ .collect(toSingle()));
+ assertEquals(
+ Reference.fieldFromField(B.class.getDeclaredField("worldContainer")),
+ retracer.retraceField(minifiedBField.get()).stream()
+ .map(rfe -> rfe.getField().asKnown().getFieldReference())
+ .collect(toSingle()));
+ }
+
+ public static class Main {
+
+ private static final Container a = new Container("Hello ");
+
+ public static void main(String[] args) {
+ System.out.println(a.getMessage() + B.worldContainer.getMessage());
+ }
+ }
+
+ public static class Container {
+
+ private final String message;
+
+ public Container(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+ }
+
+ public static class B {
+
+ public static final Container worldContainer = new Container("World!");
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
index 9dc47ba..f49e491 100644
--- a/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
@@ -204,7 +204,7 @@
FieldSubject anX = lookupAnX(inspector);
FieldSubject anArrayOfX = lookupAnArrayOfX(inspector);
- FieldSubject aFieldsOfX =lookupAFieldsOfX(inspector);
+ FieldSubject aFieldsOfX = lookupAFieldsOfX(inspector);
FieldSubject aFieldsOfXInner = clazz.field("Fields$Inner", "aFieldsOfXInner");
// Check that all fields have been renamed
diff --git a/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java b/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java
index 81a977b..045cc76 100644
--- a/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java
@@ -13,9 +13,11 @@
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DataEntryResource;
+import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.StreamUtils;
import com.android.tools.r8.utils.StringUtils;
@@ -54,66 +56,72 @@
@Test
public void test() throws IOException, CompilationFailedException, ExecutionException {
Path path = temp.newFile("out.zip").toPath();
- testForR8(parameters.getBackend())
- .addInnerClasses(ScriptEngineTest.class)
- .addKeepMainRule(TestClass.class)
- .applyIf(
- parameters.isDexRuntime(),
- testBuilder ->
- testBuilder.addOptionsModification(
- options ->
- options
- .getOpenClosedInterfacesOptions()
- .suppressAllOpenInterfacesDueToMissingClasses()))
- .setMinApi(parameters)
- .addDataEntryResources(
- DataEntryResource.fromBytes(
- StringUtils.lines(MyScriptEngine1FactoryImpl.class.getTypeName()).getBytes(),
- "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
- Origin.unknown()))
- .addDataEntryResources(
- DataEntryResource.fromBytes(
- StringUtils.lines(MyScriptEngine2FactoryImpl.class.getTypeName()).getBytes(),
- "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
- Origin.unknown()))
- .apply(
- b -> {
- if (parameters.isDexRuntime()) {
- addRhinoForAndroid(b);
- b.allowDiagnosticWarningMessages();
- }
- })
- // TODO(b/136633154): This should work both with and without -dontobfuscate.
- .addDontObfuscate()
- // TODO(b/136633154): This should work both with and without -dontshrink.
- .noTreeShaking()
- .compile()
- .applyIf(
- parameters.isDexRuntime(),
- result ->
- result.assertAllWarningMessagesMatch(
- anyOf(
- containsString("Missing class "),
- containsString(
- "it is required for default or static interface methods desugaring"),
- allOf(
- containsString("Unverifiable code in `"),
- containsString("org.mozilla.javascript.tools.")),
- equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))))
- .writeToZip(path)
- .run(parameters.getRuntime(), TestClass.class)
- // TODO(b/136633154): This should provide 2 script engines on both runtimes. The use of
- // the rhino-android library on Android will add the Rhino script engine, and the JVM
- // comes with "Oracle Nashorn" included.
- .assertSuccessWithOutput(
- parameters.isCfRuntime()
- // No default JS engine starting from JDK-14 where Nashorn was removed,
- // see b/227162584.
- ? (parameters.isCfRuntime()
- && parameters.asCfRuntime().isNewerThanOrEqual(CfVm.JDK14)
- ? StringUtils.lines("MyEngine1", "MyEngine2")
- : StringUtils.lines("MyEngine1", "MyEngine2", "Oracle Nashorn"))
- : StringUtils.lines("Mozilla Rhino", "MyEngine1", "MyEngine2"));
+ R8TestRunResult runResult =
+ testForR8(parameters.getBackend())
+ .addInnerClasses(ScriptEngineTest.class)
+ .addKeepMainRule(TestClass.class)
+ .applyIf(
+ parameters.isDexRuntime(),
+ testBuilder ->
+ testBuilder.addOptionsModification(
+ options ->
+ options
+ .getOpenClosedInterfacesOptions()
+ .suppressAllOpenInterfacesDueToMissingClasses()))
+ .setMinApi(parameters)
+ .addDataEntryResources(
+ DataEntryResource.fromBytes(
+ StringUtils.lines(MyScriptEngine1FactoryImpl.class.getTypeName()).getBytes(),
+ "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
+ Origin.unknown()))
+ .addDataEntryResources(
+ DataEntryResource.fromBytes(
+ StringUtils.lines(MyScriptEngine2FactoryImpl.class.getTypeName()).getBytes(),
+ "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
+ Origin.unknown()))
+ .apply(
+ b -> {
+ if (parameters.isDexRuntime()) {
+ addRhinoForAndroid(b);
+ b.allowDiagnosticWarningMessages();
+ }
+ })
+ // TODO(b/136633154): This should work both with and without -dontobfuscate.
+ .addDontObfuscate()
+ // TODO(b/136633154): This should work both with and without -dontshrink.
+ .noTreeShaking()
+ .compile()
+ .applyIf(
+ parameters.isDexRuntime(),
+ result ->
+ result.assertAllWarningMessagesMatch(
+ anyOf(
+ containsString("Missing class "),
+ containsString(
+ "it is required for default or static interface methods"
+ + " desugaring"),
+ allOf(
+ containsString("Unverifiable code in `"),
+ containsString("org.mozilla.javascript.tools.")),
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))))
+ .writeToZip(path)
+ .run(parameters.getRuntime(), TestClass.class);
+ if (parameters.isDexRuntimeVersion(Version.V7_0_0)) {
+ // TODO(b/290592800): sun.misc.Service is defined on bootclasspath for android 7.
+ runResult.assertFailureWithErrorThatThrows(IllegalAccessError.class);
+ } else {
+ // TODO(b/136633154): This should provide 2 script engines on both runtimes. The use of
+ // the rhino-android library on Android will add the Rhino script engine, and the JVM
+ // comes with "Oracle Nashorn" included.
+ runResult.assertSuccessWithOutput(
+ parameters.isCfRuntime()
+ // No default JS engine starting from JDK-14 where Nashorn was removed,
+ // see b/227162584.
+ ? (parameters.isCfRuntime() && parameters.asCfRuntime().isNewerThanOrEqual(CfVm.JDK14)
+ ? StringUtils.lines("MyEngine1", "MyEngine2")
+ : StringUtils.lines("MyEngine1", "MyEngine2", "Oracle Nashorn"))
+ : StringUtils.lines("Mozilla Rhino", "MyEngine1", "MyEngine2"));
+ }
// TODO(b/136633154): On the JVM this should always be there as the service loading is in
// the library. On Android we should be able to rewrite the code and not have it.
diff --git a/src/test/java/com/android/tools/r8/utils/DaggerUtils.java b/src/test/java/com/android/tools/r8/utils/DaggerUtils.java
index 80fad3d..685c0e7 100644
--- a/src/test/java/com/android/tools/r8/utils/DaggerUtils.java
+++ b/src/test/java/com/android/tools/r8/utils/DaggerUtils.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.TestRuntime.CfRuntime;
+import com.android.tools.r8.ToolHelper;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import java.nio.file.Path;
@@ -20,7 +21,7 @@
public class DaggerUtils {
- private static final Path DAGGER_ROOT = Paths.get("third_party", "dagger", "2.41");
+ private static final Path DAGGER_ROOT = Paths.get(ToolHelper.THIRD_PARTY_DIR, "dagger", "2.41");
private static final String GUAVA = "guava-31.0.1-jre.jar";
private static final List<Path> DAGGER_COMPILER =
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
index abc83be..c9aeccb 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
@@ -57,6 +57,13 @@
return signature;
}
+ // First check if we have residual signature information.
+
+ MemberNaming memberNaming = clazz.getNaming().lookup(signature);
+ if (memberNaming != null) {
+ return memberNaming.getOriginalSignature().asFieldSignature();
+ }
+
// Map the type to the original name. This is needed as the in the Proguard map the
// names on the left side are the original names. E.g.
//
@@ -70,9 +77,9 @@
String fieldType = originalType != null ? originalType : obfuscatedType;
FieldSignature lookupSignature = new FieldSignature(signature.name, fieldType);
- MemberNaming memberNaming = clazz.getNaming().lookup(lookupSignature);
+ memberNaming = clazz.getNaming().lookup(lookupSignature);
return memberNaming != null
- ? (FieldSignature) memberNaming.getOriginalSignature()
+ ? memberNaming.getOriginalSignature().asFieldSignature()
: lookupSignature;
}
@@ -148,7 +155,7 @@
public FieldReference getFinalReference() {
return Reference.field(
Reference.classFromDescriptor(getField().getHolderType().toDescriptorString()),
- getOriginalName(),
+ getFinalName(),
Reference.typeFromDescriptor(getField().getType().toDescriptorString()));
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/TypeSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/TypeSubject.java
index 5761b99..efa2c30 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/TypeSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/TypeSubject.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.references.TypeReference;
public class TypeSubject extends Subject {
@@ -21,6 +22,10 @@
return dexType.getTypeName();
}
+ public TypeReference getTypeReference() {
+ return dexType.asTypeReference();
+ }
+
@Override
public boolean isPresent() {
return true;