Merge commit 'e139309308ffc3cb030bc705f6e2496cd423a35a' into dev-release
diff --git a/.gitignore b/.gitignore
index 8534e4c..28f7415 100644
--- a/.gitignore
+++ b/.gitignore
@@ -111,6 +111,8 @@
third_party/nest/*
third_party/openjdk/desugar_jdk_libs
third_party/openjdk/desugar_jdk_libs.tar.gz
+third_party/openjdk/desugar_jdk_libs_11
+third_party/openjdk/desugar_jdk_libs_11.tar.gz
third_party/openjdk/jdk-15/linux
third_party/openjdk/jdk-15/linux.tar.gz
third_party/openjdk/jdk-15/osx
diff --git a/build.gradle b/build.gradle
index 323256b..2e908a5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -329,6 +329,7 @@
"kotlinx-coroutines-1.3.6",
"openjdk/openjdk-rt-1.8",
"openjdk/desugar_jdk_libs",
+ "openjdk/desugar_jdk_libs_11",
"openjdk/jdk-11-test",
"proguard/proguard5.2.1",
"proguard/proguard6.0.1",
@@ -566,7 +567,9 @@
if (OperatingSystem.current().isLinux()) {
options.forkOptions.javaHome = file(jdkDir + 'linux')
} else if (OperatingSystem.current().isMacOsX()) {
- options.forkOptions.javaHome = file(jdkDir + 'osx')
+ options.forkOptions.javaHome = compatibility > JavaVersion.VERSION_1_9
+ ? file(jdkDir + 'osx/Contents/Home')
+ : file(jdkDir + 'osx')
} else {
options.forkOptions.javaHome = file(jdkDir + 'windows')
}
@@ -997,6 +1000,16 @@
])
}
+task buildDesugaredLibrary(type: Exec) {
+ def outputDir = "build/libs"
+ def script = "tools/create_jctf_tests.py"
+ inputs.file script
+ outputs.dir outputDir
+ dependsOn downloadDeps
+ commandLine "python", script
+ workingDir = projectDir
+}
+
task generateR8LibKeepRules(type: Exec) {
doFirst {
// TODO(b/154785341): We should remove this.
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg
index 5e0355e..b782dbe 100644
--- a/infra/config/global/luci-scheduler.cfg
+++ b/infra/config/global/luci-scheduler.cfg
@@ -19,11 +19,11 @@
# The format of this file is important, we have a hackish parsing to trigger
# builds in tools/trigger.py
trigger {
- id: "master-gitiles-trigger"
+ id: "main-gitiles-trigger"
acl_sets: "default"
gitiles: {
repo: "https://r8.googlesource.com/r8"
- refs: "refs/heads/master"
+ refs: "refs/heads/main"
}
triggers: "archive"
triggers: "linux"
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index f0cb3e8..555713b 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -206,6 +206,7 @@
private BiPredicate<String, Long> dexClassChecksumFilter = (name, checksum) -> true;
private List<AssertionsConfiguration> assertionsConfiguration = new ArrayList<>();
private List<Consumer<Inspector>> outputInspections = new ArrayList<>();
+ protected StringConsumer proguardMapConsumer = null;
abstract CompilationMode defaultCompilationMode();
@@ -278,6 +279,33 @@
}
/**
+ * Set an output destination to which proguard-map content should be written.
+ *
+ * <p>This is a short-hand for setting a {@link StringConsumer.FileConsumer} using {@link
+ * #setProguardMapConsumer}. Note that any subsequent call to this method or {@link
+ * #setProguardMapConsumer} will override the previous setting.
+ *
+ * @param proguardMapOutput File-system path to write output at.
+ */
+ B setProguardMapOutputPath(Path proguardMapOutput) {
+ assert proguardMapOutput != null;
+ return setProguardMapConsumer(new StringConsumer.FileConsumer(proguardMapOutput));
+ }
+
+ /**
+ * Set a consumer for receiving the proguard-map content.
+ *
+ * <p>Note that any subsequent call to this method or {@link #setProguardMapOutputPath} will
+ * override the previous setting.
+ *
+ * @param proguardMapConsumer Consumer to receive the content once produced.
+ */
+ B setProguardMapConsumer(StringConsumer proguardMapConsumer) {
+ this.proguardMapConsumer = proguardMapConsumer;
+ return self();
+ }
+
+ /**
* Get the main dex list consumer that will receive the final complete main dex list.
*/
public StringConsumer getMainDexListConsumer() {
diff --git a/src/main/java/com/android/tools/r8/DumpOptions.java b/src/main/java/com/android/tools/r8/DumpOptions.java
index 3feeee3..f923ffa 100644
--- a/src/main/java/com/android/tools/r8/DumpOptions.java
+++ b/src/main/java/com/android/tools/r8/DumpOptions.java
@@ -143,7 +143,7 @@
}
public boolean hasMainDexKeepRules() {
- return mainDexKeepRules != null;
+ return mainDexKeepRules != null && !mainDexKeepRules.isEmpty();
}
public List<ProguardConfigurationRule> getMainDexKeepRules() {
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 4c235d9..1fc7689 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -253,6 +253,33 @@
return self();
}
+ /**
+ * Set an output destination to which proguard-map content should be written.
+ *
+ * <p>This is a short-hand for setting a {@link StringConsumer.FileConsumer} using {@link
+ * #setProguardMapConsumer}. Note that any subsequent call to this method or {@link
+ * #setProguardMapConsumer} will override the previous setting.
+ *
+ * @param proguardMapOutput File-system path to write output at.
+ */
+ @Override
+ public L8Command.Builder setProguardMapOutputPath(Path proguardMapOutput) {
+ return super.setProguardMapOutputPath(proguardMapOutput);
+ }
+
+ /**
+ * Set a consumer for receiving the proguard-map content.
+ *
+ * <p>Note that any subsequent call to this method or {@link #setProguardMapOutputPath} will
+ * override the previous setting.
+ *
+ * @param proguardMapConsumer Consumer to receive the content once produced.
+ */
+ @Override
+ public L8Command.Builder setProguardMapConsumer(StringConsumer proguardMapConsumer) {
+ return super.setProguardMapConsumer(proguardMapConsumer);
+ }
+
@Override
void validate() {
if (isPrintHelp()) {
@@ -273,6 +300,9 @@
if (isShrinking() && getProgramConsumer() instanceof ClassFileConsumer) {
reporter.error("L8 does not support shrinking when generating class files");
}
+ if (!isShrinking() && proguardMapConsumer != null) {
+ reporter.error("L8 does not support defining a map consumer when not shrinking");
+ }
super.validate();
}
@@ -294,7 +324,7 @@
D8Command d8Command = null;
AndroidApp inputs = getAppBuilder().build();
- ProgramConsumer l8CfConsumer = null;
+ ProgramConsumer l8CfConsumer;
if (isShrinking()) {
l8CfConsumer = new InMemoryJarContent();
R8Command.Builder r8Builder =
@@ -314,6 +344,9 @@
for (Pair<List<String>, Origin> proguardConfig : proguardConfigStrings) {
r8Builder.addProguardConfiguration(proguardConfig.getFirst(), proguardConfig.getSecond());
}
+ if (proguardMapConsumer != null) {
+ r8Builder.setProguardMapConsumer(proguardMapConsumer);
+ }
r8Builder.addProguardConfiguration(
libraryConfiguration.getExtraKeepRules(), Origin.unknown());
// TODO(b/180903899): Remove rule when -dontwarn sun.misc.Unsafe is part of config.
diff --git a/src/main/java/com/android/tools/r8/L8CommandParser.java b/src/main/java/com/android/tools/r8/L8CommandParser.java
index 3dac9dc..402e59a 100644
--- a/src/main/java/com/android/tools/r8/L8CommandParser.java
+++ b/src/main/java/com/android/tools/r8/L8CommandParser.java
@@ -18,8 +18,15 @@
public class L8CommandParser extends BaseCompilerCommandParser<L8Command, L8Command.Builder> {
- private static final Set<String> OPTIONS_WITH_PARAMETER = ImmutableSet.of(
- "--output", "--lib", MIN_API_FLAG, "--desugared-lib", THREAD_COUNT_FLAG, "--pg-conf");
+ private static final Set<String> OPTIONS_WITH_PARAMETER =
+ ImmutableSet.of(
+ "--output",
+ "--lib",
+ MIN_API_FLAG,
+ "--desugared-lib",
+ THREAD_COUNT_FLAG,
+ "--pg-conf",
+ "--pg-map-output");
public static void main(String[] args) throws CompilationFailedException {
L8Command command = parse(args, Origin.root()).build();
@@ -50,6 +57,8 @@
+ AndroidApiLevel.getDefault().getLevel()
+ ".",
" --pg-conf <file> # Proguard configuration <file>.",
+ " --pg-map-output <file> # Output the resulting name and line mapping to"
+ + " <file>.",
" --desugared-lib <file> # Specify desugared library configuration.",
" # <file> is a desugared library configuration"
+ " (json)."),
@@ -149,6 +158,8 @@
addLibraryArgument(builder, origin, nextArg);
} else if (arg.equals("--pg-conf")) {
builder.addProguardConfigurationFiles(Paths.get(nextArg));
+ } else if (arg.equals("--pg-map-output")) {
+ builder.setProguardMapOutputPath(Paths.get(nextArg));
} else if (arg.equals("--desugared-lib")) {
builder.addDesugaredLibraryConfiguration(StringResource.fromFile(Paths.get(nextArg)));
} else if (arg.equals("--classfile")) {
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 9663d3f..2b3f988 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -102,7 +102,6 @@
private boolean disableVerticalClassMerging = false;
private boolean forceProguardCompatibility = false;
private Optional<Boolean> includeDataResources = Optional.empty();
- private StringConsumer proguardMapConsumer = null;
private StringConsumer proguardUsageConsumer = null;
private StringConsumer proguardSeedsConsumer = null;
private StringConsumer proguardConfigurationConsumer = null;
@@ -237,10 +236,9 @@
*
* @param proguardMapOutput File-system path to write output at.
*/
+ @Override
public Builder setProguardMapOutputPath(Path proguardMapOutput) {
- assert proguardMapOutput != null;
- this.proguardMapConsumer = new StringConsumer.FileConsumer(proguardMapOutput);
- return self();
+ return super.setProguardMapOutputPath(proguardMapOutput);
}
/**
@@ -251,9 +249,9 @@
*
* @param proguardMapConsumer Consumer to receive the content once produced.
*/
+ @Override
public Builder setProguardMapConsumer(StringConsumer proguardMapConsumer) {
- this.proguardMapConsumer = proguardMapConsumer;
- return self();
+ return super.setProguardMapConsumer(proguardMapConsumer);
}
/**
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 8a28e9f..062c572 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -31,7 +31,7 @@
}
static int getMajorVersion(String label) {
- if (label.equals("master")) {
+ if (label.equals("main")) {
return -1;
}
int start = 0;
@@ -49,7 +49,7 @@
}
static int getMinorVersion(String label) {
- if (label.equals("master")) {
+ if (label.equals("main")) {
return -1;
}
int start = label.indexOf('.') + 1;
@@ -67,7 +67,7 @@
}
static int getPatchVersion(String label) {
- if (label.equals("master")) {
+ if (label.equals("main")) {
return -1;
}
int skip = label.indexOf('.') + 1;
@@ -87,7 +87,7 @@
}
static String getPreReleaseString(String label) {
- if (label.equals("master")) {
+ if (label.equals("main")) {
return null;
}
int start = label.indexOf('-') + 1;
@@ -107,6 +107,6 @@
}
static boolean isDevelopmentVersion(String label, boolean isEngineering) {
- return label.equals("master") || label.endsWith("-dev") || isEngineering;
+ return label.equals("main") || label.endsWith("-dev") || isEngineering;
}
}
diff --git a/src/main/java/com/android/tools/r8/contexts/CompilationContext.java b/src/main/java/com/android/tools/r8/contexts/CompilationContext.java
index b2cc211..f037883 100644
--- a/src/main/java/com/android/tools/r8/contexts/CompilationContext.java
+++ b/src/main/java/com/android/tools/r8/contexts/CompilationContext.java
@@ -8,8 +8,8 @@
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
public class CompilationContext {
@@ -35,7 +35,7 @@
}
private final Consumer<String> testingConsumer;
- private final Set<String> seenSetForTesting = new HashSet<>();
+ private final Map<String, String> seenSetForTesting = new ConcurrentHashMap<>();
private int nextProcessorId = 0;
private CompilationContext(InternalOptions options) {
@@ -49,7 +49,7 @@
if (testingConsumer != null) {
testingConsumer.accept(descriptor);
}
- assert seenSetForTesting.add(descriptor)
+ assert seenSetForTesting.put(descriptor, descriptor) == null
: "Duplicated use of context descriptor: " + descriptor;
return true;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 8ba291b..86b96e8 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -27,6 +27,7 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.desugar.LambdaClass;
import com.android.tools.r8.kotlin.Kotlin;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.DescriptorUtils;
@@ -299,6 +300,8 @@
public final DexString thisName = createString("this");
public final DexString lambdaInstanceFieldName = createString(LAMBDA_INSTANCE_FIELD_NAME);
+ public final DexString javacLambdaMethodPrefix =
+ createString(LambdaClass.JAVAC_EXPECTED_LAMBDA_METHOD_PREFIX);
// As much as possible, R8 should rely on the content of the static enum field, using
// enumMembers.isValuesFieldCandidate or checking the object state in the optimization info.
diff --git a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
index 0f7b951..ceac26a 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -143,7 +143,8 @@
if (definitionFor(type) == null && definitionFor(renamed) != null) {
continue;
}
- assert definitionFor(type).type == renamed || definitionFor(renamed) != null;
+ assert definitionFor(type).type == renamed || definitionFor(renamed) != null
+ : "The lens and app is inconsistent";
}
}
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java
index b4cab05..864a7b4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java
@@ -12,6 +12,10 @@
/** Interface for desugaring a single class-file instruction. */
public interface CfInstructionDesugaring {
+ default void scan(ProgramMethod method, CfInstructionDesugaringEventConsumer eventConsumer) {
+ // Default scan is to do nothing.
+ }
+
/**
* Given an instruction, returns the list of instructions that the instruction should be desugared
* to. If no desugaring is needed, {@code null} should be returned (for efficiency).
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index a264d65..3b5a40b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
+import com.android.tools.r8.graph.DexMethodHandle.MethodHandleType;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
@@ -272,12 +273,6 @@
// Creates a delegation target for this particular lambda class. Note that we
// should always be able to create targets for the lambdas we support.
private Target createTarget(ProgramMethod accessedFrom) {
- if (appView.options().canAccessModifyLambdaImplementationMethods(appView)
- && descriptor.delegatesToLambdaImplMethod()) {
- return createLambdaImplMethodTarget(accessedFrom);
- }
-
- // Method referenced directly, without lambda$ method.
switch (descriptor.implHandle.type) {
case INVOKE_SUPER:
throw new Unimplemented("Method references to super methods are not yet supported");
@@ -286,8 +281,13 @@
case INVOKE_CONSTRUCTOR:
return createConstructorTarget(accessedFrom);
case INVOKE_STATIC:
- return createStaticMethodTarget(accessedFrom);
+ return canAccessModifyLambdaImplMethod()
+ ? createLambdaImplMethodTarget(accessedFrom)
+ : createStaticMethodTarget(accessedFrom);
case INVOKE_DIRECT:
+ return canAccessModifyLambdaImplMethod()
+ ? createLambdaImplMethodTarget(accessedFrom)
+ : createInstanceMethodTarget(accessedFrom);
case INVOKE_INSTANCE:
return createInstanceMethodTarget(accessedFrom);
default:
@@ -295,12 +295,25 @@
}
}
+ private boolean doesNotNeedAccessor(ProgramMethod accessedFrom) {
+ return canAccessModifyLambdaImplMethod() || !descriptor.needsAccessor(accessedFrom);
+ }
+
+ private boolean canAccessModifyLambdaImplMethod() {
+ MethodHandleType invokeType = descriptor.implHandle.type;
+ return appView.options().canAccessModifyLambdaImplementationMethods(appView)
+ && (invokeType.isInvokeDirect() || invokeType.isInvokeStatic())
+ && descriptor.delegatesToLambdaImplMethod(appView.dexItemFactory())
+ && !desugaring.isDirectTargetedLambdaImplementationMethod(descriptor.implHandle);
+ }
+
private Target createLambdaImplMethodTarget(ProgramMethod accessedFrom) {
DexMethodHandle implHandle = descriptor.implHandle;
assert implHandle != null;
DexMethod implMethod = implHandle.asMethod();
// Lambda$ method. We should always find it. If not found an ICCE can be expected to be thrown.
+ assert descriptor.delegatesToLambdaImplMethod(appView.dexItemFactory());
assert implMethod.holder == accessedFrom.getHolderType();
assert descriptor.verifyTargetFoundInClass(accessedFrom.getHolderType());
if (implHandle.type.isInvokeStatic()) {
@@ -318,12 +331,10 @@
result.getResolvedHolder().asProgramClass(), result.getResolvedMethod()));
}
- assert implHandle.type.isInvokeInstance() || implHandle.type.isInvokeDirect();
-
+ assert implHandle.type.isInvokeDirect();
// If the lambda$ method is an instance-private method on an interface we convert it into a
// public static method as it will be placed on the companion class.
- if (implHandle.type.isInvokeDirect()
- && appView.definitionFor(implMethod.holder).isInterface()) {
+ if (appView.definitionFor(implMethod.holder).isInterface()) {
DexProto implProto = implMethod.proto;
DexType[] implParams = implProto.parameters.values;
DexType[] newParams = new DexType[implParams.length + 1];
@@ -356,7 +367,7 @@
assert descriptor.implHandle.type.isInvokeInstance() ||
descriptor.implHandle.type.isInvokeDirect();
- if (!descriptor.needsAccessor(appView, accessedFrom)) {
+ if (doesNotNeedAccessor(accessedFrom)) {
return new NoAccessorMethodTarget(Invoke.Type.VIRTUAL);
}
// We need to generate an accessor method in `accessedFrom` class/interface
@@ -388,7 +399,7 @@
private Target createStaticMethodTarget(ProgramMethod accessedFrom) {
assert descriptor.implHandle.type.isInvokeStatic();
- if (!descriptor.needsAccessor(appView, accessedFrom)) {
+ if (doesNotNeedAccessor(accessedFrom)) {
return new NoAccessorMethodTarget(Invoke.Type.STATIC);
}
@@ -412,7 +423,7 @@
assert implHandle != null;
assert implHandle.type.isInvokeConstructor();
- if (!descriptor.needsAccessor(appView, accessedFrom)) {
+ if (doesNotNeedAccessor(accessedFrom)) {
return new NoAccessorMethodTarget(Invoke.Type.DIRECT);
}
@@ -435,7 +446,7 @@
// Create targets for interface methods.
private Target createInterfaceMethodTarget(ProgramMethod accessedFrom) {
assert descriptor.implHandle.type.isInvokeInterface();
- assert !descriptor.needsAccessor(appView, accessedFrom);
+ assert doesNotNeedAccessor(accessedFrom);
return new NoAccessorMethodTarget(Invoke.Type.INTERFACE);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
index 3cc480d..edfa934 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
@@ -4,11 +4,8 @@
package com.android.tools.r8.ir.desugar;
-import static com.android.tools.r8.ir.desugar.LambdaClass.JAVAC_EXPECTED_LAMBDA_METHOD_PREFIX;
-
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
-import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -180,14 +177,9 @@
return targetHolder == type;
}
- public boolean canAccessModifyLambdaImplementationMethods(AppView<?> appView) {
- return appView.enableWholeProgramOptimizations();
- }
-
/** If the lambda delegates to lambda$ method. */
- public boolean delegatesToLambdaImplMethod() {
- String methodName = implHandle.asMethod().getName().toString();
- return methodName.startsWith(JAVAC_EXPECTED_LAMBDA_METHOD_PREFIX);
+ public boolean delegatesToLambdaImplMethod(DexItemFactory factory) {
+ return implHandle.asMethod().getName().startsWith(factory.javacLambdaMethodPrefix);
}
/** Is a stateless lambda, i.e. lambda does not capture any values */
@@ -196,12 +188,7 @@
}
/** Checks if call site needs a accessor when referenced from `accessedFrom`. */
- boolean needsAccessor(AppView<?> appView, ProgramMethod accessedFrom) {
- if (appView.options().canAccessModifyLambdaImplementationMethods(appView)
- && delegatesToLambdaImplMethod()) {
- return false;
- }
-
+ boolean needsAccessor(ProgramMethod accessedFrom) {
if (implHandle.type.isInvokeInterface()) {
// Interface methods must be public.
return false;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
index 3a7a195..433e023 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
@@ -98,9 +98,7 @@
@Override
public void scan(ProgramMethod method, CfInstructionDesugaringEventConsumer eventConsumer) {
ensureCfCode(method);
- if (recordRewriter != null) {
- recordRewriter.scan(method, eventConsumer);
- }
+ desugarings.forEach(d -> d.scan(method, eventConsumer));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/RecordRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/RecordRewriter.java
index 469f119..d8d47e8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/RecordRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/RecordRewriter.java
@@ -78,6 +78,7 @@
recordHashCodeHelperProto = factory.createProto(factory.intType, factory.recordType);
}
+ @Override
public void scan(
ProgramMethod programMethod, CfInstructionDesugaringEventConsumer eventConsumer) {
CfCode cfCode = programMethod.getDefinition().getCode().asCfCode();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
index 34dda4e..59411a7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
@@ -15,6 +15,9 @@
import com.android.tools.r8.cf.code.CfStore;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.CfCode;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.ProgramMethod;
@@ -28,20 +31,42 @@
import com.android.tools.r8.synthesis.SyntheticNaming;
import com.android.tools.r8.utils.Box;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
+import java.util.Set;
import org.objectweb.asm.Opcodes;
public class LambdaInstructionDesugaring implements CfInstructionDesugaring {
private final AppView<?> appView;
+ private final Set<DexMethod> directTargetedLambdaImplementationMethods =
+ Sets.newIdentityHashSet();
+
+ public boolean isDirectTargetedLambdaImplementationMethod(DexMethodHandle implMethod) {
+ return implMethod.type.isInvokeDirect()
+ && directTargetedLambdaImplementationMethods.contains(implMethod.asMethod());
+ }
public LambdaInstructionDesugaring(AppView<?> appView) {
this.appView = appView;
}
@Override
+ public void scan(ProgramMethod method, CfInstructionDesugaringEventConsumer eventConsumer) {
+ CfCode code = method.getDefinition().getCode().asCfCode();
+ for (CfInstruction instruction : code.getInstructions()) {
+ if (instruction.isInvokeSpecial()) {
+ DexMethod target = instruction.asInvoke().getMethod();
+ if (target.getName().startsWith(appView.dexItemFactory().javacLambdaMethodPrefix)) {
+ directTargetedLambdaImplementationMethods.add(target);
+ }
+ }
+ }
+ }
+
+ @Override
public Collection<CfInstruction> desugarInstruction(
CfInstruction instruction,
FreshLocalProvider freshLocalProvider,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
index 0cc7497..7dae8cd 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize;
+import static com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult.isOverriding;
+
import com.android.tools.r8.graph.AccessControl;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
@@ -376,7 +378,11 @@
|| !newResolutionResult
.getResolvedMethod()
.getAccessFlags()
- .isAtLeastAsVisibleAs(resolutionResult.getResolvedMethod().getAccessFlags())) {
+ .isAtLeastAsVisibleAs(resolutionResult.getResolvedMethod().getAccessFlags())
+ // isOverriding expects both arguments to be not private.
+ || (!newResolutionResult.getResolvedMethod().isPrivateMethod()
+ && !isOverriding(
+ resolutionResult.getResolvedMethod(), newResolutionResult.getResolvedMethod()))) {
return target;
}
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 5ade4de..9da3a40 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.jar;
-import static com.android.tools.r8.repackaging.Repackaging.DefaultRepackagingConfiguration.TEMPORARY_PACKAGE_NAME;
import static com.android.tools.r8.utils.InternalOptions.ASM_VERSION;
import com.android.tools.r8.ByteDataView;
@@ -186,7 +185,6 @@
}
String desc = namingLens.lookupDescriptor(clazz.type).toString();
String name = namingLens.lookupInternalName(clazz.type);
- assert !name.contains(TEMPORARY_PACKAGE_NAME);
String signature = clazz.getClassSignature().toRenamedString(namingLens, isTypeMissing);
String superName =
clazz.type == options.itemFactory.objectType
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index 9ab6c15..e53f285 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -18,10 +18,8 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.shaking.ProguardPackageNameList;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
@@ -37,9 +35,7 @@
private final AppView<AppInfoWithLiveness> appView;
private final ClassNamingStrategy classNamingStrategy;
- private final PackageNamingStrategy packageNamingStrategy;
private final Iterable<? extends DexClass> classes;
- private final Set<String> usedPackagePrefixes = Sets.newHashSet();
private final Set<String> usedTypeNames = Sets.newHashSet();
private final Map<DexType, DexString> renaming = Maps.newIdentityHashMap();
private final Map<String, Namespace> states = new HashMap<>();
@@ -48,27 +44,19 @@
private final Namespace topLevelState;
private final boolean allowMixedCaseNaming;
private final Predicate<String> isUsed;
- private final ProguardPackageNameList keepPackageNames;
ClassNameMinifier(
AppView<AppInfoWithLiveness> appView,
ClassNamingStrategy classNamingStrategy,
- PackageNamingStrategy packageNamingStrategy,
Iterable<? extends DexClass> classes) {
this.appView = appView;
this.classNamingStrategy = classNamingStrategy;
- this.packageNamingStrategy = packageNamingStrategy;
this.classes = classes;
InternalOptions options = appView.options();
this.keepInnerClassStructure = options.keepInnerClassStructure();
// Initialize top-level naming state.
topLevelState = new Namespace("");
- String newPackageDescriptor =
- StringUtils.replaceAll(options.getProguardConfiguration().getPackagePrefix(), ".", "/");
- if (!newPackageDescriptor.isEmpty()) {
- registerPackagePrefixesAsUsed(newPackageDescriptor);
- }
states.put("", topLevelState);
if (options.getProguardConfiguration().hasDontUseMixedCaseClassnames()) {
@@ -78,7 +66,6 @@
allowMixedCaseNaming = true;
isUsed = usedTypeNames::contains;
}
- keepPackageNames = options.getProguardConfiguration().getKeepPackageNamesPatterns();
}
private void setUsedTypeName(String typeName) {
@@ -176,8 +163,6 @@
private void registerClassAsUsed(DexType type, DexString descriptor) {
renaming.put(type, descriptor);
- registerPackagePrefixesAsUsed(
- getParentPackagePrefix(getClassBinaryNameFromDescriptor(descriptor.toSourceString())));
setUsedTypeName(descriptor.toString());
if (keepInnerClassStructure) {
DexType outerClass = getOutClassForType(type);
@@ -192,16 +177,6 @@
}
}
- /** Registers the given package prefix and all of parent packages as used. */
- private void registerPackagePrefixesAsUsed(String packagePrefix) {
- String usedPrefix = packagePrefix;
- while (usedPrefix.length() > 0) {
- usedPackagePrefixes.add(usedPrefix);
- states.computeIfAbsent(usedPrefix, Namespace::new);
- usedPrefix = getParentPackagePrefix(usedPrefix);
- }
- }
-
private DexType getOutClassForType(DexType type) {
DexClass clazz = appView.definitionFor(type);
if (clazz == null) {
@@ -249,29 +224,8 @@
private Namespace getStateForClass(DexType type) {
String packageName = getPackageBinaryNameFromJavaType(type.getPackageDescriptor());
- // Check whether the given class should be kept.
- // or check whether the given class belongs to a package that is kept for another class.
- if (keepPackageNames.matches(type)) {
- return states.computeIfAbsent(packageName, Namespace::new);
- }
- return getStateForPackagePrefix(packageName);
- }
-
- private Namespace getStateForPackagePrefix(String prefix) {
- Namespace state = states.get(prefix);
- if (state == null) {
- // Calculate the parent package prefix, e.g., La/b/c -> La/b
- String parentPackage = getParentPackagePrefix(prefix);
- // Create a state for parent package prefix, if necessary, in a recursive manner.
- // That recursion should end when the parent package hits the top-level, "".
- Namespace superState = getStateForPackagePrefix(parentPackage);
- // From the super state, get a renamed package prefix for the current level.
- String renamedPackagePrefix = superState.nextPackagePrefix();
- // Create a new state, which corresponds to a new name space, for the current level.
- state = new Namespace(renamedPackagePrefix);
- states.put(prefix, state);
- }
- return state;
+ // Packages are repackaged and obfuscated when doing repackaging.
+ return states.computeIfAbsent(packageName, Namespace::new);
}
private Namespace getStateForOuterClass(DexType outer, String innerClassSeparator) {
@@ -326,13 +280,6 @@
return candidate;
}
- String nextPackagePrefix() {
- String next = packageNamingStrategy.next(packagePrefix, this, usedPackagePrefixes::contains);
- assert !usedPackagePrefixes.contains(next);
- usedPackagePrefixes.add(next);
- return next;
- }
-
@Override
public int getDictionaryIndex() {
return dictionaryIndex;
@@ -344,8 +291,7 @@
}
@Override
- public int incrementNameIndex(boolean isDirectMethodCall) {
- assert !isDirectMethodCall;
+ public int incrementNameIndex() {
return nameIndex++;
}
}
@@ -368,10 +314,6 @@
boolean isRenamedByApplyMapping(DexType type);
}
- protected interface PackageNamingStrategy {
- String next(char[] packagePrefix, InternalNamingState state, Predicate<String> isUsed);
- }
-
/**
* Compute parent package prefix from the given package prefix.
*
diff --git a/src/main/java/com/android/tools/r8/naming/FieldNamingState.java b/src/main/java/com/android/tools/r8/naming/FieldNamingState.java
index 35e3d3f..9e99065 100644
--- a/src/main/java/com/android/tools/r8/naming/FieldNamingState.java
+++ b/src/main/java/com/android/tools/r8/naming/FieldNamingState.java
@@ -114,8 +114,7 @@
}
@Override
- public int incrementNameIndex(boolean isDirectMethodCall) {
- assert !isDirectMethodCall;
+ public int incrementNameIndex() {
return nextNameIndex++;
}
}
diff --git a/src/main/java/com/android/tools/r8/naming/InternalNamingState.java b/src/main/java/com/android/tools/r8/naming/InternalNamingState.java
index e5749c1..9cbacda 100644
--- a/src/main/java/com/android/tools/r8/naming/InternalNamingState.java
+++ b/src/main/java/com/android/tools/r8/naming/InternalNamingState.java
@@ -10,5 +10,5 @@
int incrementDictionaryIndex();
- int incrementNameIndex(boolean isDirectMethodCall);
+ int incrementNameIndex();
}
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 51c3272..4a50244 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 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/MethodNamingState.java b/src/main/java/com/android/tools/r8/naming/MethodNamingState.java
index 5aa368b..922c062 100644
--- a/src/main/java/com/android/tools/r8/naming/MethodNamingState.java
+++ b/src/main/java/com/android/tools/r8/naming/MethodNamingState.java
@@ -185,7 +185,7 @@
}
@Override
- public int incrementNameIndex(boolean isDirectMethodCall) {
+ public int incrementNameIndex() {
assert checkParentPublicNameCountIsLessThanOrEqual();
return nameCount++;
}
diff --git a/src/main/java/com/android/tools/r8/naming/Minifier.java b/src/main/java/com/android/tools/r8/naming/Minifier.java
index a542a2f..c5b8ced 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -20,7 +20,6 @@
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.naming.ClassNameMinifier.ClassNamingStrategy;
import com.android.tools.r8.naming.ClassNameMinifier.ClassRenaming;
-import com.android.tools.r8.naming.ClassNameMinifier.PackageNamingStrategy;
import com.android.tools.r8.naming.FieldNameMinifier.FieldRenaming;
import com.android.tools.r8.naming.MethodNameMinifier.MethodRenaming;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -55,7 +54,6 @@
new ClassNameMinifier(
appView,
new MinificationClassNamingStrategy(appView),
- new MinificationPackageNamingStrategy(appView),
// Use deterministic class order to make sure renaming is deterministic.
appView.appInfo().classesWithDeterministicOrder());
ClassRenaming classRenaming = classNameMinifier.computeRenaming(timing);
@@ -106,14 +104,15 @@
private final MixedCasing mixedCasing;
BaseMinificationNamingStrategy(List<String> obfuscationDictionary, boolean dontUseMixedCasing) {
+ assert obfuscationDictionary != null;
this.obfuscationDictionary = obfuscationDictionary;
- this.obfuscationDictionaryForLookup = new HashSet<>(this.obfuscationDictionary);
+ this.obfuscationDictionaryForLookup = new HashSet<>(obfuscationDictionary);
this.mixedCasing =
dontUseMixedCasing ? MixedCasing.DONT_USE_MIXED_CASE : MixedCasing.USE_MIXED_CASE;
- assert obfuscationDictionary != null;
}
- String nextName(char[] packagePrefix, InternalNamingState state, boolean isDirectMethodCall) {
+ /** TODO(b/182992598): using char[] could give problems with unicode */
+ String nextName(char[] packagePrefix, InternalNamingState state) {
StringBuilder nextName = new StringBuilder();
nextName.append(packagePrefix);
String nextString;
@@ -123,8 +122,7 @@
} else {
do {
nextString =
- SymbolGenerationUtils.numberToIdentifier(
- state.incrementNameIndex(isDirectMethodCall), mixedCasing);
+ SymbolGenerationUtils.numberToIdentifier(state.incrementNameIndex(), mixedCasing);
} while (obfuscationDictionaryForLookup.contains(nextString));
}
} while (PRIMITIVE_TYPE_NAMES.contains(nextString));
@@ -153,7 +151,7 @@
String candidate = null;
String lastName = null;
do {
- String newName = nextName(packagePrefix, state, false) + ";";
+ String newName = nextName(packagePrefix, state) + ";";
if (newName.equals(lastName)) {
throw new CompilationError(
"Generating same name '"
@@ -187,24 +185,44 @@
}
}
- static class MinificationPackageNamingStrategy extends BaseMinificationNamingStrategy
- implements PackageNamingStrategy {
+ public static class MinificationPackageNamingStrategy extends BaseMinificationNamingStrategy {
- MinificationPackageNamingStrategy(AppView<?> appView) {
+ private final InternalNamingState namingState =
+ new InternalNamingState() {
+
+ private int dictionaryIndex = 0;
+ private int nameIndex = 1;
+
+ @Override
+ public int getDictionaryIndex() {
+ return dictionaryIndex;
+ }
+
+ @Override
+ public int incrementDictionaryIndex() {
+ return dictionaryIndex++;
+ }
+
+ @Override
+ public int incrementNameIndex() {
+ return nameIndex++;
+ }
+ };
+
+ public MinificationPackageNamingStrategy(AppView<?> appView) {
super(
appView.options().getProguardConfiguration().getPackageObfuscationDictionary(),
appView.options().getProguardConfiguration().hasDontUseMixedCaseClassnames());
}
- @Override
- public String next(char[] packagePrefix, InternalNamingState state, Predicate<String> isUsed) {
+ public String next(String packagePrefix, Predicate<String> isUsed) {
// Note that the differences between this method and the other variant for class renaming are
// 1) this one uses the different dictionary and counter,
// 2) this one does not append ';' at the end, and
- // 3) this one removes 'L' at the beginning to make the return value a binary form.
+ // 3) this one assumes no 'L' at the beginning to make the return value a binary form.
String nextPackageName;
do {
- nextPackageName = nextName(packagePrefix, state, false).substring(1);
+ nextPackageName = nextName(packagePrefix.toCharArray(), namingState);
} while (isUsed.test(nextPackageName));
return nextPackageName;
}
@@ -230,10 +248,9 @@
InternalNamingState internalState,
BiPredicate<DexString, DexMethod> isAvailable) {
assert checkAllowMemberRenaming(method.getHolderType());
- boolean isDirectOrStatic = method.isDirectMethod() || method.isStatic();
DexString candidate;
do {
- candidate = getNextName(internalState, isDirectOrStatic);
+ candidate = getNextName(internalState);
} while (!isAvailable.test(candidate, method.getReference()));
return candidate;
}
@@ -246,13 +263,13 @@
assert checkAllowMemberRenaming(field.getHolderType());
DexString candidate;
do {
- candidate = getNextName(internalState, false);
+ candidate = getNextName(internalState);
} while (!isAvailable.test(candidate, field));
return candidate;
}
- private DexString getNextName(InternalNamingState internalState, boolean isDirectOrStatic) {
- return factory.createString(nextName(EMPTY_CHAR_ARRAY, internalState, isDirectOrStatic));
+ private DexString getNextName(InternalNamingState internalState) {
+ return factory.createString(nextName(EMPTY_CHAR_ARRAY, internalState));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
index a8e299a..3b2c0d5 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
@@ -29,7 +29,6 @@
import com.android.tools.r8.naming.MemberNaming.Signature;
import com.android.tools.r8.naming.MethodNameMinifier.MethodRenaming;
import com.android.tools.r8.naming.Minifier.MinificationClassNamingStrategy;
-import com.android.tools.r8.naming.Minifier.MinificationPackageNamingStrategy;
import com.android.tools.r8.naming.Minifier.MinifierMemberNamingStrategy;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -137,11 +136,6 @@
appView,
new ApplyMappingClassNamingStrategy(
appView, mappedNames, seedMapper.getMappedToDescriptorNames()),
- // The package naming strategy will actually not be used since all classes and methods
- // will be output with identity name if not found in mapping. However, there is a check
- // in the ClassNameMinifier that the strategy should produce a "fresh" name so we just
- // use the existing strategy.
- new MinificationPackageNamingStrategy(appView),
classesWithDeterministicOrder(mappedClasses));
ClassRenaming classRenaming = classNameMinifier.computeRenaming(timing);
timing.end();
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 0000000..b0a13ba
--- /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 c1c5105..cb0708f 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 @@
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 @@
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/repackaging/Repackaging.java b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
index 056abce..c6612c5 100644
--- a/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
+++ b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.graph.ProgramPackageCollection;
import com.android.tools.r8.graph.SortedProgramPackageCollection;
import com.android.tools.r8.graph.TreeFixerBase;
+import com.android.tools.r8.naming.Minifier.MinificationPackageNamingStrategy;
import com.android.tools.r8.repackaging.RepackagingLens.Builder;
import com.android.tools.r8.shaking.AnnotationFixer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -35,6 +36,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -202,19 +204,17 @@
Iterator<ProgramPackage> iterator = packages.iterator();
while (iterator.hasNext()) {
ProgramPackage pkg = iterator.next();
- String newPackageDescriptor =
- repackagingConfiguration.getNewPackageDescriptor(pkg, seenPackageDescriptors);
- if (pkg.getPackageDescriptor().equals(newPackageDescriptor)) {
+ if (repackagingConfiguration.isPackageInTargetLocation(pkg)) {
for (DexProgramClass alreadyRepackagedClass : pkg) {
if (!appView.appInfo().isRepackagingAllowed(alreadyRepackagedClass)) {
mappings.put(alreadyRepackagedClass.getType(), alreadyRepackagedClass.getType());
}
}
for (DexProgramClass alreadyRepackagedClass : pkg) {
- processClass(alreadyRepackagedClass, pkg, newPackageDescriptor, mappings);
+ processClass(alreadyRepackagedClass, pkg, pkg.getPackageDescriptor(), mappings);
}
- packageMappings.put(pkg.getPackageDescriptor(), newPackageDescriptor);
- seenPackageDescriptors.add(newPackageDescriptor);
+ packageMappings.put(pkg.getPackageDescriptor(), pkg.getPackageDescriptor());
+ seenPackageDescriptors.add(pkg.getPackageDescriptor());
iterator.remove();
}
}
@@ -228,15 +228,28 @@
ExecutorService executorService)
throws ExecutionException {
// For each package, find the set of classes that can be repackaged, and move them to the
- // desired package.
+ // desired package. We iterate all packages first to see if any classes are pinned and cannot
+ // be moved, to properly reserve their package.
+ Map<ProgramPackage, Collection<DexProgramClass>> packagesWithClassesToRepackage =
+ new IdentityHashMap<>();
for (ProgramPackage pkg : packages) {
+ Collection<DexProgramClass> classesToRepackage =
+ computeClassesToRepackage(pkg, executorService);
+ packagesWithClassesToRepackage.put(pkg, classesToRepackage);
+ // Reserve the package name to ensure that we are not renaming to a package we cannot move.
+ if (classesToRepackage.size() != pkg.classesInPackage().size()) {
+ seenPackageDescriptors.add(pkg.getPackageDescriptor());
+ }
+ }
+ for (ProgramPackage pkg : packages) {
+ Collection<DexProgramClass> classesToRepackage = packagesWithClassesToRepackage.get(pkg);
+ if (classesToRepackage.isEmpty()) {
+ continue;
+ }
// Already processed packages should have been removed.
String newPackageDescriptor =
repackagingConfiguration.getNewPackageDescriptor(pkg, seenPackageDescriptors);
- assert !pkg.getPackageDescriptor().equals(newPackageDescriptor);
-
- Collection<DexProgramClass> classesToRepackage =
- computeClassesToRepackage(pkg, executorService);
+ assert !repackagingConfiguration.isPackageInTargetLocation(pkg);
for (DexProgramClass classToRepackage : classesToRepackage) {
processClass(classToRepackage, pkg, newPackageDescriptor, mappings);
}
@@ -249,8 +262,6 @@
classesToRepackage.size() == pkg.classesInPackage().size()
? newPackageDescriptor
: pkg.getPackageDescriptor());
- // TODO(b/165783399): Investigate if repackaging can lead to different dynamic dispatch. See,
- // for example, CrossPackageInvokeSuperToPackagePrivateMethodTest.
}
}
@@ -298,6 +309,8 @@
String getNewPackageDescriptor(ProgramPackage pkg, Set<String> seenPackageDescriptors);
+ boolean isPackageInTargetLocation(ProgramPackage pkg);
+
DexType getRepackagedType(
DexProgramClass clazz,
DexProgramClass outerClass,
@@ -310,12 +323,13 @@
private final AppView<?> appView;
private final DexItemFactory dexItemFactory;
private final ProguardConfiguration proguardConfiguration;
- public static final String TEMPORARY_PACKAGE_NAME = "TEMPORARY_PACKAGE_NAME_FOR_";
+ private final MinificationPackageNamingStrategy packageMinificationStrategy;
public DefaultRepackagingConfiguration(AppView<?> appView) {
this.appView = appView;
this.dexItemFactory = appView.dexItemFactory();
this.proguardConfiguration = appView.options().getProguardConfiguration();
+ this.packageMinificationStrategy = new MinificationPackageNamingStrategy(appView);
}
@Override
@@ -326,13 +340,7 @@
proguardConfiguration.getPackageObfuscationMode();
if (packageObfuscationMode.isRepackageClasses()) {
return newPackageDescriptor;
- }
- assert packageObfuscationMode.isFlattenPackageHierarchy()
- || packageObfuscationMode.isMinification();
- if (!newPackageDescriptor.isEmpty()) {
- newPackageDescriptor += DESCRIPTOR_PACKAGE_SEPARATOR;
- }
- if (packageObfuscationMode.isMinification()) {
+ } else if (packageObfuscationMode.isMinification()) {
assert !proguardConfiguration.hasApplyMappingFile();
// Always keep top-level classes since there packages can never be minified.
if (pkg.getPackageDescriptor().equals("")
@@ -340,18 +348,37 @@
|| mayHavePinnedPackagePrivateOrProtectedItem(pkg)) {
return pkg.getPackageDescriptor();
}
- // For us to rename shaking/A to a/a if we have a class shaking/Kept, we have to propose
- // a different name than the last package name - the class will be minified in
- // ClassNameMinifier.
- newPackageDescriptor += TEMPORARY_PACKAGE_NAME + pkg.getLastPackageName();
+ // Plain minification do not support using a specified package prefix.
+ newPackageDescriptor = "";
} else {
- newPackageDescriptor += pkg.getLastPackageName();
+ assert packageObfuscationMode.isFlattenPackageHierarchy();
+ if (!newPackageDescriptor.isEmpty()) {
+ newPackageDescriptor += DESCRIPTOR_PACKAGE_SEPARATOR;
+ }
}
- String finalPackageDescriptor = newPackageDescriptor;
- for (int i = 1; seenPackageDescriptors.contains(finalPackageDescriptor); i++) {
- finalPackageDescriptor = newPackageDescriptor + INNER_CLASS_SEPARATOR + i;
+ return packageMinificationStrategy.next(
+ newPackageDescriptor, seenPackageDescriptors::contains);
+ }
+
+ @Override
+ public boolean isPackageInTargetLocation(ProgramPackage pkg) {
+ String newPackageDescriptor =
+ DescriptorUtils.getBinaryNameFromJavaType(proguardConfiguration.getPackagePrefix());
+ PackageObfuscationMode packageObfuscationMode =
+ proguardConfiguration.getPackageObfuscationMode();
+ if (packageObfuscationMode.isRepackageClasses()) {
+ return pkg.getPackageDescriptor().equals(newPackageDescriptor);
+ } else if (packageObfuscationMode.isMinification()) {
+ // Always keep top-level classes since there packages can never be minified.
+ return pkg.getPackageDescriptor().equals("")
+ || proguardConfiguration.getKeepPackageNamesPatterns().matches(pkg)
+ || mayHavePinnedPackagePrivateOrProtectedItem(pkg);
+ } else {
+ assert packageObfuscationMode.isFlattenPackageHierarchy();
+ // For flatten we will move the package into the package specified by the prefix so we can
+ // always minify the last part.
+ return false;
}
- return finalPackageDescriptor;
}
private boolean mayHavePinnedPackagePrivateOrProtectedItem(ProgramPackage pkg) {
@@ -400,7 +427,7 @@
}
// Ensure that the generated name is unique.
DexType finalRepackagedDexType = repackagedDexType;
- for (int i = 1; mappings.inverse().containsKey(finalRepackagedDexType); i++) {
+ for (int i = 1; isRepackageTypeUsed(finalRepackagedDexType, mappings, appView); i++) {
finalRepackagedDexType =
repackagedDexType.addSuffix(
Character.toString(INNER_CLASS_SEPARATOR) + i, dexItemFactory);
@@ -409,6 +436,12 @@
}
}
+ private static boolean isRepackageTypeUsed(
+ DexType type, BiMap<DexType, DexType> mappings, AppView<?> appView) {
+ return mappings.inverse().containsKey(type)
+ || (appView.hasLiveness() && appView.withLiveness().appInfo().wasPruned(type));
+ }
+
/** Testing only. */
public static class SuffixRenamingRepackagingConfiguration implements RepackagingConfiguration {
@@ -428,6 +461,11 @@
}
@Override
+ public boolean isPackageInTargetLocation(ProgramPackage pkg) {
+ return true;
+ }
+
+ @Override
public DexType getRepackagedType(
DexProgramClass clazz,
DexProgramClass outerClass,
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 331466b..86c8ef6 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -10,6 +10,8 @@
import static com.android.tools.r8.naming.IdentifierNameStringUtils.identifyIdentifier;
import static com.android.tools.r8.naming.IdentifierNameStringUtils.isReflectionMethod;
import static com.android.tools.r8.shaking.AnnotationRemover.shouldKeepAnnotation;
+import static com.android.tools.r8.utils.FunctionUtils.ignoreArgument;
+import static java.util.Collections.emptySet;
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.cf.code.CfInstruction;
@@ -114,7 +116,6 @@
import com.android.tools.r8.utils.Action;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.IteratorUtils;
-import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.OptionalBool;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.SetUtils;
@@ -136,11 +137,9 @@
import java.lang.reflect.InvocationHandler;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -148,6 +147,7 @@
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -351,9 +351,9 @@
/** A set of methods that need code inspection for Java reflection in use. */
private final ProgramMethodSet pendingReflectiveUses = ProgramMethodSet.createLinked();
- /** Mapping of types to the methods reachable at that type. */
- private final Map<DexProgramClass, Set<DexMethod>> reachableVirtualTargets =
- new IdentityHashMap<>();
+ /** Mapping of types to the resolved methods for that type along with the context. */
+ private final Map<DexProgramClass, Map<ResolutionSearchKey, Set<DexProgramClass>>>
+ reachableVirtualTargets = new IdentityHashMap<>();
/** Collection of keep requirements for the program. */
private final MutableKeepInfoCollection keepInfo = new MutableKeepInfoCollection();
@@ -2342,16 +2342,14 @@
private void transitionMethodsForInstantiatedLambda(LambdaDescriptor lambda) {
transitionMethodsForInstantiatedObject(
- InstantiatedObject.of(lambda),
- appInfo().definitionFor(appInfo.dexItemFactory().objectType),
- lambda.interfaces);
+ InstantiatedObject.of(lambda), appInfo.dexItemFactory().objectType, lambda.interfaces);
}
private void transitionMethodsForInstantiatedClass(DexProgramClass clazz) {
assert !clazz.isAnnotation();
assert !clazz.isInterface();
transitionMethodsForInstantiatedObject(
- InstantiatedObject.of(clazz), clazz, Collections.emptyList());
+ InstantiatedObject.of(clazz), clazz.type, Collections.emptyList());
}
/**
@@ -2362,102 +2360,66 @@
* methods are considered reachable.
*/
private void transitionMethodsForInstantiatedObject(
- InstantiatedObject instantiation, DexClass clazz, List<DexType> interfaces) {
- Set<Wrapper<DexMethod>> seen = new HashSet<>();
- WorkList<DexType> worklist = WorkList.newIdentityWorkList();
+ InstantiatedObject instantiation, DexType type, List<DexType> interfaces) {
+ WorkList<DexType> worklist = WorkList.newIdentityWorkList(type);
worklist.addIfNotSeen(interfaces);
- // First we lookup and mark all targets on the instantiated class for each reachable method in
- // the super chain (inclusive).
- DexClass initialClass = clazz;
- while (clazz != null) {
+ while (worklist.hasNext()) {
+ DexClass clazz = appInfo().definitionFor(worklist.next());
+ if (clazz == null) {
+ continue;
+ }
if (clazz.isProgramClass()) {
- markProgramMethodOverridesAsLive(instantiation, initialClass, clazz.asProgramClass(), seen);
+ markProgramMethodOverridesAsLive(instantiation, clazz.asProgramClass());
} else {
markLibraryAndClasspathMethodOverridesAsLive(instantiation, clazz);
}
+ if (clazz.superType != null) {
+ worklist.addIfNotSeen(clazz.superType);
+ }
worklist.addIfNotSeen(clazz.interfaces);
- clazz = clazz.superType != null ? appInfo().definitionFor(clazz.superType) : null;
- }
- // The targets for methods on the type and its supertype that are reachable are now marked.
- // In a second step, we look at interfaces. We order the search this way such that a
- // method reachable on a class takes precedence when reporting edges. That order mirrors JVM
- // resolution/dispatch.
- while (worklist.hasNext()) {
- DexType type = worklist.next();
- DexClass iface = appInfo().definitionFor(type);
- if (iface == null) {
- continue;
- }
- assert iface.superType == appInfo.dexItemFactory().objectType;
- if (iface.isNotProgramClass()) {
- markLibraryAndClasspathMethodOverridesAsLive(instantiation, iface);
- } else {
- markProgramMethodOverridesAsLive(instantiation, initialClass, iface.asProgramClass(), seen);
- }
- worklist.addIfNotSeen(Arrays.asList(iface.interfaces.values));
}
}
- private Set<DexMethod> getReachableVirtualTargets(DexProgramClass clazz) {
- return reachableVirtualTargets.getOrDefault(clazz, Collections.emptySet());
+ private Map<ResolutionSearchKey, Set<DexProgramClass>> getReachableVirtualTargets(
+ DexProgramClass clazz) {
+ return reachableVirtualTargets.getOrDefault(clazz, Collections.emptyMap());
}
private void markProgramMethodOverridesAsLive(
- InstantiatedObject instantiation,
- DexClass initialClass,
- DexProgramClass superClass,
- Set<Wrapper<DexMethod>> seenMethods) {
- for (DexMethod method : getReachableVirtualTargets(superClass)) {
- assert method.holder == superClass.type;
- Wrapper<DexMethod> signature = MethodSignatureEquivalence.get().wrap(method);
- if (!seenMethods.contains(signature)) {
- SingleResolutionResult resolution =
- appInfo.resolveMethodOn(superClass, method).asSingleResolution();
- assert resolution != null;
- assert resolution.getResolvedHolder().isProgramClass();
- if (resolution != null) {
- if (!initialClass.isProgramClass()
- || resolution
- .isAccessibleForVirtualDispatchFrom(initialClass.asProgramClass(), appInfo)
- .isTrue()) {
- seenMethods.add(signature);
- }
- if (resolution.getResolvedHolder().isProgramClass()) {
- markLiveOverrides(
- instantiation, superClass, resolution.getResolutionPair().asProgramMethod());
- }
- }
- }
- }
- }
-
- private void markLiveOverrides(
- InstantiatedObject instantiation,
- DexProgramClass initialHolder,
- ProgramMethod resolutionMethod) {
- // The validity of the reachable method is checked at the point it becomes "reachable" and is
- // resolved. If the method is private, then the dispatch is not "virtual" and the method is
- // simply marked live on its holder.
- if (resolutionMethod.getDefinition().isPrivateMethod()) {
- markVirtualMethodAsLive(
- resolutionMethod,
- graphReporter.reportReachableMethodAsLive(
- resolutionMethod.getDefinition().getReference(), resolutionMethod));
- return;
- }
- // Otherwise, we set the initial holder type to be the holder of the reachable method, which
- // ensures that access will be generally valid.
- SingleResolutionResult resolution =
- new SingleResolutionResult(
- initialHolder, resolutionMethod.getHolder(), resolutionMethod.getDefinition());
- LookupTarget lookup = resolution.lookupVirtualDispatchTarget(instantiation, appInfo);
- if (lookup != null) {
- markVirtualDispatchTargetAsLive(
- lookup,
- programMethod ->
- graphReporter.reportReachableMethodAsLive(
- resolutionMethod.getDefinition().getReference(), programMethod));
- }
+ InstantiatedObject instantiation, DexProgramClass currentClass) {
+ assert instantiation.isLambda()
+ || appInfo.isSubtype(instantiation.asClass().getType(), currentClass.type);
+ getReachableVirtualTargets(currentClass)
+ .forEach(
+ (resolutionSearchKey, contexts) -> {
+ SingleResolutionResult singleResolution =
+ appInfo
+ .resolveMethod(resolutionSearchKey.method, resolutionSearchKey.isInterface)
+ .asSingleResolution();
+ if (singleResolution == null) {
+ assert false : "Should not be null";
+ return;
+ }
+ contexts.forEach(
+ context ->
+ singleResolution
+ .lookupVirtualDispatchTargets(
+ context,
+ appInfo,
+ (type, subTypeConsumer, lambdaConsumer) -> {
+ assert appInfo.isSubtype(currentClass.type, type);
+ instantiation.apply(subTypeConsumer, lambdaConsumer);
+ },
+ definition -> keepInfo.isPinned(definition.getReference(), appInfo))
+ .forEach(
+ target ->
+ markVirtualDispatchTargetAsLive(
+ target,
+ programMethod ->
+ graphReporter.reportReachableMethodAsLive(
+ singleResolution.getResolvedMethod().getReference(),
+ programMethod))));
+ });
}
private void markLibraryAndClasspathMethodOverridesAsLive(
@@ -2798,8 +2760,13 @@
return;
}
- // If the method has already been marked, just report the new reason for the resolved target.
- if (getReachableVirtualTargets(holder).contains(method)) {
+ DexProgramClass contextHolder = context.getContextClass();
+ // If the method has already been marked, just report the new reason for the resolved target and
+ // save the context to ensure correct lookup of virtual dispatch targets.
+ ResolutionSearchKey resolutionSearchKey = new ResolutionSearchKey(method, interfaceInvoke);
+ Set<DexProgramClass> seenContexts = getReachableVirtualTargets(holder).get(resolutionSearchKey);
+ if (seenContexts != null) {
+ seenContexts.add(contextHolder);
graphReporter.registerMethod(resolution.getResolvedMethod(), reason);
return;
}
@@ -2813,15 +2780,16 @@
DexProgramClass resolvedHolder = resolution.getResolvedHolder().asProgramClass();
DexEncodedMethod resolvedMethod = resolution.getResolvedMethod();
markMethodAsTargeted(new ProgramMethod(resolvedHolder, resolvedMethod), reason);
-
- DexProgramClass contextHolder = context.getContextClass();
if (resolution.isAccessibleForVirtualDispatchFrom(contextHolder, appInfo).isFalse()) {
// Not accessible from this context, so this call will cause a runtime exception.
return;
}
// The method resolved and is accessible, so currently live overrides become live.
- reachableVirtualTargets.computeIfAbsent(holder, k -> Sets.newIdentityHashSet()).add(method);
+ reachableVirtualTargets
+ .computeIfAbsent(holder, ignoreArgument(HashMap::new))
+ .computeIfAbsent(resolutionSearchKey, ignoreArgument(Sets::newIdentityHashSet))
+ .add(contextHolder);
resolution
.lookupVirtualDispatchTargets(
@@ -3347,7 +3315,7 @@
rootSet.noHorizontalClassMerging,
rootSet.neverPropagateValue,
joinIdentifierNameStrings(rootSet.identifierNameStrings, identifierNameStrings),
- Collections.emptySet(),
+ emptySet(),
Collections.emptyMap(),
lockCandidates,
initClassReferences);
@@ -3776,7 +3744,7 @@
Set<DexClass> subtypes =
objectAllocationInfoCollection.getImmediateSubtypesInInstantiatedHierarchy(clazz.type);
if (subtypes == null) {
- return Collections.emptySet();
+ return emptySet();
}
Set<DexProgramClass> programClasses = SetUtils.newIdentityHashSet(subtypes.size());
for (DexClass subtype : subtypes) {
@@ -4548,4 +4516,29 @@
return enqueuer.definitionFor(type, context, enqueuer::ignoreMissingClass);
}
}
+
+ public static class ResolutionSearchKey {
+
+ private final DexMethod method;
+ private final boolean isInterface;
+
+ private ResolutionSearchKey(DexMethod method, boolean isInterface) {
+ this.method = method;
+ this.isInterface = isInterface;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ResolutionSearchKey that = (ResolutionSearchKey) o;
+ return method == that.method && isInterface == that.isInterface;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(method, isInterface);
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/shaking/InstantiatedObject.java b/src/main/java/com/android/tools/r8/shaking/InstantiatedObject.java
index d4fe555..9c92725 100644
--- a/src/main/java/com/android/tools/r8/shaking/InstantiatedObject.java
+++ b/src/main/java/com/android/tools/r8/shaking/InstantiatedObject.java
@@ -5,6 +5,7 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.ir.desugar.LambdaDescriptor;
+import java.util.function.Consumer;
public abstract class InstantiatedObject {
@@ -16,6 +17,16 @@
return new InstantiatedLambda(lambda);
}
+ public void apply(
+ Consumer<DexProgramClass> classConsumer, Consumer<LambdaDescriptor> lambdaConsumer) {
+ if (isClass()) {
+ classConsumer.accept(asClass());
+ } else {
+ assert isLambda();
+ lambdaConsumer.accept(asLambda());
+ }
+ }
+
public boolean isClass() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/utils/FunctionUtils.java b/src/main/java/com/android/tools/r8/utils/FunctionUtils.java
index 3338dde..acd5cb3 100644
--- a/src/main/java/com/android/tools/r8/utils/FunctionUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/FunctionUtils.java
@@ -7,6 +7,7 @@
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Supplier;
public class FunctionUtils {
@@ -28,4 +29,8 @@
func.apply(t).accept(argument);
}
}
+
+ public static <T, R> Function<T, R> ignoreArgument(Supplier<R> supplier) {
+ return ignore -> supplier.get();
+ }
}
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 7a99160..83a2245 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -571,7 +571,7 @@
@Override
public boolean isRepackagingEnabled() {
return proguardConfiguration.getPackageObfuscationMode().isSome()
- && (isShrinking() || isMinifying());
+ && (isMinifying() || testing.repackageWithNoMinification);
}
@Override
@@ -1154,7 +1154,10 @@
public static class HorizontalClassMergerOptions {
- public boolean enable = true;
+ // TODO(b/138781768): Set enable to true when this bug is resolved.
+ public boolean enable =
+ !Version.isDevelopmentVersion()
+ || System.getProperty("com.android.tools.r8.disableHorizontalClassMerging") == null;
public boolean enableConstructorMerging = true;
public boolean enableJavaLambdaMerging = true;
@@ -1320,6 +1323,7 @@
// TODO(b/177333791): Set to true
public boolean checkForNotExpandingMainDexTracingResult = false;
public Set<String> allowedUnusedDontWarnPatterns = new HashSet<>();
+ public boolean repackageWithNoMinification = false;
public boolean allowConflictingSyntheticTypes = false;
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 47ccd91..f8ad5bb 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.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 @@
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 @@
}
}
+ 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/examplesJava9/stream/ProgramRewritingTestClass.java b/src/test/examplesJava9/stream/ProgramRewritingTestClass.java
index 7eedeb9..6bf4f12 100644
--- a/src/test/examplesJava9/stream/ProgramRewritingTestClass.java
+++ b/src/test/examplesJava9/stream/ProgramRewritingTestClass.java
@@ -27,11 +27,9 @@
ArrayList<Object> aList = new ArrayList<>();
Queue<Object> queue = new LinkedList<>();
LinkedHashSet<Object> lhs = new LinkedHashSet<>();
- // They both should be rewritten to invokeStatic to the dispatch class.
+ // Following should be rewritten to invokeStatic to the dispatch class.
System.out.println(set.spliterator().getClass().getName());
System.out.println("j$.util.Spliterators$IteratorSpliterator");
- System.out.println(list.spliterator().getClass().getName());
- System.out.println("j$.util.Spliterators$IteratorSpliterator");
// Following should be rewritten to invokeStatic to Collection dispatch class.
System.out.println(set.stream().getClass().getName());
System.out.println("j$.util.stream.ReferencePipeline$Head");
diff --git a/src/test/java/com/android/tools/r8/BackportedMethodListTest.java b/src/test/java/com/android/tools/r8/BackportedMethodListTest.java
index bb344d7..4ffaaa7 100644
--- a/src/test/java/com/android/tools/r8/BackportedMethodListTest.java
+++ b/src/test/java/com/android/tools/r8/BackportedMethodListTest.java
@@ -88,7 +88,7 @@
private void addLibraryDesugaring(BackportedMethodListCommand.Builder builder) {
builder
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P.getLevel()));
}
@@ -143,7 +143,7 @@
BackportedMethodList.run(
BackportedMethodListCommand.builder()
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setConsumer(new ListStringConsumer())
.build());
fail("Expected failure");
diff --git a/src/test/java/com/android/tools/r8/ExtractMarkerTest.java b/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
index 7cbcf63..6ed73d8 100644
--- a/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
@@ -129,7 +129,7 @@
DexString markerString =
factory.createString(
"~~D8{\"compilation-mode\":\"debug\",\"has-checksums\":false,"
- + "\"min-api\":21,\"sha-1\":\"engineering\",\"version\":\"master\" }");
+ + "\"min-api\":21,\"sha-1\":\"engineering\",\"version\":\"main\" }");
assertEquals("dex", Marker.parse(markerString).getBackend());
}
@@ -139,7 +139,7 @@
DexString markerString =
factory.createString(
"~~R8{\"compilation-mode\":\"release\",\"has-checksums\":true,"
- + "\"sha-1\":\"engineering\",\"version\":\"master\" }");
+ + "\"sha-1\":\"engineering\",\"version\":\"main\" }");
assertEquals("cf", Marker.parse(markerString).getBackend());
}
}
diff --git a/src/test/java/com/android/tools/r8/L8CommandTest.java b/src/test/java/com/android/tools/r8/L8CommandTest.java
index bb32740..8bb9f30 100644
--- a/src/test/java/com/android/tools/r8/L8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/L8CommandTest.java
@@ -15,19 +15,19 @@
import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
import com.android.tools.r8.AssertionsConfiguration.AssertionTransformationScope;
-import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.StringConsumer.FileConsumer;
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.utils.AndroidApiLevel;
import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.ImmutableList;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
@@ -58,7 +58,7 @@
L8Command.builder()
.setProgramConsumer(DexIndexedConsumer.emptyConsumer())
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.build());
}
@@ -79,7 +79,7 @@
.addProgramFiles(ToolHelper.getDesugarJDKLibs())
.setMinApiLevel(20)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setOutput(output, OutputMode.DexIndexed)
.build());
assertMarkersMatch(
@@ -96,7 +96,7 @@
.addProgramFiles(ToolHelper.getDesugarJDKLibs())
.setMinApiLevel(20)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setOutput(output, OutputMode.ClassFile)
.build());
assertMarkersMatch(ExtractMarker.extractMarkerFromDexFile(output), markerTool(Tool.L8));
@@ -113,11 +113,10 @@
"--min-api",
"20",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString(),
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
"--output",
output.toString());
L8.run(l8Command);
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
assertMarkersMatch(
ExtractMarker.extractMarkerFromDexFile(output),
ImmutableList.of(markerTool(Tool.L8), markerTool(Tool.D8)));
@@ -134,7 +133,7 @@
"--min-api",
"20",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString(),
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
"--output",
output.toString(),
"--classfile");
@@ -150,12 +149,35 @@
parse(
diagnostics,
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString(),
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
"--pg-conf",
pgconf.toString());
}
@Test
+ public void testFlagPgConfWithConsumer() throws Exception {
+ TestDiagnosticMessagesImpl diagnostics = new TestDiagnosticMessagesImpl();
+ Path pgconf = temp.newFolder().toPath().resolve("pg.conf");
+ Path pgMap = temp.newFolder().toPath().resolve("pg-map.txt");
+ FileUtils.writeTextFile(pgconf, "");
+ L8Command parsedCommand =
+ parse(
+ diagnostics,
+ "--desugared-lib",
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
+ "--pg-conf",
+ pgconf.toString(),
+ "--pg-map-output",
+ pgMap.toString());
+ assertNotNull(parsedCommand.getR8Command());
+ InternalOptions internalOptions = parsedCommand.getR8Command().getInternalOptions();
+ assertNotNull(internalOptions);
+ assertTrue(internalOptions.proguardMapConsumer instanceof StringConsumer.FileConsumer);
+ FileConsumer proguardMapConsumer = (FileConsumer) internalOptions.proguardMapConsumer;
+ assertEquals(pgMap, proguardMapConsumer.getOutputPath());
+ }
+
+ @Test
public void testFlagPgConfWithClassFile() throws Exception {
TestDiagnosticMessagesImpl diagnostics = new TestDiagnosticMessagesImpl();
try {
@@ -164,7 +186,7 @@
parse(
diagnostics,
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString(),
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
"--pg-conf",
pgconf.toString(),
"--classfile");
@@ -182,7 +204,7 @@
parse(
diagnostics,
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString(),
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
"--pg-conf");
fail("Expected parse error");
} catch (CompilationFailedException e) {
@@ -227,6 +249,29 @@
prepareBuilder(handler).setProgramConsumer(ClassFileConsumer.emptyConsumer()).build());
}
+ @Test(expected = CompilationFailedException.class)
+ public void proguardMapConsumerNotShrinking() throws Throwable {
+ DiagnosticsChecker.checkErrorsContains(
+ "L8 does not support defining a map consumer when not shrinking",
+ (handler) ->
+ prepareBuilder(handler)
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProguardMapConsumer(StringConsumer.emptyConsumer())
+ .build());
+ }
+
+ @Test(expected = CompilationFailedException.class)
+ public void proguardMapOutputNotShrinking() throws Throwable {
+ Path pgMapOut = temp.newFile("pg-out.txt").toPath();
+ DiagnosticsChecker.checkErrorsContains(
+ "L8 does not support defining a map consumer when not shrinking",
+ (handler) ->
+ prepareBuilder(handler)
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProguardMapOutputPath(pgMapOut)
+ .build());
+ }
+
private void addProguardConfigurationString(
DiagnosticsHandler diagnostics, ProgramConsumer programConsumer) throws Throwable {
String keepRule = "-keep class java.time.*";
@@ -236,7 +281,7 @@
prepareBuilder(diagnostics)
.setProgramConsumer(programConsumer)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.addProguardConfiguration(keepRules, Origin.unknown());
assertTrue(builder.isShrinking());
assertNotNull(builder.build().getR8Command());
@@ -270,7 +315,7 @@
prepareBuilder(diagnostics)
.setProgramConsumer(programConsumer)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.addProguardConfigurationFiles(keepRuleFile);
assertTrue(builder1.isShrinking());
assertNotNull(builder1.build().getR8Command());
@@ -281,7 +326,7 @@
prepareBuilder(new TestDiagnosticMessagesImpl())
.setProgramConsumer(DexIndexedConsumer.emptyConsumer())
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.addProguardConfigurationFiles(keepRuleFiles);
assertTrue(builder2.isShrinking());
assertNotNull(builder2.build().getR8Command());
@@ -308,7 +353,7 @@
@Test
public void desugaredLibrary() throws CompilationFailedException {
L8Command l8Command =
- parse("--desugared-lib", ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString());
+ parse("--desugared-lib", ToolHelper.getDesugarLibJsonForTesting().toString());
assertFalse(
l8Command.getInternalOptions().desugaredLibraryConfiguration.getRewritePrefix().isEmpty());
}
@@ -337,21 +382,21 @@
parse(
"--force-enable-assertions",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getAssertionsConfiguration(),
AssertionTransformation.ENABLE);
checkSingleForceAllAssertion(
parse(
"--force-disable-assertions",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getAssertionsConfiguration(),
AssertionTransformation.DISABLE);
checkSingleForceAllAssertion(
parse(
"--force-passthrough-assertions",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getAssertionsConfiguration(),
AssertionTransformation.PASSTHROUGH);
checkSingleForceClassAndPackageAssertion(
@@ -359,7 +404,7 @@
"--force-enable-assertions:ClassName",
"--force-enable-assertions:PackageName...",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getAssertionsConfiguration(),
AssertionTransformation.ENABLE);
checkSingleForceClassAndPackageAssertion(
@@ -367,7 +412,7 @@
"--force-disable-assertions:ClassName",
"--force-disable-assertions:PackageName...",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getAssertionsConfiguration(),
AssertionTransformation.DISABLE);
checkSingleForceClassAndPackageAssertion(
@@ -375,7 +420,7 @@
"--force-passthrough-assertions:ClassName",
"--force-passthrough-assertions:PackageName...",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getAssertionsConfiguration(),
AssertionTransformation.PASSTHROUGH);
}
@@ -384,7 +429,7 @@
public void numThreadsOption() throws Exception {
assertEquals(
ThreadUtils.NOT_SPECIFIED,
- parse("--desugared-lib", ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ parse("--desugared-lib", ToolHelper.getDesugarLibJsonForTesting().toString())
.getThreadCount());
assertEquals(
1,
@@ -392,7 +437,7 @@
"--thread-count",
"1",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getThreadCount());
assertEquals(
2,
@@ -400,7 +445,7 @@
"--thread-count",
"2",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getThreadCount());
assertEquals(
10,
@@ -408,7 +453,7 @@
"--thread-count",
"10",
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ ToolHelper.getDesugarLibJsonForTesting().toString())
.getThreadCount());
}
@@ -423,7 +468,7 @@
"--thread-count",
value,
"--desugared-lib",
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString()));
+ ToolHelper.getDesugarLibJsonForTesting().toString()));
fail("Expected failure");
} catch (CompilationFailedException e) {
// Expected.
@@ -439,7 +484,7 @@
@Override
String[] requiredArgsForTest() {
- return new String[] {"--desugared-lib", ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString()};
+ return new String[] {"--desugared-lib", ToolHelper.getDesugarLibJsonForTesting().toString()};
}
@Override
diff --git a/src/test/java/com/android/tools/r8/MarkersTest.java b/src/test/java/com/android/tools/r8/MarkersTest.java
index 1a7c92a..2ab8a16 100644
--- a/src/test/java/com/android/tools/r8/MarkersTest.java
+++ b/src/test/java/com/android/tools/r8/MarkersTest.java
@@ -66,7 +66,7 @@
.setMinApiLevel(apiLevel.getLevel())
.setMode(compilationMode)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setOutput(output, OutputMode.DexIndexed);
if (shrinkDesugaredLibrary) {
builder.addProguardConfiguration(ImmutableList.of("-keep class * { *; }"), Origin.unknown());
@@ -75,7 +75,7 @@
Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
String version =
new JsonParser()
- .parse(FileUtils.readTextFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING, Charsets.UTF_8))
+ .parse(FileUtils.readTextFile(ToolHelper.getDesugarLibJsonForTesting(), Charsets.UTF_8))
.getAsJsonObject()
.get("version")
.getAsString();
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index e9cd5ff..a6c4924 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -429,7 +429,7 @@
AndroidApiLevel minApiLevel, KeepRuleConsumer keepRuleConsumer) {
assert minApiLevel.getLevel() < AndroidApiLevel.O.getLevel();
builder.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING));
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
// TODO(b/158543446): This should not be setting an implicit library file. Doing so causes
// inconsistent library setup depending on the api level and makes tests hard to read and
// reason about.
diff --git a/src/test/java/com/android/tools/r8/TestRuntime.java b/src/test/java/com/android/tools/r8/TestRuntime.java
index 04b61c0..20bf4b8 100644
--- a/src/test/java/com/android/tools/r8/TestRuntime.java
+++ b/src/test/java/com/android/tools/r8/TestRuntime.java
@@ -83,11 +83,13 @@
return new CfRuntime(CfVm.JDK8, home);
}
- private static Path getCheckedInJdkHome(Path path) {
+ private static Path getCheckedInJdkHome(Path path, CfVm vm) {
if (ToolHelper.isLinux()) {
return path.resolve("linux");
} else if (ToolHelper.isMac()) {
- return path.resolve("osx");
+ return vm.lessThanOrEqual(CfVm.JDK9)
+ ? path.resolve("osx")
+ : path.resolve("osx/Contents/Home");
} else {
assert ToolHelper.isWindows();
return path.resolve("windows");
@@ -95,16 +97,16 @@
}
public static CfRuntime getCheckedInJdk9() {
- return new CfRuntime(CfVm.JDK9, getCheckedInJdkHome(JDK9_PATH));
+ return new CfRuntime(CfVm.JDK9, getCheckedInJdkHome(JDK9_PATH, CfVm.JDK9));
}
public static CfRuntime getCheckedInJdk11() {
- return new CfRuntime(CfVm.JDK11, getCheckedInJdkHome(JDK11_PATH));
+ return new CfRuntime(CfVm.JDK11, getCheckedInJdkHome(JDK11_PATH, CfVm.JDK11));
}
// TODO(b/169692487): Add this to 'getCheckedInCfRuntimes' when we start having support for JDK15.
public static CfRuntime getCheckedInJdk15() {
- return new CfRuntime(CfVm.JDK15, getCheckedInJdkHome(JDK15_PATH));
+ return new CfRuntime(CfVm.JDK15, getCheckedInJdkHome(JDK15_PATH, CfVm.JDK15));
}
public static List<CfRuntime> getCheckedInCfRuntimes() {
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 9d0e9b5..18037be 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -133,9 +133,6 @@
public static final String DEFAULT_PROGUARD_MAP_FILE = "proguard.map";
public static final String JAVA_8_RUNTIME = "third_party/openjdk/openjdk-rt-1.8/rt.jar";
- public static final String DESUGAR_JDK_LIBS =
- System.getProperty(
- "desugar_jdk_libs", "third_party/openjdk/desugar_jdk_libs/desugar_jdk_libs.jar");
public static final String CORE_LAMBDA_STUBS =
"third_party/core-lambda-stubs/core-lambda-stubs.jar";
public static final String JSR223_RI_JAR = "third_party/jsr223-api-1.0/jsr223-api-1.0.jar";
@@ -180,12 +177,24 @@
public static final Path DESUGAR_LIB_CONVERSIONS =
Paths.get(LIBS_DIR, "library_desugar_conversions.zip");
- public static final String DESUGAR_LIB_JSON_DIR =
- System.getProperty("desugar_jdk_json_dir", "src/library_desugar");
- public static final Path DESUGAR_LIB_JSON_FOR_TESTING =
- Paths.get(DESUGAR_LIB_JSON_DIR, "desugar_jdk_libs.json");
- public static final Path DESUGAR_LIB_JSON_FOR_TESTING_ALTERNATIVE_3 =
- Paths.get(DESUGAR_LIB_JSON_DIR, "desugar_jdk_libs_alternative_3.json");
+
+ public static Path getDesugarJDKLibs() {
+ return Paths.get(
+ System.getProperty(
+ "desugar_jdk_libs", "third_party/openjdk/desugar_jdk_libs/desugar_jdk_libs.jar"));
+ }
+
+ private static String getDesugarLibraryJsonDir() {
+ return System.getProperty("desugar_jdk_json_dir", "src/library_desugar");
+ }
+
+ public static Path getDesugarLibJsonForTesting() {
+ return Paths.get(getDesugarLibraryJsonDir(), "desugar_jdk_libs.json");
+ }
+
+ public static Path getDesugarLibJsonForTestingAlternative3() {
+ return Paths.get(getDesugarLibraryJsonDir(), "desugar_jdk_libs_alternative_3.json");
+ }
public static boolean isLocalDevelopment() {
return System.getProperty("local_development", "0").equals("1");
@@ -758,10 +767,6 @@
return Paths.get(JAVA_8_RUNTIME);
}
- public static Path getDesugarJDKLibs() {
- return Paths.get(DESUGAR_JDK_LIBS);
- }
-
public static Path getCoreLambdaStubs() {
return Paths.get(CORE_LAMBDA_STUBS);
}
diff --git a/src/test/java/com/android/tools/r8/VersionTests.java b/src/test/java/com/android/tools/r8/VersionTests.java
index dad43b9..343ea89 100644
--- a/src/test/java/com/android/tools/r8/VersionTests.java
+++ b/src/test/java/com/android/tools/r8/VersionTests.java
@@ -33,12 +33,12 @@
int minorVersion = Version.getMinorVersion();
int patchVersion = Version.getPatchVersion();
String preReleaseString = Version.getPreReleaseString();
- if (LABEL.equals("master")) {
+ if (LABEL.equals("main")) {
assertEquals(-1, majorVersion);
assertEquals(-1, minorVersion);
assertEquals(-1, patchVersion);
assertNull(preReleaseString);
- assertTrue(Version.getVersionString().startsWith("master"));
+ assertTrue(Version.getVersionString().startsWith("main"));
} else {
assertTrue(majorVersion > 0);
assertTrue(minorVersion >= 0);
@@ -59,7 +59,7 @@
@Test
public void testDevelopmentPredicate() {
- if (LABEL.equals("master") || LABEL.contains("-dev")) {
+ if (LABEL.equals("main") || LABEL.contains("-dev")) {
assertTrue(Version.isDevelopmentVersion());
} else {
// This is a release branch, but Version.isDevelopmentVersion will still return true
@@ -70,13 +70,13 @@
@Test
public void testLabelParsing() {
- assertEquals(-1, Version.getMajorVersion("master"));
- assertEquals(-1, Version.getMinorVersion("master"));
- assertEquals(-1, Version.getPatchVersion("master"));
- assertNull(Version.getPreReleaseString("master"));
- // 'master' is checked before 'isEngineering'.
- assertTrue(Version.isDevelopmentVersion("master", false));
- assertTrue(Version.isDevelopmentVersion("master", true));
+ assertEquals(-1, Version.getMajorVersion("main"));
+ assertEquals(-1, Version.getMinorVersion("main"));
+ assertEquals(-1, Version.getPatchVersion("main"));
+ assertNull(Version.getPreReleaseString("main"));
+ // 'main' is checked before 'isEngineering'.
+ assertTrue(Version.isDevelopmentVersion("main", false));
+ assertTrue(Version.isDevelopmentVersion("main", true));
assertEquals(1, Version.getMajorVersion("1.2.3-dev"));
assertEquals(2, Version.getMinorVersion("1.2.3-dev"));
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/PackagePrivateOverridePublicizerBottomTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/PackagePrivateOverridePublicizerBottomTest.java
index 6dc8328..45ddf3e 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/PackagePrivateOverridePublicizerBottomTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/PackagePrivateOverridePublicizerBottomTest.java
@@ -64,8 +64,7 @@
.enableNeverClassInliningAnnotations()
.allowAccessModification()
.run(parameters.getRuntime(), Main.class)
- // TODO(b/182185057): This is an error in the devirtualizer
- .assertSuccessWithOutputLines(EXPECTED_ART_4)
+ .apply(this::assertSuccessOutput)
.inspect(
inspector -> {
ClassSubject subViewModelSubject =
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergeWithRepackageNameCollissionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergeWithRepackageNameCollissionTest.java
new file mode 100644
index 0000000..f3772a7
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergeWithRepackageNameCollissionTest.java
@@ -0,0 +1,104 @@
+// Copyright (c) 2021, 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 com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NoHorizontalClassMerging;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runners.Parameterized;
+
+public class MergeWithRepackageNameCollissionTest extends HorizontalClassMergingTestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withDexRuntimes().withAllApiLevels().build();
+ }
+
+ public MergeWithRepackageNameCollissionTest(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(getProgramFileData())
+ .addProgramClasses(I.class, Runner.class)
+ .addKeepMainRule(Main.class)
+ .addKeepClassAndMembersRules(I.class, Runner.class)
+ .setMinApi(parameters.getApiLevel())
+ .enableNoHorizontalClassMergingAnnotations()
+ .enableInliningAnnotations()
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("C::baz", "Hello World");
+ }
+
+ private Collection<byte[]> getProgramFileData() throws Exception {
+ return ImmutableList.of(
+ transformer(A.class).setClassDescriptor("La/a;").transform(),
+ transformer(B.class).setClassDescriptor("Lb/a;").setSuper("La/a;").transform(),
+ transformer(D.class).setClassDescriptor("Lc/a;").transform(),
+ transformer(Main.class)
+ .replaceClassDescriptorInMethodInstructions(descriptor(A.class), "La/a;")
+ .replaceClassDescriptorInMethodInstructions(descriptor(B.class), "Lb/a;")
+ .replaceClassDescriptorInMethodInstructions(descriptor(D.class), "Lc/a;")
+ .transform());
+ }
+
+ public static /* will be: a.a */ class A {
+
+ @NeverInline
+ public static void foo() {
+ System.out.println("A::foo");
+ }
+ }
+
+ // a.a will be merged into b.a and thereby produce a mapping from a.a -> b.a in our lens.
+ public static /* will be: b.a */ class B extends A {}
+
+ // c.a will be repackaged to a.a
+ @NoHorizontalClassMerging
+ public static /* will be: c.a */ class D {
+
+ @NeverInline
+ public static void baz() {
+ System.out.println("C::baz");
+ }
+ }
+
+ public interface I {
+
+ void run();
+ }
+
+ public static class Runner {
+
+ @NeverInline
+ static void callI(I i) {
+ i.run();
+ }
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) {
+ D.baz();
+ callFoo(null);
+ Runner.callI(
+ () -> {
+ System.out.println("Hello World");
+ });
+ }
+
+ public static void callFoo(Object obj) {
+ if (obj != null) {
+ B.foo();
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/InvokeSuperToRewrittenDefaultMethodTest.java b/src/test/java/com/android/tools/r8/desugar/InvokeSuperToRewrittenDefaultMethodTest.java
index 93e46d0..5aa2894 100644
--- a/src/test/java/com/android/tools/r8/desugar/InvokeSuperToRewrittenDefaultMethodTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/InvokeSuperToRewrittenDefaultMethodTest.java
@@ -76,7 +76,7 @@
// TODO(b/158543446): Remove this once enableCoreLibraryDesugaring is fixed.
b.getBuilder()
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING));
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
} else {
// TODO(b/158543446): Move this out to the shared builder once
// enableCoreLibraryDesugaring is fixed.
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BackwardsCompatibleSpecificationTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BackwardsCompatibleSpecificationTest.java
index 6b46ee4..a922636 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BackwardsCompatibleSpecificationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BackwardsCompatibleSpecificationTest.java
@@ -28,7 +28,7 @@
}
private final Path desugaredLib = ToolHelper.getDesugarJDKLibs();
- private final Path desugaredSpec = ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING;
+ private final Path desugaredSpec = ToolHelper.getDesugarLibJsonForTesting();
private final String release;
public BackwardsCompatibleSpecificationTest(TestParameters parameters, String release) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
index f71c916..5cc22b7 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
@@ -69,7 +69,7 @@
options.reporter,
libraryCompilation,
parameters.getApiLevel().getLevel())
- .parse(StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING_ALTERNATIVE_3));
+ .parse(StringResource.fromFile(ToolHelper.getDesugarLibJsonForTestingAlternative3()));
}
private void configurationForProgramCompilation(InternalOptions options) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/CustomCollectionTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/CustomCollectionTest.java
index 19cd88f..514742c 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/CustomCollectionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/CustomCollectionTest.java
@@ -223,8 +223,9 @@
System.out.println(ccollection.spliterator().getClass().getName());
System.out.println("j$.util.Spliterators$IteratorSpliterator");
+ // See SpliteratorTest for the concrete class name.
System.out.println(cArrayList.spliterator().getClass().getName());
- System.out.println("j$.util.Spliterators$IteratorSpliterator");
+ System.out.println(new ArrayList<>().spliterator().getClass().getName());
System.out.println(cSortedSet.spliterator().getClass().getName());
System.out.println("j$.util.SortedSet$1");
System.out.println(customSortedSetWithReverseChain.spliterator().getClass().getName());
@@ -264,7 +265,8 @@
System.out.println(ccollection.spliterator().getClass().getName());
System.out.println("j$.util.Spliterators$IteratorSpliterator");
System.out.println(cArrayList.spliterator().getClass().getName());
- System.out.println("j$.util.Spliterators$IteratorSpliterator");
+ // See SpliteratorTest for the concrete class name.
+ System.out.println(new ArrayList<>().spliterator().getClass().getName());
System.out.println(cSortedSet.spliterator().getClass().getName());
System.out.println("j$.util.SortedSet$1");
System.out.println(customSortedSetWithReverseChain.spliterator().getClass().getName());
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryChecksumsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryChecksumsTest.java
index 6aff20f..bcefe74 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryChecksumsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryChecksumsTest.java
@@ -43,7 +43,7 @@
.addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
.setMode(CompilationMode.DEBUG)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(AndroidApiLevel.B.getLevel())
.setOutput(out, OutputMode.DexIndexed)
.build());
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryConfigurationParsingTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryConfigurationParsingTest.java
index 12ed820..348351b 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryConfigurationParsingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryConfigurationParsingTest.java
@@ -115,7 +115,7 @@
public void testReference() throws Exception {
// Just test that the reference file parses without issues.
DesugaredLibraryConfiguration config =
- runPassing(StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING));
+ runPassing(StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
assertEquals(libraryCompilation, config.isLibraryCompilation());
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryContentTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryContentTest.java
index d99b31f..02d036c 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryContentTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryContentTest.java
@@ -70,7 +70,7 @@
.addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
.addLibraryFiles(ToolHelper.getCoreLambdaStubs())
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(parameters.getApiLevel().getLevel())
.setOutput(desugaredLib, OutputMode.DexIndexed);
ToolHelper.runL8(l8Builder.build(), options -> {});
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
index 4de3828..8f1d451 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
@@ -41,12 +41,31 @@
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import org.junit.BeforeClass;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
public class DesugaredLibraryTestBase extends TestBase {
+ private static final boolean FORCE_JDK11_DESUGARED_LIB = false;
+
+ @BeforeClass
+ public static void setUpDesugaredLibrary() {
+ if (!FORCE_JDK11_DESUGARED_LIB) {
+ return;
+ }
+ System.setProperty("desugar_jdk_json_dir", "src/library_desugar/jdk11");
+ System.setProperty(
+ "desugar_jdk_libs", "third_party/openjdk/desugar_jdk_libs_11/desugar_jdk_libs.jar");
+ System.out.println("Forcing the usage of JDK11 desugared library.");
+ }
+
+ public static boolean isJDK11DesugaredLibrary() {
+ String property = System.getProperty("desugar_jdk_json_dir", "");
+ return property.contains("jdk11");
+ }
+
// For conversions tests, we need DexRuntimes where classes to convert are present (DexRuntimes
// above N and O depending if Stream or Time APIs are used), but we need to compile the program
// with a minAPI below to force the use of conversions.
@@ -124,7 +143,7 @@
.setMode(shrink ? CompilationMode.RELEASE : CompilationMode.DEBUG)
.addProgramFiles(extraPaths)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(apiLevel.getLevel())
.setOutput(desugaredLib, OutputMode.DexIndexed);
Path mapping = null;
@@ -201,7 +220,7 @@
.addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
.setMode(CompilationMode.DEBUG)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(parameters.getApiLevel().getLevel())
.setOutput(desugaredLib, OutputMode.ClassFile);
@@ -220,7 +239,7 @@
libraryCompilation,
parameters.getApiLevel().getLevel())
.parse(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING),
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()),
builder -> builder.setSupportAllCallbacksFromLibrary(supportAllCallbacksFromLibrary));
}
@@ -240,7 +259,7 @@
.addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
.setMode(CompilationMode.DEBUG)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(apiLevel.getLevel())
.setOutput(desugaredLib, OutputMode.ClassFile);
ToolHelper.runL8(l8Builder.build());
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java
index 8dd0d27..04411fb 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java
@@ -58,7 +58,7 @@
.addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
.setMode(shrinkDesugaredLibrary ? CompilationMode.RELEASE : CompilationMode.DEBUG)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(parameters.getApiLevel().getLevel())
.setOutput(desugaredLib, OutputMode.DexIndexed);
if (shrinkDesugaredLibrary) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmptyDesugaredLibrary.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmptyDesugaredLibrary.java
index 5b706e8..fc35e73 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmptyDesugaredLibrary.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmptyDesugaredLibrary.java
@@ -44,7 +44,7 @@
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
.addProgramFiles(ToolHelper.getDesugarJDKLibs())
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(minApiLevel.getLevel());
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java
index cae7a4a..9cb9cea 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java
@@ -195,7 +195,7 @@
DesugaredLibraryConfigurationParser parser =
new DesugaredLibraryConfigurationParser(
new DexItemFactory(), null, true, minApi.getLevel());
- return parser.parse(StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING));
+ return parser.parse(StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
}
private Map<ClassReference, Set<MethodReference>> getDirectlyReferencedWrapperTypes(
@@ -275,8 +275,8 @@
Path out = temp.newFolder().toPath();
GenerateLintFiles desugaredApi =
new GenerateLintFiles(
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString(),
- ToolHelper.DESUGAR_JDK_LIBS,
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
+ ToolHelper.getDesugarJDKLibs().toString(),
out.toString());
desugaredApi.run(targetApi.getLevel());
return new CodeInspector(
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/IterateTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/IterateTest.java
new file mode 100644
index 0000000..41935e4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/IterateTest.java
@@ -0,0 +1,102 @@
+// Copyright (c) 2019, 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.desugar.desugaredlibrary;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.stream.IntStream;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class IterateTest extends DesugaredLibraryTestBase {
+
+ private final TestParameters parameters;
+ private final boolean shrinkDesugaredLibrary;
+ private static final String EXPECTED_OUTPUT = StringUtils.lines("1");
+
+ @Parameters(name = "{1}, shrinkDesugaredLibrary: {0}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ BooleanUtils.values(),
+ getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build());
+ }
+
+ public IterateTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
+ this.shrinkDesugaredLibrary = shrinkDesugaredLibrary;
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testIterateD8Cf() throws Exception {
+ // Only test without shrinking desugared library.
+ Assume.assumeFalse(shrinkDesugaredLibrary);
+ // Use D8 to desugar with Java classfile output.
+ Path jar =
+ testForD8(Backend.CF)
+ .addInnerClasses(IterateTest.class)
+ .setMinApi(parameters.getApiLevel())
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
+ .compile()
+ .writeToZip();
+
+ if (parameters.getRuntime().isDex()) {
+ // Convert to DEX without desugaring and run.
+ testForD8()
+ .addProgramFiles(jar)
+ .setMinApi(parameters.getApiLevel())
+ .disableDesugaring()
+ .compile()
+ .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()))
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ } else {
+ // Run on the JVM with desugared library on classpath.
+ testForJvm()
+ .addProgramFiles(jar)
+ .addRunClasspathFiles(buildDesugaredLibraryClassFile(parameters.getApiLevel()))
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+ }
+
+ @Test
+ public void testIterate() throws Exception {
+ if (parameters.isCfRuntime()) {
+ testForJvm()
+ .addInnerClasses(IterateTest.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ return;
+ }
+ KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ testForD8()
+ .addInnerClasses(IterateTest.class)
+ .setMinApi(parameters.getApiLevel())
+ .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .compile()
+ .addDesugaredCoreLibraryRunClassPath(
+ this::buildDesugaredLibrary,
+ parameters.getApiLevel(),
+ keepRuleConsumer.get(),
+ shrinkDesugaredLibrary)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ IntStream iterate = IntStream.iterate(1, x -> x + 3);
+ System.out.println(iterate.findFirst().getAsInt());
+ }
+ }
+}
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 624e8a0..f5f2275 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
@@ -120,15 +120,15 @@
Path directory = temp.newFolder().toPath();
GenerateLintFiles.main(
new String[] {
- ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString(),
- ToolHelper.DESUGAR_JDK_LIBS,
+ ToolHelper.getDesugarLibJsonForTesting().toString(),
+ ToolHelper.getDesugarJDKLibs().toString(),
directory.toString()
});
InternalOptions options = new InternalOptions(new DexItemFactory(), new Reporter());
DesugaredLibraryConfiguration desugaredLibraryConfiguration =
new DesugaredLibraryConfigurationParser(
options.itemFactory, options.reporter, false, AndroidApiLevel.B.getLevel())
- .parse(StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING));
+ .parse(StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
for (AndroidApiLevel apiLevel : AndroidApiLevel.values()) {
Path compileApiLevelDirectory = directory.resolve("compile_api_level_" + apiLevel.getLevel());
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingJ$Test.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingJ$Test.java
index 0245f6e..a8462e1 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingJ$Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingJ$Test.java
@@ -106,7 +106,7 @@
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
.addProgramFiles(ToolHelper.getDesugarJDKLibs())
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(AndroidApiLevel.B.getLevel())
.setOutput(outputDex, OutputMode.DexIndexed)
.build());
@@ -121,7 +121,7 @@
.addProgramFiles(JDK_11_JAVA_BASE_EXTENSION_COMPILED_FILES)
.addClasspathFiles(ToolHelper.getDesugarJDKLibs())
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(AndroidApiLevel.B.getLevel())
.setOutput(outputDex, OutputMode.DexIndexed)
.build());
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
index f62067c..efddc67 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
@@ -75,8 +75,8 @@
.parse(
StringResource.fromFile(
libraryDesugarJavaUtilObjects
- ? ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING_ALTERNATIVE_3
- : ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING));
+ ? ToolHelper.getDesugarLibJsonForTestingAlternative3()
+ : ToolHelper.getDesugarLibJsonForTesting()));
}
private void configurationForProgramCompilation(InternalOptions options) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
index 082253b..aa05c9d 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
@@ -14,7 +14,6 @@
import com.android.tools.r8.D8TestRunResult;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestShrinkerBuilder;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.utils.AndroidApiLevel;
@@ -154,28 +153,24 @@
.streamInstructions()
.filter(instr -> instr.isInvokeInterface() || instr.isInvokeStatic())
.collect(Collectors.toList());
- assertEquals(23, invokes.size());
+ assertEquals(22, invokes.size());
assertInvokeStaticMatching(invokes, 0, "Set$-EL;->spliterator");
- assertInvokeStaticMatching(invokes, 1, "List$-EL;->spliterator");
- assertInvokeStaticMatching(invokes, 2, "Collection$-EL;->stream");
- assertInvokeInterfaceMatching(invokes, 3, "Set;->iterator");
- assertInvokeStaticMatching(invokes, 4, "Collection$-EL;->stream");
- assertInvokeStaticMatching(invokes, 5, "Set$-EL;->spliterator");
- assertInvokeInterfaceMatching(invokes, 9, "Iterator;->remove");
+ assertInvokeStaticMatching(invokes, 1, "Collection$-EL;->stream");
+ assertInvokeInterfaceMatching(invokes, 2, "Set;->iterator");
+ assertInvokeStaticMatching(invokes, 3, "Collection$-EL;->stream");
+ assertInvokeStaticMatching(invokes, 4, "Set$-EL;->spliterator");
+ assertInvokeInterfaceMatching(invokes, 8, "Iterator;->remove");
+ assertInvokeStaticMatching(invokes, 9, "DesugarArrays;->spliterator");
assertInvokeStaticMatching(invokes, 10, "DesugarArrays;->spliterator");
- assertInvokeStaticMatching(invokes, 11, "DesugarArrays;->spliterator");
+ assertInvokeStaticMatching(invokes, 11, "DesugarArrays;->stream");
assertInvokeStaticMatching(invokes, 12, "DesugarArrays;->stream");
- assertInvokeStaticMatching(invokes, 13, "DesugarArrays;->stream");
- assertInvokeStaticMatching(invokes, 14, "Collection$-EL;->stream");
- assertInvokeStaticMatching(invokes, 15, "IntStream$-CC;->range");
- assertInvokeStaticMatching(invokes, 17, "Comparator$-CC;->comparingInt");
- assertInvokeStaticMatching(invokes, 18, "List$-EL;->sort");
- assertInvokeStaticMatching(invokes, 20, "Comparator$-CC;->comparingInt");
- assertInvokeStaticMatching(invokes, 21, "List$-EL;->sort");
- assertInvokeStaticMatching(invokes, 22, "Collection$-EL;->stream");
- // TODO (b/134732760): Support Java 9 Stream APIs
- // assertTrue(invokes.get(17).isInvokeStatic());
- // assertTrue(invokes.get(17).toString().contains("Stream$-CC;->iterate"));
+ assertInvokeStaticMatching(invokes, 13, "Collection$-EL;->stream");
+ assertInvokeStaticMatching(invokes, 14, "IntStream$-CC;->range");
+ assertInvokeStaticMatching(invokes, 16, "Comparator$-CC;->comparingInt");
+ assertInvokeStaticMatching(invokes, 17, "List$-EL;->sort");
+ assertInvokeStaticMatching(invokes, 19, "Comparator$-CC;->comparingInt");
+ assertInvokeStaticMatching(invokes, 20, "List$-EL;->sort");
+ assertInvokeStaticMatching(invokes, 21, "Collection$-EL;->stream");
}
private void assertInvokeInterfaceMatching(List<InstructionSubject> invokes, int i, String s) {
@@ -193,7 +188,6 @@
StringUtils.lines(
"-keep class j$.util.List$-EL {",
" void sort(java.util.List, java.util.Comparator);",
- " j$.util.Spliterator spliterator(java.util.List);",
"}",
"-keep class j$.util.Collection$-EL {",
" j$.util.stream.Stream stream(java.util.Collection);",
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/SpliteratorTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/SpliteratorTest.java
new file mode 100644
index 0000000..5af29c3
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/SpliteratorTest.java
@@ -0,0 +1,103 @@
+// Copyright (c) 2019, 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.desugar.desugaredlibrary;
+
+import static junit.framework.TestCase.assertTrue;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class SpliteratorTest extends DesugaredLibraryTestBase {
+
+ private final TestParameters parameters;
+ private static final String EXPECTED_OUTPUT_JDK11 =
+ StringUtils.lines(
+ "j$.util.AbstractList$RandomAccessSpliterator",
+ "j$.util.AbstractList$RandomAccessSpliterator",
+ "j$.util.Spliterators$IteratorSpliterator",
+ "j$.util.Spliterators$IteratorSpliterator");
+ private static final String EXPECTED_OUTPUT_JDK8 =
+ StringUtils.lines(
+ "j$.util.Spliterators$IteratorSpliterator",
+ "j$.util.Spliterators$IteratorSpliterator",
+ "j$.util.Spliterators$IteratorSpliterator",
+ "j$.util.Spliterators$IteratorSpliterator");
+
+ @Parameters(name = "{0}")
+ public static List<Object[]> data() {
+ return buildParameters(getTestParameters().withDexRuntimes().withAllApiLevels().build());
+ }
+
+ public SpliteratorTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testSpliterator() throws Exception {
+ Assume.assumeTrue(requiresEmulatedInterfaceCoreLibDesugaring(parameters));
+ testForD8()
+ .addInnerClasses(SpliteratorTest.class)
+ .setMinApi(parameters.getApiLevel())
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
+ .compile()
+ .inspect(this::validateInterfaces)
+ .addDesugaredCoreLibraryRunClassPath(this::buildDesugaredLibrary, parameters.getApiLevel())
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(
+ isJDK11DesugaredLibrary() ? EXPECTED_OUTPUT_JDK11 : EXPECTED_OUTPUT_JDK8);
+ }
+
+ private void validateInterfaces(CodeInspector inspector) {
+ assertTrue(
+ inspector
+ .clazz("com.android.tools.r8.desugar.desugaredlibrary.SpliteratorTest$MyArrayList")
+ .getDexProgramClass()
+ .interfaces
+ .toString()
+ .contains("j$.util.List"));
+ assertTrue(
+ inspector
+ .clazz("com.android.tools.r8.desugar.desugaredlibrary.SpliteratorTest$MyLinkedList")
+ .getDexProgramClass()
+ .interfaces
+ .toString()
+ .contains("j$.util.List"));
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ System.out.println(new ArrayList<>().spliterator().getClass().getName());
+ System.out.println(new MyArrayList<>().spliterator().getClass().getName());
+ System.out.println(new LinkedList<>().spliterator().getClass().getName());
+ System.out.println(new MyLinkedList<>().spliterator().getClass().getName());
+ }
+ }
+
+ static class MyArrayList<E> extends ArrayList<E> {
+ @Override
+ public void sort(Comparator<? super E> c) {
+ // Override to force j$ interface.
+ }
+ }
+
+ static class MyLinkedList<E> extends LinkedList<E> {
+ @Override
+ public void sort(Comparator<? super E> c) {
+ // Override to force j$ interface.
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java
index 43d5b9a..3fe90f3 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java
@@ -48,7 +48,7 @@
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
.addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
.addDesugaredLibraryConfiguration(
- StringResource.fromFile(ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING))
+ StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(parameters.getApiLevel().getLevel())
.setOutput(desugaredLib, OutputMode.DexIndexed);
ToolHelper.runL8(l8Builder.build(), x -> {});
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/DuplicateAPIDesugaredLibTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/DuplicateAPIDesugaredLibTest.java
index 812cd34..9a251a9 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/DuplicateAPIDesugaredLibTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/DuplicateAPIDesugaredLibTest.java
@@ -82,8 +82,12 @@
private void assertDupMethod(CodeInspector inspector, boolean supportAllCallbacksFromLibrary) {
ClassSubject clazz = inspector.clazz("j$.util.concurrent.ConcurrentHashMap");
+ int numForEachMethods =
+ isJDK11DesugaredLibrary()
+ ? supportAllCallbacksFromLibrary ? 4 : 3
+ : supportAllCallbacksFromLibrary ? 2 : 1;
assertEquals(
- supportAllCallbacksFromLibrary ? 2 : 1,
+ numForEachMethods,
clazz.virtualMethods().stream().filter(m -> m.getOriginalName().equals("forEach")).count());
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamTests.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamTests.java
index 0901c28..355343d 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamTests.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamTests.java
@@ -73,23 +73,31 @@
return files;
}
- private static String[] FAILING_RUNNABLE_TESTS =
- new String[] {
- // J9 failure.
- "org/openjdk/tests/java/util/stream/SpliteratorTest.java",
- "org/openjdk/tests/java/util/stream/WhileOpStatefulTest.java",
- "org/openjdk/tests/java/util/stream/IterateTest.java",
- "org/openjdk/tests/java/util/stream/WhileOpTest.java",
- // Assertion error
- "org/openjdk/tests/java/util/stream/StreamCloseTest.java",
- "org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java",
- "org/openjdk/tests/java/util/stream/CountTest.java",
- // J9 Random problem
- "org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java",
- "org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java",
- "org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java"
+ private static final String[] FAILING_RUNNABLE_TESTS = new String[] {
+ // Disabled, D8 generated code raises AbstractMethodError instead of NPE because of API
+ // unsupported in the desugared library.
+ // "org/openjdk/tests/java/util/stream/SpliteratorTest.java",
+ // Disabled because both the stream close issue and the Random issue (See below).
+ // "org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java",
// Disabled because explicit cast done on a wrapped value.
// "org/openjdk/tests/java/util/SplittableRandomTest.java",
+ // Disabled due to a desugaring failure due to the extended library used for the test.
+ // "org/openjdk/tests/java/util/stream/IterateTest.java",
+ };
+
+ // Cannot succeed with JDK 8 desugared library because use J9 features.
+ // Stream close issue with try with resource desugaring mixed with partial library desugaring.
+ public static final String[] STREAM_CLOSE_TESTS =
+ new String[] {"org/openjdk/tests/java/util/stream/StreamCloseTest.java"};
+
+ // Cannot succeed with JDK 8 desugared library because use J9 features.
+ public static final String[] SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_AND_V7 =
+ new String[] {
+ // Require the virtual method isDefault() in class java/lang/reflect/Method.
+ "org/openjdk/tests/java/util/stream/WhileOpTest.java",
+ "org/openjdk/tests/java/util/stream/WhileOpStatefulTest.java",
+ // Require a Random method not present before Android 7 and not desugared.
+ "org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java"
};
// Disabled because time to run > 1 min for each test.
@@ -108,6 +116,15 @@
"org/openjdk/tests/java/util/stream/ToArrayOpTest.java"
};
+ private static final String[] SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_ONLY =
+ new String[] {
+ // Assertion error
+ "org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java",
+ "org/openjdk/tests/java/util/stream/CountTest.java",
+ // J9 Random problem
+ "org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java",
+ };
+
private static String[] SUCCESSFUL_RUNNABLE_TESTS =
new String[] {
"org/openjdk/tests/java/util/stream/FindFirstOpTest.java",
@@ -136,6 +153,37 @@
"org/openjdk/tests/java/util/stream/FindAnyOpTest.java"
};
+ private Map<String, String> getSuccessfulTests() {
+ Map<String, String> runnableTests = getRunnableTests(SUCCESSFUL_RUNNABLE_TESTS);
+ if (isJDK11DesugaredLibrary()) {
+ runnableTests.putAll(getRunnableTests(SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_ONLY));
+ if (parameters.getDexRuntimeVersion().isNewerThanOrEqual(Version.V7_0_0)) {
+ runnableTests.putAll(getRunnableTests(SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_AND_V7));
+ }
+ if (!parameters.getApiLevel().isLessThanOrEqualTo(AndroidApiLevel.K)) {
+ runnableTests.putAll(getRunnableTests(STREAM_CLOSE_TESTS));
+ }
+ }
+ return runnableTests;
+ }
+
+ private Map<String, String> getFailingTests() {
+ Map<String, String> runnableTests = getRunnableTests(FAILING_RUNNABLE_TESTS);
+ if (!isJDK11DesugaredLibrary()) {
+ runnableTests.putAll(getRunnableTests(SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_ONLY));
+ runnableTests.putAll(getRunnableTests(SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_AND_V7));
+ runnableTests.putAll(getRunnableTests(STREAM_CLOSE_TESTS));
+ } else {
+ if (parameters.getApiLevel().isLessThanOrEqualTo(AndroidApiLevel.K)) {
+ runnableTests.putAll(getRunnableTests(STREAM_CLOSE_TESTS));
+ }
+ if (!parameters.getDexRuntimeVersion().isNewerThanOrEqual(Version.V7_0_0)) {
+ runnableTests.putAll(getRunnableTests(SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_AND_V7));
+ }
+ }
+ return runnableTests;
+ }
+
private static Map<String, String> getRunnableTests(String[] tests) {
IdentityHashMap<String, String> pathToName = new IdentityHashMap<>();
int javaExtSize = JAVA_EXTENSION.length();
@@ -150,16 +198,18 @@
private static String[] missingDesugaredMethods() {
// These methods are from Java 9 and not supported in the current desugared libraries.
- return new String[]{
- // Stream
- "takeWhile(",
- "dropWhile(",
- "iterate(",
- "range(",
- "doubles(",
- // Collectors
- "filtering(",
- "flatMapping(",
+ return new String[] {
+ // Stream
+ "takeWhile(",
+ "dropWhile(",
+ "iterate(",
+ "range(",
+ "doubles(",
+ // Collectors
+ "filtering(",
+ "flatMapping(",
+ // isDefault()Z in class Ljava/lang/reflect/Method
+ "isDefault("
};
}
@@ -262,7 +312,7 @@
private void runSuccessfulTests(D8TestCompileResult compileResult) throws Exception {
String verbosity = "2"; // Increase verbosity for debugging.
- Map<String, String> runnableTests = getRunnableTests(SUCCESSFUL_RUNNABLE_TESTS);
+ Map<String, String> runnableTests = getSuccessfulTests();
for (String path : runnableTests.keySet()) {
assert runnableTests.get(path) != null;
D8TestRunResult result =
@@ -281,7 +331,7 @@
// For failing runnable tests, we just ensure that they do not fail due to desugaring, but
// due to an expected failure (missing API, etc.).
String verbosity = "2"; // Increase verbosity for debugging.
- Map<String, String> runnableTests = getRunnableTests(FAILING_RUNNABLE_TESTS);
+ Map<String, String> runnableTests = getFailingTests();
for (String path : runnableTests.keySet()) {
assert runnableTests.get(path) != null;
D8TestRunResult result =
@@ -291,9 +341,6 @@
if (stdout.contains("java.lang.NoSuchMethodError")
&& Arrays.stream(missingDesugaredMethods()).anyMatch(stdout::contains)) {
// TODO(b/134732760): support Java 9 APIs.
- } else if (stdout.contains("java.lang.NoSuchMethodError")
- && stdout.contains("org.openjdk.tests.java.util.stream.IterateTest.testIterate")) {
- // TODO(b/134732760): support Java 9 APIs.
} else if (stdout.contains("in class Ljava/util/Random")
&& stdout.contains("java.lang.NoSuchMethodError")) {
// TODO(b/134732760): Random Java 9 Apis, support or do not use them.
diff --git a/src/test/java/com/android/tools/r8/desugar/lambdas/ExplicitCallToJavacGeneratedInstanceLambdaMethodTest.java b/src/test/java/com/android/tools/r8/desugar/lambdas/ExplicitCallToJavacGeneratedInstanceLambdaMethodTest.java
index 721e41d..ac20adf 100644
--- a/src/test/java/com/android/tools/r8/desugar/lambdas/ExplicitCallToJavacGeneratedInstanceLambdaMethodTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/lambdas/ExplicitCallToJavacGeneratedInstanceLambdaMethodTest.java
@@ -43,10 +43,7 @@
.addProgramClasses(Main.class, A.class, FunctionalInterface.class)
.addProgramClassFileData(getProgramClassFileData())
.run(parameters.getRuntime(), Main.class)
- .applyIf(
- parameters.isCfRuntime(),
- result -> result.assertSuccessWithOutputLines("Hello world!", "Hello world!"),
- result -> result.assertFailureWithErrorThatThrows(NoSuchMethodError.class));
+ .assertSuccessWithOutputLines("Hello world!", "Hello world!");
}
@Test
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PackagePrivateOverrideDeVirtualizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PackagePrivateOverrideDeVirtualizerTest.java
index b3ca988..33da30f 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PackagePrivateOverrideDeVirtualizerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PackagePrivateOverrideDeVirtualizerTest.java
@@ -56,8 +56,7 @@
.enableNoVerticalClassMergingAnnotations()
.enableNeverClassInliningAnnotations()
.run(parameters.getRuntime(), Main.class)
- // TODO(b/182185057): This should be EXPECTED.
- .assertSuccessWithOutputLines(EXPECTED_DALVIK);
+ .apply(this::assertSuccessOutput);
}
private byte[] getSubViewModelInAnotherPackage() throws Exception {
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageDontObfuscateTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageDontObfuscateTest.java
new file mode 100644
index 0000000..5ece41d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageDontObfuscateTest.java
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.repackage;
+
+import static com.android.tools.r8.shaking.ProguardConfigurationParser.FLATTEN_PACKAGE_HIERARCHY;
+import static com.android.tools.r8.shaking.ProguardConfigurationParser.REPACKAGE_CLASSES;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.ProguardVersion;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * A simple test that checks that R8 behaves the same as PG for repackaging. We do require that
+ * classes that are looked up reflectively are kept in some way, however, for easier debugging with
+ * -dontobfuscate we should follow PG behavior. *
+ */
+@RunWith(Parameterized.class)
+public class RepackageDontObfuscateTest extends RepackageTestBase {
+
+ private final String[] EXPECTED = new String[] {"A::foo", "A::foo", "A::foo"};
+
+ @Parameters(name = "{1}, kind: {0}, PG-version: {2}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ ImmutableList.of(FLATTEN_PACKAGE_HIERARCHY, REPACKAGE_CLASSES),
+ getTestParameters().withAllRuntimesAndApiLevels().build(),
+ ProguardVersion.values());
+ }
+
+ private final ProguardVersion proguardVersion;
+
+ public RepackageDontObfuscateTest(
+ String flattenPackageHierarchyOrRepackageClasses,
+ TestParameters parameters,
+ ProguardVersion proguardVersion) {
+ super(flattenPackageHierarchyOrRepackageClasses, parameters);
+ this.proguardVersion = proguardVersion;
+ }
+
+ @Test
+ public void testPG() throws Exception {
+ assumeTrue(parameters.isCfRuntime());
+ testForProguard(proguardVersion)
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .apply(this::configureRepackaging)
+ .addInliningAnnotations()
+ .addDontWarn(RepackageDontObfuscateTest.class)
+ .noMinification()
+ .compile()
+ .inspect(
+ inspector -> {
+ ClassSubject aClass = inspector.clazz(A.class);
+ assertThat(aClass, isPresentAndNotRenamed());
+ })
+ .run(parameters.getRuntime(), Main.class, A.class.getTypeName())
+ .assertSuccessWithOutputLines(EXPECTED);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .setMinApi(parameters.getApiLevel())
+ .addKeepMainRule(Main.class)
+ .enableInliningAnnotations()
+ .apply(this::configureRepackaging)
+ .noMinification()
+ .compile()
+ .inspect(
+ inspector -> {
+ ClassSubject aClass = inspector.clazz(A.class);
+ assertThat(aClass, isPresentAndNotRenamed());
+ })
+ .run(parameters.getRuntime(), Main.class, A.class.getTypeName())
+ .assertSuccessWithOutputLines(EXPECTED);
+ }
+
+ public static class A {
+
+ @NeverInline
+ public static void foo() {
+ System.out.println("A::foo");
+ }
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) throws Exception {
+ A.foo();
+ Class.forName("com.android.tools.r8.repackage.RepackageDontObfuscateTest$A")
+ .getDeclaredMethod("foo")
+ .invoke(null);
+ Class.forName(args[0]).getDeclaredMethod("foo").invoke(null);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageFeatureWithSyntheticsTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageFeatureWithSyntheticsTest.java
index 4eb6d15..5e62057 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageFeatureWithSyntheticsTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageFeatureWithSyntheticsTest.java
@@ -92,7 +92,6 @@
.addKeepMethodRules(
Reference.methodFromMethod(TestClass.class.getDeclaredMethod("run", I.class)))
.addKeepAttributeInnerClassesAndEnclosingMethod()
- .noMinification()
.apply(this::configureRepackaging)
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
@@ -107,14 +106,14 @@
// If it is, the access will fail resulting in a runtime exception.
compileResult.inspect(
baseInspector -> {
- assertThat(FIRST_FOO, isRepackagedAsExpected(baseInspector, "first"));
+ assertThat(FIRST_FOO, isRepackagedAsExpected(baseInspector, "a"));
assertThat(FIRST_PKG_PRIVATE, isNotRepackaged(baseInspector));
assertEquals(
getTestClasses().size() + expectedSyntheticsInBase,
baseInspector.allClasses().size());
},
featureInspector -> {
- assertThat(FIRST_FIRST_FOO, isRepackagedAsExpected(featureInspector, "first$1"));
+ assertThat(FIRST_FIRST_FOO, isRepackagedAsExpected(featureInspector, "b"));
assertThat(FIRST_FIRST_PKG_PRIVATE, isNotRepackaged(featureInspector));
assertEquals(
getFeatureClasses().size() + expectedSyntheticsInFeature,
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageTestBase.java b/src/test/java/com/android/tools/r8/repackage/RepackageTestBase.java
index 788bb0a..616295a 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageTestBase.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageTestBase.java
@@ -7,9 +7,9 @@
import static com.android.tools.r8.shaking.ProguardConfigurationParser.FLATTEN_PACKAGE_HIERARCHY;
import static com.android.tools.r8.shaking.ProguardConfigurationParser.REPACKAGE_CLASSES;
-import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestShrinkerBuilder;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -130,7 +130,7 @@
};
}
- protected void configureRepackaging(R8TestBuilder<?> testBuilder) {
+ protected void configureRepackaging(TestShrinkerBuilder<?, ?, ?, ?, ?> testBuilder) {
testBuilder.addKeepRules(
"-" + flattenPackageHierarchyOrRepackageClasses + " \"" + getRepackagePackage() + "\"");
}
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageWithSuffixRenamingConfigurationTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageWithSuffixRenamingConfigurationTest.java
index b22042f..dcfd6c3 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageWithSuffixRenamingConfigurationTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageWithSuffixRenamingConfigurationTest.java
@@ -30,10 +30,12 @@
.addKeepMainRule(TestClass.class)
.addKeepClassRules(GreeterFoo.class)
.addOptionsModification(
- options ->
- options.testing.repackagingConfigurationFactory =
- appView ->
- new SuffixRenamingRepackagingConfiguration("Foo", appView.dexItemFactory()))
+ options -> {
+ options.testing.repackageWithNoMinification = true;
+ options.testing.repackagingConfigurationFactory =
+ appView ->
+ new SuffixRenamingRepackagingConfiguration("Foo", appView.dexItemFactory());
+ })
.apply(this::configureRepackaging)
.enableInliningAnnotations()
.noMinification()
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java
index 4df6622..1a3bfca 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java
@@ -67,7 +67,7 @@
// TODO(b/172014416): We should not be able to look this up through the repackage name
String expectedOriginalNamePrefix =
isFlattenPackageHierarchy()
- ? "foo.repackage.RepackageWithSyntheticItemTest$A"
+ ? "foo.a.RepackageWithSyntheticItemTest$A"
: "foo.RepackageWithSyntheticItemTest$A";
assertThat(
classesStartingWithfoo.get(0).getOriginalName(),
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 aa543c8..41d1c3f 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 @@
.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/shaking/AbstractSuperClassLiveMethodTest.java b/src/test/java/com/android/tools/r8/shaking/AbstractSuperClassLiveMethodTest.java
deleted file mode 100644
index 8cdd48e..0000000
--- a/src/test/java/com/android/tools/r8/shaking/AbstractSuperClassLiveMethodTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2021, 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.shaking;
-
-import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.NoVerticalClassMerging;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class AbstractSuperClassLiveMethodTest extends TestBase {
-
- private final TestParameters parameters;
- private final String NEW_DESCRIPTOR = "Lfoo/A;";
- private final String[] EXPECTED = new String[] {"A::foo", "Base::foo"};
- private final String[] EXPECTED_DALVIK = new String[] {"A::foo", "A::foo"};
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
- }
-
- public AbstractSuperClassLiveMethodTest(TestParameters parameters) {
- this.parameters = parameters;
- }
-
- public List<byte[]> getProgramClassFileData() throws Exception {
- return ImmutableList.of(
- transformer(A.class).setClassDescriptor(NEW_DESCRIPTOR).transform(),
- transformer(Main.class)
- .replaceClassDescriptorInMethodInstructions(descriptor(A.class), NEW_DESCRIPTOR)
- .transform());
- }
-
- @Test
- public void testRuntime() throws Exception {
- testForRuntime(parameters)
- .addProgramClasses(Base.class)
- .addProgramClassFileData(getProgramClassFileData())
- .run(parameters.getRuntime(), Main.class)
- .applyIf(
- parameters.isDexRuntime() && parameters.getDexRuntimeVersion().isDalvik(),
- r -> r.assertSuccessWithOutputLines(EXPECTED_DALVIK),
- r -> r.assertSuccessWithOutputLines(EXPECTED));
- }
-
- @Test
- public void testForR8() throws Exception {
- testForR8(parameters.getBackend())
- .addProgramClasses(Base.class)
- .addProgramClassFileData(getProgramClassFileData())
- .setMinApi(parameters.getApiLevel())
- .addKeepMainRule(Main.class)
- .enableInliningAnnotations()
- .enableNoVerticalClassMergingAnnotations()
- .enableNeverClassInliningAnnotations()
- .addOptionsModification(options -> options.enableDevirtualization = false)
- .run(parameters.getRuntime(), Main.class)
- .applyIf(
- parameters.isDexRuntime() && parameters.getDexRuntimeVersion().isDalvik(),
- r -> r.assertSuccessWithOutputLines(EXPECTED_DALVIK),
- // TODO(b/182444403): Should succeed with EXPECTED.
- r -> r.assertFailureWithErrorThatThrows(AbstractMethodError.class));
- }
-
- @NoVerticalClassMerging
- public abstract static class Base {
-
- @NeverInline
- void foo() {
- System.out.println("Base::foo");
- }
- }
-
- @NeverClassInline
- public static class /* will be foo.A */ A extends Base {
-
- @Override
- @NeverInline
- public void foo() {
- System.out.println("A::foo");
- }
- }
-
- public static class Main {
-
- public static void main(String[] args) {
- Base a = new A();
- ((A) a).foo();
- a.foo();
- }
- }
-}
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 be358de..1763108 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.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.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 @@
}
@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/HorizontallyMergedClassesInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/HorizontallyMergedClassesInspector.java
index 91fb002..e6fa548 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/HorizontallyMergedClassesInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/HorizontallyMergedClassesInspector.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.utils.codeinspector;
-import static com.android.tools.r8.TestBase.toDexType;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -72,11 +71,20 @@
return this;
}
+ public HorizontallyMergedClassesInspector assertClassesMerged(Class<?>... classes) {
+ return assertClassesMerged(Arrays.asList(classes));
+ }
+
public HorizontallyMergedClassesInspector assertClassesMerged(Collection<Class<?>> classes) {
return assertTypesMerged(classes.stream().map(this::toDexType).collect(Collectors.toList()));
}
public HorizontallyMergedClassesInspector assertClassReferencesMerged(
+ ClassReference... classReferences) {
+ return assertClassReferencesMerged(Arrays.asList(classReferences));
+ }
+
+ public HorizontallyMergedClassesInspector assertClassReferencesMerged(
Collection<ClassReference> classReferences) {
return assertTypesMerged(
classReferences.stream().map(this::toDexType).collect(Collectors.toList()));
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 28f0b9c..e7db18c 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 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 05d83b7..29bc90b 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 boolean isRenamed();
public abstract boolean isSynthetic();
+
+ public boolean isCompilerSynthesized() {
+ throw new Unimplemented(
+ "Predicate not yet supported on Subject: " + getClass().getSimpleName());
+ }
}
diff --git a/third_party/openjdk/desugar_jdk_libs_11.tar.gz.sha1 b/third_party/openjdk/desugar_jdk_libs_11.tar.gz.sha1
new file mode 100644
index 0000000..cb35cd0
--- /dev/null
+++ b/third_party/openjdk/desugar_jdk_libs_11.tar.gz.sha1
@@ -0,0 +1 @@
+5696c90f0675746b4e996c80de461dd2cfd80076
\ No newline at end of file
diff --git a/tools/archive.py b/tools/archive.py
index e92e87d..24e8e0a 100755
--- a/tools/archive.py
+++ b/tools/archive.py
@@ -56,51 +56,51 @@
def GetGitHash():
return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()
-def IsMaster(version):
+def IsMain(version):
branches = subprocess.check_output(['git', 'branch', '-r', '--contains',
'HEAD'])
- # CL runs from gerrit does not have a branch, we always treat them as master
+ # CL runs from gerrit does not have a branch, we always treat them as main
# commits to archive these to the hash based location
if len(branches) == 0:
return True
- if not version == 'master':
+ if not version == 'main':
# Sanity check, we don't want to archive on top of release builds EVER
# Note that even though we branch, we never push the bots to build the same
- # commit as master on a branch since we always change the version to
- # not be just 'master' (or we crash here :-)).
- if 'origin/master' in branches:
- raise Exception('We are seeing origin/master in a commit that '
- 'don\'t have \'master\' as version')
+ # commit as main on a branch since we always change the version to
+ # not be just 'main' (or we crash here :-)).
+ if 'origin/main' in branches:
+ raise Exception('We are seeing origin/main in a commit that '
+ 'don\'t have \'main\' as version')
return False
- if not 'origin/master' in branches:
- raise Exception('We are not seeing origin/master '
- 'in a commit that have \'master\' as version')
+ if not 'origin/main' in branches:
+ raise Exception('We are not seeing origin/main '
+ 'in a commit that have \'main\' as version')
return True
def GetStorageDestination(storage_prefix,
version_or_path,
file_name,
- is_master):
- # We archive master commits under raw/master instead of directly under raw
+ is_main):
+ # We archive main commits under raw/main instead of directly under raw
version_dir = GetVersionDestination(storage_prefix,
version_or_path,
- is_master)
+ is_main)
return '%s/%s' % (version_dir, file_name)
-def GetVersionDestination(storage_prefix, version_or_path, is_master):
- archive_dir = 'raw/master' if is_master else 'raw'
+def GetVersionDestination(storage_prefix, version_or_path, is_main):
+ archive_dir = 'raw/main' if is_main else 'raw'
return '%s%s/%s/%s' % (storage_prefix, ARCHIVE_BUCKET,
archive_dir, version_or_path)
-def GetUploadDestination(version_or_path, file_name, is_master):
- return GetStorageDestination('gs://', version_or_path, file_name, is_master)
+def GetUploadDestination(version_or_path, file_name, is_main):
+ return GetStorageDestination('gs://', version_or_path, file_name, is_main)
-def GetUrl(version_or_path, file_name, is_master):
+def GetUrl(version_or_path, file_name, is_main):
return GetStorageDestination('https://storage.googleapis.com/',
- version_or_path, file_name, is_master)
+ version_or_path, file_name, is_main)
-def GetMavenUrl(is_master):
- return GetVersionDestination('https://storage.googleapis.com/', '', is_master)
+def GetMavenUrl(is_main):
+ return GetVersionDestination('https://storage.googleapis.com/', '', is_main)
def SetRLimitToMax():
(soft, hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
@@ -157,13 +157,13 @@
utils.DESUGAR_CONFIGURATION_MAVEN_ZIP)
version = GetVersion()
- is_master = IsMaster(version)
- if is_master:
- # On master we use the git hash to archive with
- print('On master, using git hash for archiving')
+ is_main = IsMain(version)
+ if is_main:
+ # On main we use the git hash to archive with
+ print('On main, using git hash for archiving')
version = GetGitHash()
- destination = GetVersionDestination('gs://', version, is_master)
+ destination = GetVersionDestination('gs://', version, is_main)
if utils.cloud_storage_exists(destination) and not options.dry_run:
raise Exception('Target archive directory %s already exists' % destination)
with utils.TempDir() as temp:
@@ -207,7 +207,7 @@
if file_name.endswith('.jar') and not file_name.endswith('-src.jar'):
with zipfile.ZipFile(tagged_jar, 'a') as zip:
zip.write(version_file, os.path.basename(version_file))
- destination = GetUploadDestination(version, file_name, is_master)
+ destination = GetUploadDestination(version, file_name, is_main)
print('Uploading %s to %s' % (tagged_jar, destination))
if options.dry_run:
if options.dry_run_output:
@@ -219,21 +219,21 @@
print('Dry run, not actually uploading')
else:
utils.upload_file_to_cloud_storage(tagged_jar, destination)
- print('File available at: %s' % GetUrl(version, file_name, is_master))
+ print('File available at: %s' % GetUrl(version, file_name, is_main))
# Upload R8 to a maven compatible location.
if file == utils.R8_JAR:
maven_dst = GetUploadDestination(utils.get_maven_path('r8', version),
- 'r8-%s.jar' % version, is_master)
+ 'r8-%s.jar' % version, is_main)
maven_pom_dst = GetUploadDestination(
utils.get_maven_path('r8', version),
- 'r8-%s.pom' % version, is_master)
+ 'r8-%s.pom' % version, is_main)
if options.dry_run:
print('Dry run, not actually creating maven repo for R8')
else:
utils.upload_file_to_cloud_storage(tagged_jar, maven_dst)
utils.upload_file_to_cloud_storage(default_pom_file, maven_pom_dst)
- print('Maven repo root available at: %s' % GetMavenUrl(is_master))
+ print('Maven repo root available at: %s' % GetMavenUrl(is_main))
# Upload desugar_jdk_libs configuration to a maven compatible location.
if file == utils.DESUGAR_CONFIGURATION:
@@ -241,7 +241,7 @@
jar_version_name = 'desugar_jdk_libs_configuration-%s.jar' % version
maven_dst = GetUploadDestination(
utils.get_maven_path('desugar_jdk_libs_configuration', version),
- jar_version_name, is_master)
+ jar_version_name, is_main)
with utils.TempDir() as tmp_dir:
desugar_jdk_libs_configuration_jar = os.path.join(tmp_dir,
@@ -262,10 +262,10 @@
else:
utils.upload_file_to_cloud_storage(
desugar_jdk_libs_configuration_jar, maven_dst)
- print('Maven repo root available at: %s' % GetMavenUrl(is_master))
+ print('Maven repo root available at: %s' % GetMavenUrl(is_main))
# Also archive the jar as non maven destination for Google3
jar_destination = GetUploadDestination(
- version, jar_basename, is_master)
+ version, jar_basename, is_main)
utils.upload_file_to_cloud_storage(
desugar_jdk_libs_configuration_jar, jar_destination)
diff --git a/tools/archive_desugar_jdk_libs.py b/tools/archive_desugar_jdk_libs.py
index 825cb91..2bc8386 100755
--- a/tools/archive_desugar_jdk_libs.py
+++ b/tools/archive_desugar_jdk_libs.py
@@ -64,7 +64,7 @@
return version
-def Upload(options, file_name, storage_path, destination, is_master):
+def Upload(options, file_name, storage_path, destination, is_main):
print('Uploading %s to %s' % (file_name, destination))
if options.dry_run:
if options.dry_run_output:
@@ -148,14 +148,14 @@
return
# Only handling versioned desugar_jdk_libs.
- is_master = False
+ is_main = False
with utils.TempDir() as checkout_dir:
CloneDesugaredLibrary(options.github_account, checkout_dir)
version = GetVersion(os.path.join(checkout_dir, VERSION_FILE))
destination = archive.GetVersionDestination(
- 'gs://', LIBRARY_NAME + '/' + version, is_master)
+ 'gs://', LIBRARY_NAME + '/' + version, is_main)
if utils.cloud_storage_exists(destination) and not options.dry_run:
raise Exception(
'Target archive directory %s already exists' % destination)
@@ -165,24 +165,24 @@
storage_path = LIBRARY_NAME + '/' + version
# Upload the jar file with the library.
destination = archive.GetUploadDestination(
- storage_path, LIBRARY_NAME + '.jar', is_master)
- Upload(options, library_jar, storage_path, destination, is_master)
+ storage_path, LIBRARY_NAME + '.jar', is_main)
+ Upload(options, library_jar, storage_path, destination, is_main)
# Upload the maven zip file with the library.
destination = archive.GetUploadDestination(
- storage_path, LIBRARY_NAME + '.zip', is_master)
- Upload(options, maven_zip, storage_path, destination, is_master)
+ storage_path, LIBRARY_NAME + '.zip', is_main)
+ Upload(options, maven_zip, storage_path, destination, is_main)
# Upload the jar file for accessing GCS as a maven repro.
maven_destination = archive.GetUploadDestination(
utils.get_maven_path('desugar_jdk_libs', version),
'desugar_jdk_libs-%s.jar' % version,
- is_master)
+ is_main)
if options.dry_run:
print('Dry run, not actually creating maven repo')
else:
utils.upload_file_to_cloud_storage(library_jar, maven_destination)
- print('Maven repo root available at: %s' % archive.GetMavenUrl(is_master))
+ print('Maven repo root available at: %s' % archive.GetMavenUrl(is_main))
if __name__ == '__main__':
diff --git a/tools/compiledump.py b/tools/compiledump.py
index 3828739..bce5d75 100755
--- a/tools/compiledump.py
+++ b/tools/compiledump.py
@@ -37,10 +37,10 @@
'--version',
help='Compiler version to use (default read from dump version file).'
'Valid arguments are:'
- ' "master" to run from your own tree,'
+ ' "main" to run from your own tree,'
' "source" to run from build classes directly,'
' "X.Y.Z" to run a specific version, or'
- ' <hash> to run that hash from master.',
+ ' <hash> to run that hash from main.',
default=None)
parser.add_argument(
'--r8-jar',
@@ -236,7 +236,7 @@
return None
def download_distribution(args, version, temp):
- if version == 'master':
+ if version == 'main':
return utils.R8_JAR if args.nolib else utils.R8LIB_JAR
if version == 'source':
return '%s:%s' % (utils.BUILD_JAVA_MAIN_DIR, utils.ALL_DEPS_JAR)
@@ -340,8 +340,8 @@
if not args.nolib and version != 'source':
stacktrace = os.path.join(temp, 'stacktrace')
open(stacktrace, 'w+').write(e.output.decode('UTF-8'))
- local_map = utils.R8LIB_MAP if version == 'master' else None
- hash_or_version = None if version == 'master' else version
+ local_map = utils.R8LIB_MAP if version == 'main' else None
+ hash_or_version = None if version == 'main' else version
print("=" * 80)
print(" RETRACED OUTPUT")
print("=" * 80)
diff --git a/tools/git_sync_cl_chain.py b/tools/git_sync_cl_chain.py
index 857aab8..ea67f63 100755
--- a/tools/git_sync_cl_chain.py
+++ b/tools/git_sync_cl_chain.py
@@ -12,8 +12,8 @@
# * feature_final xxxxxxxxx [feature_prereq_c: ...] ...
# feature_prereq_c xxxxxxxxx [feature_prereq_b: ...] ...
# feature_prereq_b xxxxxxxxx [feature_prereq_a: ...] ...
-# feature_prereq_a xxxxxxxxx [master: ...] ...
-# master xxxxxxxxx [origin/master] ...
+# feature_prereq_a xxxxxxxxx [main: ...] ...
+# main xxxxxxxxx [origin/main] ...
#
# Executing `git_sync_cl_chain.py -m <message>` causes the following chain of
# commands to be executed:
@@ -54,8 +54,8 @@
action='store_true')
result.add_option('--no_upload', '--no-upload',
help='Disable uploading to Gerrit', action='store_true')
- result.add_option('--skip_master', '--skip-master',
- help='Disable syncing for master',
+ result.add_option('--skip_main', '--skip-main',
+ help='Disable syncing for main',
action='store_true')
(options, args) = result.parse_args(argv)
options.upload = not options.no_upload
@@ -105,7 +105,7 @@
pull_for_current_branch(branch, options)
- if branch.name == 'master':
+ if branch.name == 'main':
continue
if status == 'closed':
@@ -119,9 +119,9 @@
if not options.leave_upstream:
if not has_seen_open_branch and len(closed_branches) > 0:
print(
- 'Setting upstream for first open branch %s to master'
+ 'Setting upstream for first open branch %s to main'
% branch.name)
- set_upstream_for_current_branch_to_master()
+ set_upstream_for_current_branch_to_main()
has_seen_open_branch = True
has_seen_local_branch = has_seen_local_branch or (status == 'None')
@@ -170,14 +170,14 @@
return utils.RunCmd(['git', 'cl', 'status', '--field', 'status'], quiet=True)[0].strip()
def pull_for_current_branch(branch, options):
- if branch.name == 'master' and options.skip_master:
+ if branch.name == 'main' and options.skip_main:
return
rebase_args = ['--rebase'] if options.rebase else []
utils.RunCmd(['git', 'pull'] + rebase_args, quiet=True)
-def set_upstream_for_current_branch_to_master():
- utils.RunCmd(['git', 'cl', 'upstream', 'master'], quiet=True)
+def set_upstream_for_current_branch_to_main():
+ utils.RunCmd(['git', 'cl', 'upstream', 'main'], quiet=True)
# Parses a line from the output of `git branch -vv`.
#
@@ -187,8 +187,8 @@
# * feature_final xxxxxxxxx [feature_prereq_c: ...] ...
# feature_prereq_c xxxxxxxxx [feature_prereq_b: ...] ...
# feature_prereq_b xxxxxxxxx [feature_prereq_a: ...] ...
-# feature_prereq_a xxxxxxxxx [master: ...] ...
-# master xxxxxxxxx [origin/master] ...
+# feature_prereq_a xxxxxxxxx [main: ...] ...
+# main xxxxxxxxx [origin/main] ...
def parse(line):
is_current = False
if line.startswith('*'):
diff --git a/tools/git_utils.py b/tools/git_utils.py
index 72485e1..9d9c6bd 100644
--- a/tools/git_utils.py
+++ b/tools/git_utils.py
@@ -11,8 +11,8 @@
utils.PrintCmd(cmd)
return subprocess.check_call(cmd)
-def GetHeadRevision(checkout_dir, use_master=False):
- revision_from = 'origin/master' if use_master else 'HEAD'
+def GetHeadRevision(checkout_dir, use_main=False):
+ revision_from = 'origin/main' if use_main else 'HEAD'
cmd = ['git', 'rev-parse', revision_from]
utils.PrintCmd(cmd)
with utils.ChangedWorkingDirectory(checkout_dir):
diff --git a/tools/internal_test.py b/tools/internal_test.py
index 9309237..48409c0 100755
--- a/tools/internal_test.py
+++ b/tools/internal_test.py
@@ -180,7 +180,7 @@
def restart_if_new_version(original_content):
new_content = get_own_file_content()
log('Lengths %s %s' % (len(original_content), len(new_content)))
- log('is master %s ' % utils.is_master())
+ log('is main %s ' % utils.is_main())
# Restart if the script got updated.
if new_content != original_content:
log('Restarting tools/internal_test.py, content changed')
@@ -195,7 +195,7 @@
def git_pull():
ensure_git_clean()
- subprocess.check_call(['git', 'checkout', 'master'])
+ subprocess.check_call(['git', 'checkout', 'main'])
subprocess.check_call(['git', 'pull'])
return utils.get_HEAD_sha1()
diff --git a/tools/r8_release.py b/tools/r8_release.py
index 72a5e02..397c97d 100755
--- a/tools/r8_release.py
+++ b/tools/r8_release.py
@@ -68,13 +68,13 @@
old_version = '%s.%s-dev' % (R8_DEV_BRANCH, patch_version)
version = '%s.%s-dev' % (R8_DEV_BRANCH, patch_version + 1)
- # Verify that the merge point from master is not empty.
+ # Verify that the merge point from main is not empty.
merge_diff_output = subprocess.check_output([
'git', 'diff', 'HEAD..%s' % commithash]).decode('utf-8')
other_diff = version_change_diff(
- merge_diff_output, old_version, "master")
+ merge_diff_output, old_version, "main")
if not other_diff:
- print('Merge point from master (%s)' % commithash, \
+ print('Merge point from main (%s)' % commithash, \
'is the same as exiting release (%s).' % old_version)
sys.exit(1)
@@ -83,7 +83,7 @@
subprocess.check_call([
'git', 'cherry-pick', '--no-edit', pre_commit])
- # Merge the desired commit from master on to the branch.
+ # Merge the desired commit from main on to the branch.
subprocess.check_call([
'git', 'merge', '--no-ff', '--no-edit', commithash])
@@ -96,7 +96,7 @@
version_diff_output = subprocess.check_output([
'git', 'diff', '%s..HEAD' % commithash]).decode('utf-8')
- validate_version_change_diff(version_diff_output, "master", version)
+ validate_version_change_diff(version_diff_output, "main", version)
# Double check that we want to push the release.
if not args.dry_run:
@@ -488,7 +488,7 @@
with utils.ChangedWorkingDirectory(temp):
library_gfile = ('/bigstore/r8-releases/raw/%s/%s/%s'
% (DESUGAR_JDK_LIBS, library_version, library_archive))
- configuration_gfile = ('/bigstore/r8-releases/raw/master/%s/%s'
+ configuration_gfile = ('/bigstore/r8-releases/raw/main/%s/%s'
% (configuration_version, configuration_archive))
download_gfile(library_gfile, library_archive)
@@ -685,7 +685,7 @@
subprocess.check_call(['git', 'checkout', branch_version])
# Rewrite the version, commit and validate.
- old_version = 'master'
+ old_version = 'main'
full_version = branch_version + '.0-dev'
version_prefix = 'LABEL = "'
sed(version_prefix + old_version,
@@ -754,7 +754,7 @@
result = argparse.ArgumentParser(description='Release r8')
group = result.add_mutually_exclusive_group()
group.add_argument('--dev-release',
- metavar=('<master hash>'),
+ metavar=('<main hash>'),
help='The hash to use for the new dev version of R8')
group.add_argument('--version',
metavar=('<version>'),
@@ -769,10 +769,10 @@
help='Update studio mirror of com.android.tools:desugar_jdk_libs')
group.add_argument('--new-dev-branch',
nargs=2,
- metavar=('<version>', '<master hash>'),
+ metavar=('<version>', '<main hash>'),
help='Create a new branch starting a version line (e.g. 2.0)')
result.add_argument('--dev-pre-cherry-pick',
- metavar=('<master hash(s)>'),
+ metavar=('<main hash(s)>'),
default=[],
action='append',
help='List of commits to cherry pick before doing full '
diff --git a/tools/run_on_app_dump.py b/tools/run_on_app_dump.py
index 1644895..779af1d 100755
--- a/tools/run_on_app_dump.py
+++ b/tools/run_on_app_dump.py
@@ -9,6 +9,7 @@
import compiledump
import gradle
import hashlib
+import jdk
import optparse
import os
import shutil
@@ -449,7 +450,7 @@
f.write(line)
-def download_app(app_sha, internal, quiet=False):
+def download_sha(app_sha, internal, quiet=False):
if internal:
utils.DownloadFromX20(app_sha)
else:
@@ -473,7 +474,7 @@
def version_is_built_jar(version):
- return version != 'master' and version != 'source'
+ return version != 'main' and version != 'source'
def compute_size_of_dex_files_in_package(path):
@@ -502,12 +503,13 @@
def get_results_for_app(app, options, temp_dir):
app_folder = app.folder if app.folder else app.name + "_" + app.revision
+ opensource_basedir = (os.path.join('benchmarks', app.name) if options.golem
+ else utils.OPENSOURCE_DUMPS_DIR)
app_dir = (os.path.join(utils.INTERNAL_DUMPS_DIR, app_folder) if app.internal
- else os.path.join(utils.OPENSOURCE_DUMPS_DIR, app_folder))
-
+ else os.path.join(opensource_basedir, app_folder))
if not os.path.exists(app_dir) and not options.golem:
# Download the app from google storage.
- download_app(app_dir + ".tar.gz.sha1", app.internal)
+ download_sha(app_dir + ".tar.gz.sha1", app.internal)
# Ensure that the dumps are in place
assert os.path.isfile(dump_for_app(app_dir, app)), "Could not find dump " \
@@ -929,7 +931,7 @@
help='The shrinkers to use (by default, all are run)',
action='append')
result.add_option('--version',
- default='master',
+ default='main',
help='The version of R8 to use (e.g., 1.4.51)')
(options, args) = result.parse_args(argv)
@@ -996,6 +998,10 @@
print('')
print('createOpenSourceAppBenchmarks() {')
print_indented('final cpus = ["Lenovo M90"];', 2)
+ # Avoid calculating this for every app
+ jdk_gz = jdk.GetJdkHome() + '.tar.gz'
+ download_sha(jdk_gz + '.sha1', False, quiet=True)
+ jdk_sha256 = get_sha256(jdk_gz)
for app in options.apps:
if app.folder and not app.internal:
indentation = 2;
@@ -1014,24 +1020,31 @@
print_indented('options.fromRevision = 9700;', indentation);
print_indented('options.mainFile = "tools/run_on_app_dump.py "', indentation)
print_indented('"--golem --shrinker r8 --app %s";' % app.name, indentation + 4)
+
app_gz = os.path.join(utils.OPENSOURCE_DUMPS_DIR, app.folder + '.tar.gz')
- app_sha = app_gz + '.sha1'
- # Golem uses a sha256 of the file in the cache, and you need to specify that.
- download_app(app_sha, app.internal, quiet=True)
- sha256 = get_sha256(app_gz)
- sha = get_sha_from_file(app_sha)
- print_indented('final resource = BenchmarkResource("",', indentation)
- print_indented('type: BenchmarkResourceType.Storage,', indentation + 4)
- print_indented('uri: "gs://r8-deps/%s",' % sha, indentation + 4)
- print_indented('hash:', indentation + 4)
- print_indented('"%s",' % sha256, indentation + 8)
- print_indented('extract: "gz");', indentation + 4);
- print_indented('options.resources.add(resource);', indentation)
+ add_golem_resource(indentation, app_gz, 'app_resource')
+ add_golem_resource(indentation, jdk_gz, 'openjdk', sha256=jdk_sha256)
+
print_indented('dumpsSuite.addBenchmark(name);', indentation)
indentation = 2
print_indented('}', indentation)
print('}')
+def add_golem_resource(indentation, gz, name, sha256=None):
+ sha = gz + '.sha1'
+ if not sha256:
+ # Golem uses a sha256 of the file in the cache, and you need to specify that.
+ download_sha(sha, False, quiet=True)
+ sha256 = get_sha256(gz)
+ sha = get_sha_from_file(sha)
+ print_indented('final %s = BenchmarkResource("",' % name, indentation)
+ print_indented('type: BenchmarkResourceType.Storage,', indentation + 4)
+ print_indented('uri: "gs://r8-deps/%s",' % sha, indentation + 4)
+ print_indented('hash:', indentation + 4)
+ print_indented('"%s",' % sha256, indentation + 8)
+ print_indented('extract: "gz");', indentation + 4);
+ print_indented('options.resources.add(%s);' % name, indentation)
+
def main(argv):
(options, args) = parse_options(argv)
@@ -1070,7 +1083,7 @@
as_utils.MoveFile(
os.path.join(temp_dir, target), os.path.join(temp_dir, 'r8lib.jar'),
quiet=options.quiet)
- elif options.version == 'master':
+ elif options.version == 'main':
if not (options.no_build or options.golem):
gradle.RunGradle(['r8', '-Pno_internal'])
build_r8lib = False
diff --git a/tools/test.py b/tools/test.py
index f7b204f..ea6a880 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -162,7 +162,8 @@
help='Enable Java debug agent and suspend compilation (default disabled)',
default=False,
action='store_true')
- result.add_option('--desugared-library-configuration', '--desugared_library-configuration',
+ result.add_option('--desugared-library-configuration',
+ '--desugared_library-configuration',
help='Use alternative desugared library configuration.')
result.add_option('--desugared-library', '--desugared_library',
help='Build and use desugared library from GitHub.')
diff --git a/tools/trigger.py b/tools/trigger.py
index 482608a..984cc08 100755
--- a/tools/trigger.py
+++ b/tools/trigger.py
@@ -42,7 +42,7 @@
def get_builders():
is_release = False
- master_builders = []
+ main_builders = []
release_builders = []
with open(LUCI_SCHEDULE, 'r') as fp:
lines = fp.readlines()
@@ -57,13 +57,13 @@
release_builders.append(builder)
else:
assert 'release' not in builder
- master_builders.append(builder)
- assert DESUGAR_BOT in master_builders
+ main_builders.append(builder)
+ assert DESUGAR_BOT in main_builders
print 'Desugar builder:\n ' + DESUGAR_BOT
- master_builders.remove(DESUGAR_BOT)
- print 'Master builders:\n ' + '\n '.join(master_builders)
+ main_builders.remove(DESUGAR_BOT)
+ print 'Main builders:\n ' + '\n '.join(main_builders)
print 'Release builders:\n ' + '\n '.join(release_builders)
- return (master_builders, release_builders)
+ return (main_builders, release_builders)
def sanity_check_url(url):
a = urllib.urlopen(url)
@@ -97,15 +97,15 @@
return 1
commit = None if (options.cl or options.desugar) else args[0]
- (master_builders, release_builders) = get_builders()
- builders = release_builders if options.release else master_builders
+ (main_builders, release_builders) = get_builders()
+ builders = release_builders if options.release else main_builders
if options.builder:
builder = options.builder
- assert builder in master_builders or builder in release_builders
+ assert builder in main_builders or builder in release_builders
builders = [options.builder]
if options.desugar:
builders = [DESUGAR_BOT]
- commit = git_utils.GetHeadRevision(utils.REPO_ROOT, use_master=True)
+ commit = git_utils.GetHeadRevision(utils.REPO_ROOT, use_main=True)
if options.cl:
trigger_cl(builders, options.cl)
else:
diff --git a/tools/utils.py b/tools/utils.py
index da4a0e4..5c1b32b 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -263,10 +263,10 @@
sha1.update(chunk)
return sha1.hexdigest()
-def is_master():
+def is_main():
remotes = subprocess.check_output(['git', 'branch', '-r', '--contains',
'HEAD'])
- return 'origin/master' in remotes
+ return 'origin/main' in remotes
def get_HEAD_sha1():
return get_HEAD_sha1_for_checkout(REPO_ROOT)