Merge commit '2696206a222cb22370975bd0eae821fd7fc0c257' into dev-release
Change-Id: Id737bba21e7f2d283247cf656a0812e54831acd8
diff --git a/infra/config/global/generated/cr-buildbucket.cfg b/infra/config/global/generated/cr-buildbucket.cfg
index 7f15036..d84a61b 100644
--- a/infra/config/global/generated/cr-buildbucket.cfg
+++ b/infra/config/global/generated/cr-buildbucket.cfg
@@ -964,6 +964,82 @@
}
}
builders {
+ name: "linux-android-7-noble"
+ swarming_host: "chrome-swarming.appspot.com"
+ swarming_tags: "vpython:native-python-wrapper"
+ dimensions: "cpu:x86-64"
+ dimensions: "normal:true"
+ dimensions: "os:Ubuntu-24.04"
+ dimensions: "pool:luci.r8.ci"
+ exe {
+ cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build"
+ cipd_version: "refs/heads/main"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "builder_group": "internal.client.r8",'
+ ' "recipe": "rex",'
+ ' "test_options": ['
+ ' "--dex_vm=7.0.0",'
+ ' "--all_tests",'
+ ' "--command_cache_dir=/tmp/ccache",'
+ ' "--tool=r8",'
+ ' "--print-times",'
+ ' "--no_internal",'
+ ' "--one_line_per_test",'
+ ' "--archive_failures"'
+ ' ]'
+ '}'
+ priority: 26
+ execution_timeout_secs: 21600
+ expiration_secs: 126000
+ build_numbers: YES
+ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+ experiments {
+ key: "luci.recipes.use_python3"
+ value: 100
+ }
+ }
+ builders {
+ name: "linux-android-7-noble_release"
+ swarming_host: "chrome-swarming.appspot.com"
+ swarming_tags: "vpython:native-python-wrapper"
+ dimensions: "cpu:x86-64"
+ dimensions: "normal:true"
+ dimensions: "os:Ubuntu-24.04"
+ dimensions: "pool:luci.r8.ci"
+ exe {
+ cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build"
+ cipd_version: "refs/heads/main"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "builder_group": "internal.client.r8",'
+ ' "recipe": "rex",'
+ ' "test_options": ['
+ ' "--dex_vm=7.0.0",'
+ ' "--all_tests",'
+ ' "--command_cache_dir=/tmp/ccache",'
+ ' "--tool=r8",'
+ ' "--print-times",'
+ ' "--no_internal",'
+ ' "--one_line_per_test",'
+ ' "--archive_failures"'
+ ' ]'
+ '}'
+ priority: 26
+ execution_timeout_secs: 21600
+ expiration_secs: 126000
+ build_numbers: YES
+ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+ experiments {
+ key: "luci.recipes.use_python3"
+ value: 100
+ }
+ }
+ builders {
name: "linux-android-7_release"
swarming_host: "chrome-swarming.appspot.com"
swarming_tags: "vpython:native-python-wrapper"
@@ -1191,6 +1267,80 @@
}
}
builders {
+ name: "linux-default-noble"
+ swarming_host: "chrome-swarming.appspot.com"
+ swarming_tags: "vpython:native-python-wrapper"
+ dimensions: "cpu:x86-64"
+ dimensions: "normal:true"
+ dimensions: "os:Ubuntu-24.04"
+ dimensions: "pool:luci.r8.ci"
+ exe {
+ cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build"
+ cipd_version: "refs/heads/main"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "builder_group": "internal.client.r8",'
+ ' "recipe": "rex",'
+ ' "test_options": ['
+ ' "--runtimes=dex-default",'
+ ' "--command_cache_dir=/tmp/ccache",'
+ ' "--tool=r8",'
+ ' "--print-times",'
+ ' "--no_internal",'
+ ' "--one_line_per_test",'
+ ' "--archive_failures"'
+ ' ]'
+ '}'
+ priority: 26
+ execution_timeout_secs: 21600
+ expiration_secs: 126000
+ build_numbers: YES
+ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+ experiments {
+ key: "luci.recipes.use_python3"
+ value: 100
+ }
+ }
+ builders {
+ name: "linux-default-noble_release"
+ swarming_host: "chrome-swarming.appspot.com"
+ swarming_tags: "vpython:native-python-wrapper"
+ dimensions: "cpu:x86-64"
+ dimensions: "normal:true"
+ dimensions: "os:Ubuntu-24.04"
+ dimensions: "pool:luci.r8.ci"
+ exe {
+ cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build"
+ cipd_version: "refs/heads/main"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "builder_group": "internal.client.r8",'
+ ' "recipe": "rex",'
+ ' "test_options": ['
+ ' "--runtimes=dex-default",'
+ ' "--command_cache_dir=/tmp/ccache",'
+ ' "--tool=r8",'
+ ' "--print-times",'
+ ' "--no_internal",'
+ ' "--one_line_per_test",'
+ ' "--archive_failures"'
+ ' ]'
+ '}'
+ priority: 26
+ execution_timeout_secs: 21600
+ expiration_secs: 126000
+ build_numbers: YES
+ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+ experiments {
+ key: "luci.recipes.use_python3"
+ value: 100
+ }
+ }
+ builders {
name: "linux-default_release"
swarming_host: "chrome-swarming.appspot.com"
swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/global/generated/luci-milo.cfg b/infra/config/global/generated/luci-milo.cfg
index 7ee27d7..1376a59 100644
--- a/infra/config/global/generated/luci-milo.cfg
+++ b/infra/config/global/generated/luci-milo.cfg
@@ -26,6 +26,11 @@
short_name: "default"
}
builders {
+ name: "buildbucket/luci.r8.ci/linux-default-noble"
+ category: "R8"
+ short_name: "noble"
+ }
+ builders {
name: "buildbucket/luci.r8.ci/linux-none"
category: "R8"
short_name: "none"
@@ -81,6 +86,11 @@
short_name: "7"
}
builders {
+ name: "buildbucket/luci.r8.ci/linux-android-7-noble"
+ category: "R8"
+ short_name: "noble"
+ }
+ builders {
name: "buildbucket/luci.r8.ci/linux-android-8"
category: "R8"
short_name: "8"
@@ -181,6 +191,11 @@
short_name: "default"
}
builders {
+ name: "buildbucket/luci.r8.ci/linux-default-noble_release"
+ category: "Release|R8"
+ short_name: "noble"
+ }
+ builders {
name: "buildbucket/luci.r8.ci/linux-none_release"
category: "Release|R8"
short_name: "none"
@@ -236,6 +251,11 @@
short_name: "7"
}
builders {
+ name: "buildbucket/luci.r8.ci/linux-android-7-noble_release"
+ category: "Release|R8"
+ short_name: "noble"
+ }
+ builders {
name: "buildbucket/luci.r8.ci/linux-android-8_release"
category: "Release|R8"
short_name: "8"
diff --git a/infra/config/global/generated/luci-notify.cfg b/infra/config/global/generated/luci-notify.cfg
index f072a67..e868b2c 100644
--- a/infra/config/global/generated/luci-notify.cfg
+++ b/infra/config/global/generated/luci-notify.cfg
@@ -288,6 +288,30 @@
}
builders {
bucket: "ci"
+ name: "linux-android-7-noble"
+ repository: "https://r8.googlesource.com/r8"
+ }
+}
+notifiers {
+ notifications {
+ on_failure: true
+ on_new_failure: true
+ notify_blamelist {}
+ }
+ builders {
+ bucket: "ci"
+ name: "linux-android-7-noble_release"
+ repository: "https://r8.googlesource.com/r8"
+ }
+}
+notifiers {
+ notifications {
+ on_failure: true
+ on_new_failure: true
+ notify_blamelist {}
+ }
+ builders {
+ bucket: "ci"
name: "linux-android-7_release"
repository: "https://r8.googlesource.com/r8"
}
@@ -360,6 +384,30 @@
}
builders {
bucket: "ci"
+ name: "linux-default-noble"
+ repository: "https://r8.googlesource.com/r8"
+ }
+}
+notifiers {
+ notifications {
+ on_failure: true
+ on_new_failure: true
+ notify_blamelist {}
+ }
+ builders {
+ bucket: "ci"
+ name: "linux-default-noble_release"
+ repository: "https://r8.googlesource.com/r8"
+ }
+}
+notifiers {
+ notifications {
+ on_failure: true
+ on_new_failure: true
+ notify_blamelist {}
+ }
+ builders {
+ bucket: "ci"
name: "linux-default_release"
repository: "https://r8.googlesource.com/r8"
}
diff --git a/infra/config/global/generated/luci-scheduler.cfg b/infra/config/global/generated/luci-scheduler.cfg
index 04e6f0f..d7f8189 100644
--- a/infra/config/global/generated/luci-scheduler.cfg
+++ b/infra/config/global/generated/luci-scheduler.cfg
@@ -384,6 +384,35 @@
}
}
job {
+ id: "linux-android-7-noble"
+ realm: "ci"
+ acl_sets: "ci"
+ triggering_policy {
+ kind: GREEDY_BATCHING
+ max_concurrent_invocations: 1
+ }
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "ci"
+ builder: "linux-android-7-noble"
+ }
+}
+job {
+ id: "linux-android-7-noble_release"
+ realm: "ci"
+ acl_sets: "ci"
+ triggering_policy {
+ kind: GREEDY_BATCHING
+ max_concurrent_invocations: 1
+ max_batch_size: 1
+ }
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "ci"
+ builder: "linux-android-7-noble_release"
+ }
+}
+job {
id: "linux-android-7_release"
realm: "ci"
acl_sets: "ci"
@@ -471,6 +500,35 @@
}
}
job {
+ id: "linux-default-noble"
+ realm: "ci"
+ acl_sets: "ci"
+ triggering_policy {
+ kind: GREEDY_BATCHING
+ max_concurrent_invocations: 1
+ }
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "ci"
+ builder: "linux-default-noble"
+ }
+}
+job {
+ id: "linux-default-noble_release"
+ realm: "ci"
+ acl_sets: "ci"
+ triggering_policy {
+ kind: GREEDY_BATCHING
+ max_concurrent_invocations: 1
+ max_batch_size: 1
+ }
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "ci"
+ builder: "linux-default-noble_release"
+ }
+}
+job {
id: "linux-default_release"
realm: "ci"
acl_sets: "ci"
@@ -866,9 +924,11 @@
triggers: "linux-android-4.4_release"
triggers: "linux-android-5_release"
triggers: "linux-android-6_release"
+ triggers: "linux-android-7-noble_release"
triggers: "linux-android-7_release"
triggers: "linux-android-8_release"
triggers: "linux-android-9_release"
+ triggers: "linux-default-noble_release"
triggers: "linux-default_release"
triggers: "linux-internal_release"
triggers: "linux-jdk11_release"
@@ -901,9 +961,11 @@
triggers: "linux-android-5"
triggers: "linux-android-6"
triggers: "linux-android-7"
+ triggers: "linux-android-7-noble"
triggers: "linux-android-8"
triggers: "linux-android-9"
triggers: "linux-default"
+ triggers: "linux-default-noble"
triggers: "linux-dev"
triggers: "linux-internal"
triggers: "linux-jdk11"
diff --git a/infra/config/global/generated/project.cfg b/infra/config/global/generated/project.cfg
index ade4005..ede4677 100644
--- a/infra/config/global/generated/project.cfg
+++ b/infra/config/global/generated/project.cfg
@@ -7,7 +7,7 @@
name: "r8"
access: "group:all"
lucicfg {
- version: "1.44.1"
+ version: "1.45.0"
package_dir: ".."
config_dir: "generated"
entry_point: "main.star"
diff --git a/infra/config/global/main.star b/infra/config/global/main.star
index 41a31c4..e0e07e5 100755
--- a/infra/config/global/main.star
+++ b/infra/config/global/main.star
@@ -168,7 +168,7 @@
default_timeout = time.hour * 6
-def get_dimensions(windows = False, internal = False, archive = False):
+def get_dimensions(windows = False, internal = False, archive = False, noble=False):
# We use the following setup:
# windows -> always windows machine
# internal -> always internal, single small, machine
@@ -181,7 +181,10 @@
if windows:
dimensions["os"] = "Windows-10"
else:
- dimensions["os"] = "Ubuntu-20.04"
+ if noble:
+ dimensions["os"] = "Ubuntu-24.04"
+ else:
+ dimensions["os"] = "Ubuntu-20.04"
if internal:
dimensions["internal"] = "true"
elif archive:
@@ -362,6 +365,11 @@
max_concurrent_invocations = 2,
)
r8_tester_with_default(
+ "linux-default-noble",
+ ["--runtimes=dex-default", "--command_cache_dir=/tmp/ccache"],
+ dimensions = get_dimensions(noble=True),
+)
+r8_tester_with_default(
"linux-none",
["--runtimes=none", "--command_cache_dir=/tmp/ccache"],
max_concurrent_invocations = 2,
@@ -409,6 +417,13 @@
"linux-android-7",
["--dex_vm=7.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"],
)
+
+r8_tester_with_default(
+ "linux-android-7-noble",
+ ["--dex_vm=7.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"],
+ dimensions = get_dimensions(noble=True),
+)
+
r8_tester_with_default(
"linux-android-8",
["--dex_vm=8.1.0", "--all_tests", "--command_cache_dir=/tmp/ccache"],
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index a3b18e5..fbaa1ec 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -84,7 +84,7 @@
MainDexRootSet mainDexRootSet =
MainDexRootSet.builder(
appView, profileCollectionAdditions, subtypingInfo, options.mainDexKeepRules)
- .build(executor);
+ .evaluateRulesAndBuild(executor);
appView.setMainDexRootSet(mainDexRootSet);
GraphConsumer graphConsumer = options.mainDexKeptGraphConsumer;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index b148ad9..57d52fa 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -372,8 +372,9 @@
Iterables.concat(
options.getProguardConfiguration().getRules(), synthesizedProguardRules))
.setAssumeInfoCollectionBuilder(assumeInfoCollectionBuilder)
+ .evaluateRules(executorService)
.tracePartialCompilationDexingOutputClasses(executorService)
- .build(executorService));
+ .build());
appView.setAssumeInfoCollection(assumeInfoCollectionBuilder.build());
// Compute the main dex rootset that will be the base of first and final main dex tracing
@@ -384,7 +385,7 @@
MainDexRootSet mainDexRootSet =
MainDexRootSet.builder(
appView, profileCollectionAdditions, subtypingInfo, options.mainDexKeepRules)
- .build(executorService);
+ .evaluateRulesAndBuild(executorService);
appView.setMainDexRootSet(mainDexRootSet);
appView.appInfo().unsetObsolete();
}
diff --git a/src/main/java/com/android/tools/r8/R8Partial.java b/src/main/java/com/android/tools/r8/R8Partial.java
index 2b104b9..e412af4 100644
--- a/src/main/java/com/android/tools/r8/R8Partial.java
+++ b/src/main/java/com/android/tools/r8/R8Partial.java
@@ -178,6 +178,7 @@
.addLibraryResourceProvider(
new InternalClasspathOrLibraryClassProvider<>(d8Result.getOutputLibraryClasses()))
.enableLegacyFullModeForKeepRules(true)
+ .setBuildMetadataConsumer(options.r8BuildMetadataConsumer)
.setEnableExperimentalMissingLibraryApiModeling(
options.apiModelingOptions().isApiModelingEnabled())
.setMinApiLevel(options.getMinApiLevel().getLevel())
diff --git a/src/main/java/com/android/tools/r8/graph/ClassDefinition.java b/src/main/java/com/android/tools/r8/graph/ClassDefinition.java
index a021545..9fd1f91 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassDefinition.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassDefinition.java
@@ -34,12 +34,4 @@
default boolean isClass() {
return true;
}
-
- boolean isClasspathClass();
-
- DexClasspathClass asClasspathClass();
-
- boolean isLibraryClass();
-
- DexLibraryClass asLibraryClass();
}
diff --git a/src/main/java/com/android/tools/r8/graph/ClasspathDefinition.java b/src/main/java/com/android/tools/r8/graph/ClasspathDefinition.java
index 43a4e70..8516fbd 100644
--- a/src/main/java/com/android/tools/r8/graph/ClasspathDefinition.java
+++ b/src/main/java/com/android/tools/r8/graph/ClasspathDefinition.java
@@ -21,4 +21,14 @@
default ProgramDerivedContext asProgramDerivedContext(ProgramDerivedContext witness) {
return ClasspathOrLibraryContext.create(this, witness);
}
+
+ @Override
+ default boolean isClasspathDefinition() {
+ return true;
+ }
+
+ @Override
+ default ClasspathDefinition asClasspathDefinition() {
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/graph/Definition.java b/src/main/java/com/android/tools/r8/graph/Definition.java
index e03b8e8..835d298 100644
--- a/src/main/java/com/android/tools/r8/graph/Definition.java
+++ b/src/main/java/com/android/tools/r8/graph/Definition.java
@@ -76,6 +76,22 @@
return null;
}
+ default boolean isClasspathClass() {
+ return false;
+ }
+
+ default DexClasspathClass asClasspathClass() {
+ return null;
+ }
+
+ default boolean isClasspathDefinition() {
+ return false;
+ }
+
+ default ClasspathDefinition asClasspathDefinition() {
+ return null;
+ }
+
default boolean isClasspathField() {
return false;
}
@@ -96,6 +112,18 @@
return null;
}
+ default boolean isLibraryClass() {
+ return false;
+ }
+
+ default DexLibraryClass asLibraryClass() {
+ return null;
+ }
+
+ default boolean isLibraryDefinition() {
+ return false;
+ }
+
default boolean isLibraryField() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index e8bc0b7..db3a696 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -675,28 +675,8 @@
return this;
}
- @Override
- public boolean isClasspathClass() {
- return false;
- }
-
- @Override
- public DexClasspathClass asClasspathClass() {
- return null;
- }
-
public abstract boolean isNotProgramClass();
- @Override
- public boolean isLibraryClass() {
- return false;
- }
-
- @Override
- public DexLibraryClass asLibraryClass() {
- return null;
- }
-
public boolean isPrivate() {
return accessFlags.isPrivate();
}
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureContextBuilder.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureContextBuilder.java
index 84bd5a1..0b901df 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureContextBuilder.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureContextBuilder.java
@@ -142,7 +142,8 @@
}
Map<DexReference, TypeParameterSubstitutions> formalsInfo = new IdentityHashMap<>();
Map<DexReference, DexReference> enclosingInfo = new IdentityHashMap<>();
- programClasses.forEach(
+ WorkList<DexClass> worklist = WorkList.newIdentityWorkList(programClasses);
+ worklist.process(
clazz -> {
// Build up a map of type variables to bounds for every reference such that we can
// lookup the information even after we prune the generic signatures.
@@ -150,7 +151,7 @@
formalsInfo.put(
clazz.getReference(),
TypeParameterSubstitutions.create(clazz.classSignature.getFormalTypeParameters()));
- clazz.forEachProgramMethod(
+ clazz.forEachClassMethod(
method -> {
MethodTypeSignature methodSignature =
method.getDefinition().getGenericSignature();
@@ -165,8 +166,15 @@
// Build up an enclosing class context such that the enclosing class can be looked up
// even after inner class and enclosing method attribute attributes are removed.
InnerClassAttribute innerClassAttribute = clazz.getInnerClassAttributeForThisClass();
- if (innerClassAttribute != null) {
+ if (innerClassAttribute != null && innerClassAttribute.getOuter() != null) {
enclosingInfo.put(clazz.getType(), innerClassAttribute.getOuter());
+ DexClass outerClass =
+ appView
+ .appInfo()
+ .definitionForWithoutExistenceAssert(innerClassAttribute.getOuter());
+ if (outerClass != null) {
+ worklist.addIfNotSeen(outerClass);
+ }
}
EnclosingMethodAttribute enclosingMethodAttribute = clazz.getEnclosingMethodAttribute();
if (enclosingMethodAttribute != null) {
diff --git a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
index 5328880..88205c7 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
@@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.util.Collections;
+import java.util.Comparator;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
@@ -260,7 +261,7 @@
}
String joined =
javaLibraryOverride.stream()
- .sorted()
+ .sorted(Comparator.comparing(DexClass::getType))
.map(clazz -> clazz.toSourceString() + " (origin: " + clazz.getOrigin() + ")")
.collect(Collectors.joining(", "));
String message =
diff --git a/src/main/java/com/android/tools/r8/graph/LibraryDefinition.java b/src/main/java/com/android/tools/r8/graph/LibraryDefinition.java
index 6767199..0dee6e9 100644
--- a/src/main/java/com/android/tools/r8/graph/LibraryDefinition.java
+++ b/src/main/java/com/android/tools/r8/graph/LibraryDefinition.java
@@ -20,4 +20,9 @@
default ProgramDerivedContext asProgramDerivedContext(ProgramDerivedContext witness) {
return ClasspathOrLibraryContext.create(this, witness);
}
+
+ @Override
+ default boolean isLibraryDefinition() {
+ return true;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstantValueUtils.java b/src/main/java/com/android/tools/r8/ir/code/ConstantValueUtils.java
index b75e839..d94abb1 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstantValueUtils.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstantValueUtils.java
@@ -4,8 +4,9 @@
package com.android.tools.r8.ir.code;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.naming.IdentifierNameStringUtils;
@@ -17,7 +18,7 @@
* Otherwise returns null. This should only be used for tracing.
*/
public static DexType getDexTypeRepresentedByValueForTracing(
- Value value, DexDefinitionSupplier definitions) {
+ Value value, AppView<? extends AppInfoWithClassHierarchy> appView) {
Value alias =
value.getAliasedValue(IgnoreDebugLocalWriteAliasedValueConfiguration.getInstance());
if (alias.isPhi()) {
@@ -30,9 +31,11 @@
if (alias.definition.isInvokeStatic()) {
InvokeStatic invoke = alias.definition.asInvokeStatic();
- if (definitions.dexItemFactory().classMethods
+ if (appView
+ .dexItemFactory()
+ .classMethods
.isReflectiveClassLookup(invoke.getInvokedMethod())) {
- return getDexTypeFromClassForName(invoke, definitions);
+ return getDexTypeFromClassForName(invoke, appView);
}
}
@@ -40,24 +43,23 @@
}
public static DexClass getClassFromClassForName(
- InvokeStatic invoke, DexDefinitionSupplier definitions) {
- DexType type = getDexTypeFromClassForName(invoke, definitions);
+ InvokeStatic invoke, AppView<? extends AppInfoWithClassHierarchy> appView) {
+ DexType type = getDexTypeFromClassForName(invoke, appView);
if (type != null && type.isClassType()) {
- return definitions.definitionFor(type);
+ return appView.definitionFor(type);
}
return null;
}
public static DexType getDexTypeFromClassForName(
- InvokeStatic invoke, DexDefinitionSupplier definitions) {
- assert definitions.dexItemFactory().classMethods
- .isReflectiveClassLookup(invoke.getInvokedMethod());
+ InvokeStatic invoke, AppView<? extends AppInfoWithClassHierarchy> appView) {
+ assert appView.dexItemFactory().classMethods.isReflectiveClassLookup(invoke.getInvokedMethod());
if (invoke.arguments().size() == 1 || invoke.arguments().size() == 3) {
Value argument = invoke.arguments().get(0);
if (argument.isConstString()) {
ConstString constStringInstruction = argument.getConstInstruction().asConstString();
- return IdentifierNameStringUtils.inferTypeFromNameString(
- definitions, constStringInstruction.getValue());
+ return IdentifierNameStringUtils.inferClassTypeFromNameString(
+ appView, constStringInstruction.getValue());
}
if (argument.isDexItemBasedConstString()) {
DexItemBasedConstString constStringInstruction =
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/AutoCloseableRetargeterHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/AutoCloseableRetargeterHelper.java
index a986672..3e41d2f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/AutoCloseableRetargeterHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/AutoCloseableRetargeterHelper.java
@@ -199,8 +199,15 @@
factory.voidType, factory.javaUtilConcurrentExecutorServiceType))
.setCode(
methodSig ->
- BackportedMethods.ExecutorServiceMethods_closeExecutorService(
- factory, methodSig)));
+ appView
+ .options()
+ .getMinApiLevel()
+ .isGreaterThanOrEqualTo(AndroidApiLevel.N)
+ ? BackportedMethods
+ .ExecutorServiceMethods_closeExecutorServiceNPlus(
+ factory, methodSig)
+ : BackportedMethods.ExecutorServiceMethods_closeExecutorService(
+ factory, methodSig)));
eventConsumer.acceptAutoCloseableForwardingMethod(method, context);
return method.getReference();
}
diff --git a/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java b/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java
index 0c81115..256e9d2 100644
--- a/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java
+++ b/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.metadata.impl.R8KeepAttributesMetadataImpl;
import com.android.tools.r8.metadata.impl.R8LibraryDesugaringMetadataImpl;
import com.android.tools.r8.metadata.impl.R8OptionsMetadataImpl;
+import com.android.tools.r8.metadata.impl.R8PartialCompilationMetadataImpl;
import com.android.tools.r8.metadata.impl.R8ResourceOptimizationMetadataImpl;
import com.android.tools.r8.metadata.impl.R8StartupOptimizationMetadataImpl;
import com.android.tools.r8.metadata.impl.R8StatsMetadataImpl;
@@ -46,6 +47,9 @@
.registerTypeAdapter(
R8LibraryDesugaringMetadata.class, deserializeTo(R8LibraryDesugaringMetadataImpl.class))
.registerTypeAdapter(
+ R8PartialCompilationMetadata.class,
+ deserializeTo(R8PartialCompilationMetadataImpl.class))
+ .registerTypeAdapter(
R8ResourceOptimizationMetadata.class,
deserializeTo(R8ResourceOptimizationMetadataImpl.class))
.registerTypeAdapter(
@@ -80,6 +84,11 @@
R8FeatureSplitsMetadata getFeatureSplitsMetadata();
/**
+ * @return null if not using partial compilation.
+ */
+ R8PartialCompilationMetadata getPartialCompilationMetadata();
+
+ /**
* @return null if resource optimization is disabled.
*/
R8ResourceOptimizationMetadata getResourceOptimizationMetadata();
diff --git a/src/main/java/com/android/tools/r8/metadata/R8PartialCompilationMetadata.java b/src/main/java/com/android/tools/r8/metadata/R8PartialCompilationMetadata.java
new file mode 100644
index 0000000..99cf1a3
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/metadata/R8PartialCompilationMetadata.java
@@ -0,0 +1,6 @@
+// Copyright (c) 2025, 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.metadata;
+
+public interface R8PartialCompilationMetadata {}
diff --git a/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java b/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java
index 870e566..ecead83 100644
--- a/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java
+++ b/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java
@@ -57,6 +57,7 @@
builder ->
builder.setFeatureSplitsMetadata(
R8FeatureSplitsMetadataImpl.create(appView, virtualFilesForFeatureSplit)))
+ .setPartialCompilationMetadata(R8PartialCompilationMetadataImpl.create(options))
.setResourceOptimizationOptions(R8ResourceOptimizationMetadataImpl.create(options))
.setStartupOptimizationOptions(R8StartupOptimizationMetadataImpl.create(options))
.setStatsMetadata(R8StatsMetadataImpl.create(appView))
diff --git a/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java b/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java
index 2abfbdc..ea6cec6 100644
--- a/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java
+++ b/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.metadata.R8DexFileMetadata;
import com.android.tools.r8.metadata.R8FeatureSplitsMetadata;
import com.android.tools.r8.metadata.R8OptionsMetadata;
+import com.android.tools.r8.metadata.R8PartialCompilationMetadata;
import com.android.tools.r8.metadata.R8ResourceOptimizationMetadata;
import com.android.tools.r8.metadata.R8StartupOptimizationMetadata;
import com.android.tools.r8.metadata.R8StatsMetadata;
@@ -60,6 +61,10 @@
private final R8FeatureSplitsMetadata featureSplitsMetadata;
@Expose
+ @SerializedName("partialCompilation")
+ private final R8PartialCompilationMetadata partialCompilationMetadata;
+
+ @Expose
@SerializedName("resourceOptimization")
private final R8ResourceOptimizationMetadata resourceOptimizationMetadata;
@@ -78,6 +83,7 @@
List<R8DexFileMetadata> dexFilesMetadata,
R8StatsMetadata statsMetadata,
R8FeatureSplitsMetadata featureSplitsMetadata,
+ R8PartialCompilationMetadata partialCompilationMetadata,
R8ResourceOptimizationMetadata resourceOptimizationMetadata,
R8StartupOptimizationMetadata startupOptimizationMetadata,
String version) {
@@ -87,6 +93,7 @@
this.dexFilesMetadata = dexFilesMetadata;
this.statsMetadata = statsMetadata;
this.featureSplitsMetadata = featureSplitsMetadata;
+ this.partialCompilationMetadata = partialCompilationMetadata;
this.resourceOptimizationMetadata = resourceOptimizationMetadata;
this.startupOptimizationMetadata = startupOptimizationMetadata;
this.version = version;
@@ -122,6 +129,11 @@
}
@Override
+ public R8PartialCompilationMetadata getPartialCompilationMetadata() {
+ return partialCompilationMetadata;
+ }
+
+ @Override
public R8ResourceOptimizationMetadata getResourceOptimizationMetadata() {
return resourceOptimizationMetadata;
}
@@ -154,6 +166,7 @@
private List<R8DexFileMetadata> dexFilesMetadata;
private R8StatsMetadata statsMetadata;
private R8FeatureSplitsMetadata featureSplitsMetadata;
+ private R8PartialCompilationMetadata partialCompilationMetadata;
private R8ResourceOptimizationMetadata resourceOptimizationOptions;
private R8StartupOptimizationMetadata startupOptimizationOptions;
private String version;
@@ -196,6 +209,12 @@
return this;
}
+ public Builder setPartialCompilationMetadata(
+ R8PartialCompilationMetadata partialCompilationMetadata) {
+ this.partialCompilationMetadata = partialCompilationMetadata;
+ return this;
+ }
+
public Builder setResourceOptimizationOptions(
R8ResourceOptimizationMetadata resourceOptimizationOptions) {
this.resourceOptimizationOptions = resourceOptimizationOptions;
@@ -221,6 +240,7 @@
dexFilesMetadata,
statsMetadata,
featureSplitsMetadata,
+ partialCompilationMetadata,
resourceOptimizationOptions,
startupOptimizationOptions,
version);
diff --git a/src/main/java/com/android/tools/r8/metadata/impl/R8PartialCompilationMetadataImpl.java b/src/main/java/com/android/tools/r8/metadata/impl/R8PartialCompilationMetadataImpl.java
new file mode 100644
index 0000000..efbc67a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/metadata/impl/R8PartialCompilationMetadataImpl.java
@@ -0,0 +1,32 @@
+// Copyright (c) 2025, 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.metadata.impl;
+
+import com.android.tools.r8.keepanno.annotations.AnnotationPattern;
+import com.android.tools.r8.keepanno.annotations.FieldAccessFlags;
+import com.android.tools.r8.keepanno.annotations.KeepConstraint;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.UsedByReflection;
+import com.android.tools.r8.metadata.R8PartialCompilationMetadata;
+import com.android.tools.r8.utils.InternalOptions;
+import com.google.gson.annotations.SerializedName;
+
+@UsedByReflection(
+ description = "Keep and preserve @SerializedName for correct (de)serialization",
+ constraints = {KeepConstraint.LOOKUP},
+ constrainAnnotations = @AnnotationPattern(constant = SerializedName.class),
+ kind = KeepItemKind.CLASS_AND_FIELDS,
+ fieldAccess = {FieldAccessFlags.PRIVATE},
+ fieldAnnotatedByClassConstant = SerializedName.class)
+public class R8PartialCompilationMetadataImpl implements R8PartialCompilationMetadata {
+
+ private R8PartialCompilationMetadataImpl() {}
+
+ public static R8PartialCompilationMetadataImpl create(InternalOptions options) {
+ if (options.partialSubCompilationConfiguration == null) {
+ return null;
+ }
+ return new R8PartialCompilationMetadataImpl();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/metadata/impl/R8StartupOptimizationMetadataImpl.java b/src/main/java/com/android/tools/r8/metadata/impl/R8StartupOptimizationMetadataImpl.java
index 9e513b4..10a564f 100644
--- a/src/main/java/com/android/tools/r8/metadata/impl/R8StartupOptimizationMetadataImpl.java
+++ b/src/main/java/com/android/tools/r8/metadata/impl/R8StartupOptimizationMetadataImpl.java
@@ -39,7 +39,7 @@
public static R8StartupOptimizationMetadataImpl create(InternalOptions options) {
StartupOptions startupOptions = options.getStartupOptions();
- if (startupOptions.getStartupProfileProviders().isEmpty()) {
+ if (!startupOptions.hasStartupProfileProviders()) {
return null;
}
return new R8StartupOptimizationMetadataImpl(startupOptions);
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
index ac6868b..0b20716 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMember;
@@ -104,10 +105,11 @@
return;
}
DexString original = staticValue.getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appView(), original);
+ Definition itemBasedString = inferMemberOrTypeFromNameString(appView(), original);
if (itemBasedString != null) {
encodedField.setStaticValue(
- new DexItemBasedValueString(itemBasedString, ClassNameComputationInfo.none()));
+ new DexItemBasedValueString(
+ itemBasedString.getReference(), ClassNameComputationInfo.none()));
}
}
@@ -176,13 +178,13 @@
return null;
}
DexString original = in.getConstInstruction().asConstString().getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appView(), original);
+ Definition itemBasedString = inferMemberOrTypeFromNameString(appView(), original);
if (itemBasedString == null) {
warnUndeterminedIdentifierIfNecessary(
field, code.context(), fieldPut.asFieldInstruction(), original);
return null;
}
- return itemBasedString;
+ return itemBasedString.getReference();
}
private InstructionListIterator decoupleIdentifierNameStringForFieldPutInstruction(
@@ -245,7 +247,7 @@
Value[] changes = new Value[ins.size()];
if (isReflectionMethod(appView.dexItemFactory(), invokedMethod) || isClassNameComparison) {
IdentifierNameStringLookupResult<?> identifierLookupResult =
- identifyIdentifier(invoke, appView, code.context());
+ identifyIdentifier(invoke, appView(), code.context());
if (identifierLookupResult == null) {
warnUndeterminedIdentifierIfNecessary(invokedMethod, code.context(), invoke, null);
return iterator;
@@ -312,12 +314,15 @@
// For general invoke. Multiple arguments can be string literals to be renamed.
for (int i = 0; i < ins.size(); i++) {
Value in = ins.get(i);
+ if (in.getType().isNullType()) {
+ continue;
+ }
if (!in.isConstString()) {
warnUndeterminedIdentifierIfNecessary(invokedMethod, code.context(), invoke, null);
continue;
}
DexString original = in.getConstInstruction().asConstString().getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appView(), original);
+ Definition itemBasedString = inferMemberOrTypeFromNameString(appView(), original);
if (itemBasedString == null) {
warnUndeterminedIdentifierIfNecessary(invokedMethod, code.context(), invoke, original);
continue;
@@ -328,7 +333,8 @@
// Prepare $decoupled just before $invoke
Value newIn = code.createValue(in.getType(), in.getLocalInfo());
DexItemBasedConstString decoupled =
- new DexItemBasedConstString(newIn, itemBasedString, ClassNameComputationInfo.none());
+ new DexItemBasedConstString(
+ newIn, itemBasedString.getReference(), ClassNameComputationInfo.none());
decoupled.setPosition(invoke.getPosition());
changes[i] = newIn;
// If the current block has catch handler, split into two blocks.
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java
index f312d7d..9e232c0 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java
@@ -5,14 +5,14 @@
import static com.android.tools.r8.utils.DescriptorUtils.javaTypeToDescriptorIfValidJavaType;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexDefinitionSupplier;
-import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexClassAndField;
+import com.android.tools.r8.graph.DexClassAndMember;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
@@ -33,7 +33,6 @@
import com.android.tools.r8.ir.code.NewArrayFilled;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.naming.identifiernamestring.IdentifierNameStringLookupResult;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.Sets;
import java.util.ArrayList;
@@ -199,15 +198,17 @@
* Returns a {@link DexReference} if one of the arguments to the invoke instruction is a constant
* string that corresponds to either a class or member name (i.e., an identifier).
*
- * @param definitions {@link DexDefinitionSupplier} that gives access to {@link DexItemFactory}.
+ * @param appView {@link AppView} that gives access to {@link DexItemFactory}.
* @param invoke {@link InvokeMethod} that is expected to have an identifier in its arguments.
* @return {@link DexReference} corresponding to the first constant string argument that matches a
* class or member name, or {@code null} if no such constant was found.
*/
@SuppressWarnings("ReferenceEquality")
public static IdentifierNameStringLookupResult<?> identifyIdentifier(
- InvokeMethod invoke, DexDefinitionSupplier definitions, ProgramMethod context) {
- DexItemFactory dexItemFactory = definitions.dexItemFactory();
+ InvokeMethod invoke,
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ ProgramMethod context) {
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
List<Value> ins = invoke.arguments();
// The only static calls: Class#forName,
// which receive either (String) or (String, boolean, ClassLoader) as ins.
@@ -215,7 +216,7 @@
InvokeStatic invokeStatic = invoke.asInvokeStatic();
if (dexItemFactory.classMethods.isReflectiveClassLookup(invokeStatic.getInvokedMethod())) {
return IdentifierNameStringLookupResult.fromClassForName(
- ConstantValueUtils.getDexTypeFromClassForName(invokeStatic, definitions));
+ ConstantValueUtils.getDexTypeFromClassForName(invokeStatic, appView));
}
}
@@ -225,8 +226,7 @@
int argumentIndex = getPositionOfFirstConstString(invokeVirtual);
if (argumentIndex >= 0) {
return IdentifierNameStringLookupResult.fromClassNameComparison(
- inferTypeFromConstStringValue(
- definitions, invokeVirtual.inValues().get(argumentIndex)));
+ inferTypeFromConstStringValue(appView, invokeVirtual.inValues().get(argumentIndex)));
}
}
}
@@ -251,7 +251,7 @@
// declared in the library. Hence there is no need to handle this case.
return null;
}
- DexClass holder = definitions.definitionFor(holderType, context);
+ DexClass holder = appView.definitionFor(holderType, context);
if (holder == null) {
return null;
}
@@ -301,34 +301,42 @@
return -1;
}
- static DexReference inferMemberOrTypeFromNameString(
- AppView<AppInfoWithLiveness> appView, DexString dexString) {
+ public static Definition inferMemberOrTypeFromNameString(
+ AppView<? extends AppInfoWithClassHierarchy> appView, DexString dexString) {
// "fully.qualified.ClassName.fieldOrMethodName"
// "fully.qualified.ClassName#fieldOrMethodName"
- DexMember<?, ?> itemBasedString = inferMemberFromNameString(appView, dexString);
- if (itemBasedString == null) {
- // "fully.qualified.ClassName"
- return inferTypeFromNameString(appView, dexString);
+ DexClassAndMember<?, ?> member = inferMemberFromNameString(appView, dexString);
+ if (member != null) {
+ return member;
}
- return itemBasedString;
+ // "fully.qualified.ClassName"
+ DexType type = inferClassTypeFromNameString(appView, dexString);
+ if (type != null) {
+ return appView.appInfo().definitionForWithoutExistenceAssert(type);
+ }
+ return null;
}
- public static DexType inferTypeFromNameString(
- DexDefinitionSupplier definitions, DexString dexString) {
+ public static DexType inferClassTypeFromNameString(
+ AppView<? extends AppInfoWithClassHierarchy> appView, DexString dexString) {
String maybeDescriptor = javaTypeToDescriptorIfValidJavaType(dexString.toString());
- if (maybeDescriptor != null) {
- return definitions.dexItemFactory().createType(maybeDescriptor);
+ if (maybeDescriptor == null) {
+ return null;
+ }
+ DexType type = appView.dexItemFactory().createType(maybeDescriptor);
+ if (type.isClassType()) {
+ return type;
}
return null;
}
public static DexType inferTypeFromConstStringValue(
- DexDefinitionSupplier definitions, Value value) {
+ AppView<? extends AppInfoWithClassHierarchy> appView, Value value) {
Value root = value.getAliasedValue();
assert !root.isPhi();
assert root.isConstString() || root.isDexItemBasedConstString();
if (root.isConstString()) {
- return inferTypeFromNameString(definitions, root.definition.asConstString().getValue());
+ return inferClassTypeFromNameString(appView, root.definition.asConstString().getValue());
}
if (root.isDexItemBasedConstString()) {
DexReference reference = root.definition.asDexItemBasedConstString().getItem();
@@ -339,8 +347,8 @@
return null;
}
- private static DexMember<?, ?> inferMemberFromNameString(
- AppView<AppInfoWithLiveness> appView, DexString dexString) {
+ private static DexClassAndMember<?, ?> inferMemberFromNameString(
+ AppView<? extends AppInfoWithClassHierarchy> appView, DexString dexString) {
String identifier = dexString.toString();
String typeIdentifier = null;
String memberIdentifier = null;
@@ -374,40 +382,39 @@
if (holder == null) {
return null;
}
- DexMember<?, ?> itemBasedString = inferFieldInHolder(holder, memberIdentifier, null);
- if (itemBasedString == null) {
- itemBasedString = inferMethodNameInHolder(holder, memberIdentifier);
+ DexClassAndField itemBasedString = inferFieldInHolder(holder, memberIdentifier, null);
+ if (itemBasedString != null) {
+ return itemBasedString;
}
- return itemBasedString;
+ return inferMethodNameInHolder(holder, memberIdentifier);
}
- @SuppressWarnings("ReferenceEquality")
- private static DexField inferFieldInHolder(DexClass holder, String name, DexType fieldType) {
- for (DexEncodedField encodedField : holder.fields()) {
- if (encodedField.getReference().name.toString().equals(name)
- && (fieldType == null || encodedField.getReference().type == fieldType)) {
- return encodedField.getReference();
+ private static DexClassAndField inferFieldInHolder(
+ DexClass holder, String name, DexType fieldType) {
+ for (DexClassAndField field : holder.classFields()) {
+ if (field.getName().isEqualTo(name)
+ && (fieldType == null || field.getType().isIdenticalTo(fieldType))) {
+ return field;
}
}
return null;
}
- private static DexMethod inferMethodNameInHolder(DexClass holder, String name) {
- for (DexEncodedMethod encodedMethod : holder.methods()) {
- if (encodedMethod.getReference().name.toString().equals(name)) {
- return encodedMethod.getReference();
+ private static DexClassAndMethod inferMethodNameInHolder(DexClass holder, String name) {
+ for (DexClassAndMethod method : holder.classMethods()) {
+ if (method.getName().isEqualTo(name)) {
+ return method;
}
}
return null;
}
- private static DexMethod inferMethodInHolder(
+ private static DexClassAndMethod inferMethodInHolder(
DexClass holder, String name, DexTypeList arguments) {
assert arguments != null;
- for (DexEncodedMethod encodedMethod : holder.methods()) {
- if (encodedMethod.getReference().name.toString().equals(name)
- && encodedMethod.getReference().proto.parameters.equals(arguments)) {
- return encodedMethod.getReference();
+ for (DexClassAndMethod method : holder.classMethods()) {
+ if (method.getName().isEqualTo(name) && method.getParameters().equals(arguments)) {
+ return method;
}
}
return null;
diff --git a/src/main/java/com/android/tools/r8/naming/identifiernamestring/DexMemberBasedConstStringIdentifierNameStringLookupResult.java b/src/main/java/com/android/tools/r8/naming/identifiernamestring/DexMemberBasedConstStringIdentifierNameStringLookupResult.java
index 5072d35..4292714 100644
--- a/src/main/java/com/android/tools/r8/naming/identifiernamestring/DexMemberBasedConstStringIdentifierNameStringLookupResult.java
+++ b/src/main/java/com/android/tools/r8/naming/identifiernamestring/DexMemberBasedConstStringIdentifierNameStringLookupResult.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.naming.identifiernamestring;
+import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.DexMember;
public class DexMemberBasedConstStringIdentifierNameStringLookupResult
@@ -12,4 +13,8 @@
DexMemberBasedConstStringIdentifierNameStringLookupResult(DexMember<?, ?> member) {
super(member);
}
+
+ DexMemberBasedConstStringIdentifierNameStringLookupResult(DexClassAndMember<?, ?> member) {
+ super(member.getReference());
+ }
}
diff --git a/src/main/java/com/android/tools/r8/naming/identifiernamestring/IdentifierNameStringLookupResult.java b/src/main/java/com/android/tools/r8/naming/identifiernamestring/IdentifierNameStringLookupResult.java
index 2c11771..7c4eb6e 100644
--- a/src/main/java/com/android/tools/r8/naming/identifiernamestring/IdentifierNameStringLookupResult.java
+++ b/src/main/java/com/android/tools/r8/naming/identifiernamestring/IdentifierNameStringLookupResult.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.utils.FunctionUtils.applyOrElse;
+import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
@@ -40,7 +41,7 @@
}
public static UncategorizedMemberIdentifierNameStringLookupResult fromUncategorized(
- DexMember<?, ?> member) {
+ DexClassAndMember<?, ?> member) {
return applyOrElse(member, UncategorizedMemberIdentifierNameStringLookupResult::new, null);
}
diff --git a/src/main/java/com/android/tools/r8/naming/identifiernamestring/UncategorizedMemberIdentifierNameStringLookupResult.java b/src/main/java/com/android/tools/r8/naming/identifiernamestring/UncategorizedMemberIdentifierNameStringLookupResult.java
index 5d29fc1..7226ca7 100644
--- a/src/main/java/com/android/tools/r8/naming/identifiernamestring/UncategorizedMemberIdentifierNameStringLookupResult.java
+++ b/src/main/java/com/android/tools/r8/naming/identifiernamestring/UncategorizedMemberIdentifierNameStringLookupResult.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.naming.identifiernamestring;
+import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.DexMember;
public class UncategorizedMemberIdentifierNameStringLookupResult
@@ -12,4 +13,8 @@
UncategorizedMemberIdentifierNameStringLookupResult(DexMember<?, ?> member) {
super(member);
}
+
+ UncategorizedMemberIdentifierNameStringLookupResult(DexClassAndMember<?, ?> member) {
+ super(member.getReference());
+ }
}
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
index e6203ea..1e01437 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexApplicationReadFlags;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClasspathClass;
@@ -303,7 +304,7 @@
}
}
- public boolean isD8Definition(ProgramDefinition definition) {
+ public boolean isD8Definition(Definition definition) {
return hasD8DefinitionFor(definition.getReference());
}
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialUseCollector.java b/src/main/java/com/android/tools/r8/partial/R8PartialUseCollector.java
index 6e30e4ee..5bdfdb9 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialUseCollector.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialUseCollector.java
@@ -12,10 +12,14 @@
import com.android.tools.r8.graph.DexClassAndField;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexValue;
+import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.naming.IdentifierNameStringUtils;
import com.android.tools.r8.partial.R8PartialSubCompilationConfiguration.R8PartialR8SubCompilationConfiguration;
import com.android.tools.r8.references.PackageReference;
import com.android.tools.r8.shaking.ProguardClassFilter;
@@ -40,21 +44,30 @@
public abstract class R8PartialUseCollector extends UseCollector {
+ private final Set<DexMember<?, ?>> identifierNameStrings;
private final ReflectiveIdentification reflectiveIdentification;
private final Set<DexReference> seenAllowObfuscation = ConcurrentHashMap.newKeySet();
private final Set<DexReference> seenDisallowObfuscation = ConcurrentHashMap.newKeySet();
private final Set<String> packagesToKeep = ConcurrentHashMap.newKeySet();
- public R8PartialUseCollector(AppView<? extends AppInfoWithClassHierarchy> appView) {
+ public R8PartialUseCollector(
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ Set<DexMember<?, ?>> identifierNameStrings) {
super(
appView,
new MissingReferencesConsumer(),
new NopDiagnosticsHandler(),
getTargetPredicate(appView));
+ this.identifierNameStrings = identifierNameStrings;
this.reflectiveIdentification =
new ReflectiveIdentification(
- appView, new KeepAllReflectiveIdentificationEventConsumer(this));
+ appView, new KeepAllReflectiveIdentificationEventConsumer(this), identifierNameStrings);
+ }
+
+ private static Predicate<DexType> getTargetPredicate(
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return type -> appView.definitionFor(type) != null;
}
@Override
@@ -62,9 +75,21 @@
return new KeepNativeMethodSignatureEventConsumer();
}
- public static Predicate<DexType> getTargetPredicate(
- AppView<? extends AppInfoWithClassHierarchy> appView) {
- return type -> appView.definitionFor(type) != null;
+ @Override
+ protected void traceFieldValue(ProgramField field) {
+ if (field.getAccessFlags().isStatic()
+ && field.getDefinition().hasExplicitStaticValue()
+ && identifierNameStrings.contains(field.getReference())) {
+ DexValue fieldValue = field.getDefinition().getStaticValue();
+ if (fieldValue.isDexValueString()) {
+ Definition definition =
+ IdentifierNameStringUtils.inferMemberOrTypeFromNameString(
+ appView, fieldValue.asDexValueString().getValue());
+ if (definition != null && isTargetType(definition.getContextType())) {
+ reflectiveIdentification.enqueue(field, definition);
+ }
+ }
+ }
}
public void run(ExecutorService executorService) throws ExecutionException {
diff --git a/src/main/java/com/android/tools/r8/shaking/ConvertCheckNotNullRule.java b/src/main/java/com/android/tools/r8/shaking/ConvertCheckNotNullRule.java
index 8dd9b27..479542a 100644
--- a/src/main/java/com/android/tools/r8/shaking/ConvertCheckNotNullRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ConvertCheckNotNullRule.java
@@ -80,7 +80,12 @@
}
@Override
- public boolean applyToNonProgramClasses() {
+ public boolean isApplicableToClasspathClasses() {
+ return true;
+ }
+
+ @Override
+ public boolean isApplicableToLibraryClasses() {
return true;
}
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 9788f61..f020f5c 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -2362,14 +2362,16 @@
unusedInterfaceTypes.computeIfAbsent(current, ignore -> Sets.newIdentityHashSet());
if (implementors.add(implementer)) {
for (DexType iface : current.getInterfaces()) {
- DexProgramClass definition = getProgramClassOrNull(iface, current);
- if (definition != null) {
- if (definition.isPublic()
- || implementer.getType().isSamePackage(definition.getType())) {
- worklist.addIfNotSeen(definition);
- } else {
- markTypeAsLive(current, implementer);
+ DexClass definition = definitionFor(iface, current);
+ if (definition == null) {
+ continue;
+ }
+ if (definition.isPublic() || implementer.getType().isSamePackage(definition.getType())) {
+ if (definition.isProgramClass()) {
+ worklist.addIfNotSeen(definition.asProgramClass());
}
+ } else {
+ markTypeAsLive(current, implementer);
}
}
}
@@ -4598,7 +4600,8 @@
amendWithCompanionMethods(rootSet.reprocess),
rootSet.alwaysClassInline,
joinIdentifierNameStrings(
- rootSet.identifierNameStrings, reflectiveIdentification.getIdentifierNameStrings()),
+ rootSet.identifierNameStrings,
+ reflectiveIdentification.getIdentifierNameStringAdditions()),
emptySet(),
prunedClasspathTypesBuilder.build(),
Collections.emptyMap(),
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeMayHaveSideEffectsRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeMayHaveSideEffectsRule.java
index 803ace4..5f2d2e9 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeMayHaveSideEffectsRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeMayHaveSideEffectsRule.java
@@ -77,7 +77,12 @@
}
@Override
- public boolean applyToNonProgramClasses() {
+ public boolean isApplicableToClasspathClasses() {
+ return true;
+ }
+
+ @Override
+ public boolean isApplicableToLibraryClasses() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java
index a224bed..57ce724 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardAssumeNoSideEffectRule.java
@@ -79,7 +79,12 @@
}
@Override
- public boolean applyToNonProgramClasses() {
+ public boolean isApplicableToClasspathClasses() {
+ return true;
+ }
+
+ @Override
+ public boolean isApplicableToLibraryClasses() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
index 2adc592..828ca04 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
@@ -193,7 +193,11 @@
return null;
}
- public boolean applyToNonProgramClasses() {
+ public boolean isApplicableToClasspathClasses() {
+ return false;
+ }
+
+ public boolean isApplicableToLibraryClasses() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java
index 56f431d..db4e0f6 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardIdentifierNameStringRule.java
@@ -75,8 +75,12 @@
}
@Override
+ public boolean isApplicableToClasspathClasses() {
+ return true;
+ }
+
+ @Override
String typeString() {
return "identifiernamestring";
}
-
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
index 85a96c2..fe4d871 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
@@ -156,6 +156,12 @@
}
@Override
+ public boolean isApplicableToClasspathClasses() {
+ assert !super.isApplicableToClasspathClasses();
+ return getIncludeDescriptorClasses();
+ }
+
+ @Override
public boolean isProguardKeepRule() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleBase.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleBase.java
index fb02899..93cbfd5 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleBase.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRuleBase.java
@@ -74,6 +74,10 @@
this.modifiers = modifiers;
}
+ public boolean getIncludeDescriptorClasses() {
+ return modifiers.includeDescriptorClasses;
+ }
+
public ProguardKeepRuleType getType() {
return type;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 39b35aa..09adf3d 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.BottomUpClassHierarchyTraversal;
+import com.android.tools.r8.graph.ClasspathDefinition;
import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotation.AnnotatedKind;
@@ -27,6 +28,7 @@
import com.android.tools.r8.graph.DexClassAndField;
import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
@@ -46,6 +48,7 @@
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMember;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.ProgramOrClasspathDefinition;
import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.ir.analysis.type.DynamicType;
@@ -240,7 +243,7 @@
// Trace references.
R8PartialUseCollector useCollector =
- new R8PartialUseCollector(appView) {
+ new R8PartialUseCollector(appView, identifierNameStrings) {
// Map from Reference to canonical ReferencedFromExcludedClassInR8PartialRule.
private final Map<Object, ReferencedFromExcludedClassInR8PartialRule> canonicalRules =
@@ -366,19 +369,37 @@
}
Collection<ProguardMemberRule> memberKeepRules = rule.getMemberRules();
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier;
+ Map<Predicate<DexDefinition>, DexClass> preconditionSupplier;
if (rule instanceof ProguardKeepRule) {
- if (clazz.isNotProgramClass()) {
+ ProguardKeepRule keepRule = rule.asProguardKeepRule();
+ if (clazz.isLibraryClass()) {
return;
}
- switch (((ProguardKeepRule) rule).getType()) {
+ // Classpath classes may have members that refer to program classes. Therefore, we cannot
+ // skip rule evaluation in presence of `,includedescriptorclasses`.
+ if (clazz.isClasspathClass() && !keepRule.getIncludeDescriptorClasses()) {
+ return;
+ }
+ switch (keepRule.getType()) {
case KEEP_CLASS_MEMBERS:
// Members mentioned at -keepclassmembers always depend on their holder.
- preconditionSupplier = ImmutableMap.of(definition -> true, clazz.asProgramClass());
+ preconditionSupplier = ImmutableMap.of(definition -> true, clazz);
markMatchingVisibleMethods(
- clazz, memberKeepRules, rule, preconditionSupplier, false, ifRulePreconditionMatch);
+ clazz,
+ memberKeepRules,
+ rule,
+ preconditionSupplier,
+ keepRule.getIncludeDescriptorClasses(),
+ false,
+ ifRulePreconditionMatch);
markMatchingVisibleFields(
- clazz, memberKeepRules, rule, preconditionSupplier, false, ifRulePreconditionMatch);
+ clazz,
+ memberKeepRules,
+ rule,
+ preconditionSupplier,
+ keepRule.getIncludeDescriptorClasses(),
+ false,
+ ifRulePreconditionMatch);
break;
case KEEP_CLASSES_WITH_MEMBERS:
if (!allRulesSatisfied(memberKeepRules, clazz)) {
@@ -392,17 +413,28 @@
// Static members in -keep are pinned no matter what.
preconditionSupplier.put(DexDefinition::isStaticMember, null);
// Instance members may need to be kept even though the holder is not instantiated.
- preconditionSupplier.put(
- definition -> !definition.isStaticMember(), clazz.asProgramClass());
+ preconditionSupplier.put(definition -> !definition.isStaticMember(), clazz);
} else {
// Members mentioned at -keep should always be pinned as long as that -keep rule is
// not triggered conditionally.
preconditionSupplier.put(alwaysTrue(), null);
}
markMatchingVisibleMethods(
- clazz, memberKeepRules, rule, preconditionSupplier, false, ifRulePreconditionMatch);
+ clazz,
+ memberKeepRules,
+ rule,
+ preconditionSupplier,
+ keepRule.getIncludeDescriptorClasses(),
+ false,
+ ifRulePreconditionMatch);
markMatchingVisibleFields(
- clazz, memberKeepRules, rule, preconditionSupplier, false, ifRulePreconditionMatch);
+ clazz,
+ memberKeepRules,
+ rule,
+ preconditionSupplier,
+ keepRule.getIncludeDescriptorClasses(),
+ false,
+ ifRulePreconditionMatch);
break;
case CONDITIONAL:
throw new Unreachable("-if rule will be evaluated separately, not here.");
@@ -423,25 +455,25 @@
|| rule instanceof ProguardWhyAreYouKeepingRule) {
markClass(clazz, rule, ifRulePreconditionMatch);
markMatchingVisibleMethods(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
markMatchingVisibleFields(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
} else if (rule instanceof ProguardAssumeMayHaveSideEffectsRule) {
markMatchingVisibleMethods(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
markMatchingOverriddenMethods(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
markMatchingVisibleFields(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
} else if (rule instanceof ProguardAssumeNoSideEffectRule
|| rule instanceof ProguardAssumeValuesRule) {
if (assumeInfoCollectionBuilder != null) {
markMatchingVisibleMethods(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
markMatchingOverriddenMethods(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
markMatchingVisibleFields(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
}
} else if (rule instanceof NoFieldTypeStrengtheningRule
|| rule instanceof NoRedundantFieldLoadEliminationRule) {
@@ -468,9 +500,9 @@
}
} else if (rule instanceof NoValuePropagationRule) {
markMatchingVisibleMethods(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
markMatchingVisibleFields(
- clazz, memberKeepRules, rule, null, true, ifRulePreconditionMatch);
+ clazz, memberKeepRules, rule, null, true, true, ifRulePreconditionMatch);
} else if (rule instanceof ProguardIdentifierNameStringRule) {
markMatchingFields(clazz, memberKeepRules, rule, null, ifRulePreconditionMatch);
markMatchingMethods(clazz, memberKeepRules, rule, null, ifRulePreconditionMatch);
@@ -506,7 +538,12 @@
application.classes(),
alwaysTrue(),
clazz -> process(clazz, rule, ifRulePreconditionMatch));
- if (rule.applyToNonProgramClasses()) {
+ if (rule.isApplicableToClasspathClasses()) {
+ for (DexClasspathClass clazz : application.classpathClasses()) {
+ process(clazz, rule, ifRulePreconditionMatch);
+ }
+ }
+ if (rule.isApplicableToLibraryClasses()) {
for (DexLibraryClass clazz : application.libraryClasses()) {
process(clazz, rule, ifRulePreconditionMatch);
}
@@ -514,7 +551,7 @@
});
}
- public RootSet build(ExecutorService executorService) throws ExecutionException {
+ public RootSetBuilder evaluateRules(ExecutorService executorService) throws ExecutionException {
application.timing.begin("Build root set...");
try {
TaskCollection<?> tasks = new TaskCollection<>(options, executorService);
@@ -551,6 +588,10 @@
alwaysInline,
dependentMinimumKeepInfo)
.extendRootSet(dependentMinimumKeepInfo));
+ return this;
+ }
+
+ public RootSet build() {
return new RootSet(
dependentMinimumKeepInfo,
ImmutableList.copyOf(reasonAsked.values()),
@@ -568,6 +609,12 @@
rootNonProgramTypes);
}
+ public RootSet evaluateRulesAndBuild(ExecutorService executorService)
+ throws ExecutionException {
+ evaluateRules(executorService);
+ return build();
+ }
+
private void propagateAssumeRules(DexClass clazz) {
List<DexClass> subclasses = subtypingInfo.getSubclasses(clazz);
if (subclasses.isEmpty()) {
@@ -634,16 +681,14 @@
pendingMethodMoveInverse);
}
- private static DexProgramClass testAndGetPrecondition(
- DexDefinition definition,
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier) {
+ private static DexClass testAndGetPrecondition(
+ DexDefinition definition, Map<Predicate<DexDefinition>, DexClass> preconditionSupplier) {
if (preconditionSupplier == null) {
return null;
}
- DexProgramClass precondition = null;
+ DexClass precondition = null;
boolean conditionEverMatched = false;
- for (Entry<Predicate<DexDefinition>, DexProgramClass> entry :
- preconditionSupplier.entrySet()) {
+ for (Entry<Predicate<DexDefinition>, DexClass> entry : preconditionSupplier.entrySet()) {
if (entry.getKey().test(definition)) {
precondition = entry.getValue();
conditionEverMatched = true;
@@ -660,7 +705,8 @@
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier,
+ Map<Predicate<DexDefinition>, DexClass> preconditionSupplier,
+ boolean includeClasspathClasses,
boolean includeLibraryClasses,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
Set<Wrapper<DexMethod>> methodsMarked =
@@ -669,7 +715,10 @@
worklist.add(clazz);
while (!worklist.isEmpty()) {
DexClass currentClass = worklist.pop();
- if (!includeLibraryClasses && currentClass.isNotProgramClass()) {
+ if (!includeClasspathClasses && currentClass.isClasspathClass()) {
+ break;
+ }
+ if (!includeLibraryClasses && currentClass.isLibraryClass()) {
break;
}
// In compat mode traverse all direct methods in the hierarchy.
@@ -680,7 +729,7 @@
|| (method.isStatic() && !method.isPrivate() && !method.isInitializer())
|| options.forceProguardCompatibility,
method -> {
- DexProgramClass precondition =
+ DexClass precondition =
testAndGetPrecondition(method.getDefinition(), preconditionSupplier);
markMethod(
method,
@@ -723,7 +772,7 @@
private final DexProgramClass originalClazz;
private final Collection<ProguardMemberRule> memberKeepRules;
private final ProguardConfigurationRule context;
- private final Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier;
+ private final Map<Predicate<DexDefinition>, DexClass> preconditionSupplier;
private final ProguardIfRulePreconditionMatch ifRulePreconditionMatch;
private final Set<Wrapper<DexMethod>> seenMethods = Sets.newHashSet();
private final Set<DexType> seenTypes = Sets.newIdentityHashSet();
@@ -732,7 +781,7 @@
DexProgramClass originalClazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule context,
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier,
+ Map<Predicate<DexDefinition>, DexClass> preconditionSupplier,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
assert context.isProguardKeepRule();
assert !context.asProguardKeepRule().getModifiers().allowsShrinking;
@@ -826,7 +875,7 @@
methodToKeep,
resolutionMethod,
(rootSetBuilder) -> {
- DexProgramClass precondition =
+ DexClass precondition =
testAndGetPrecondition(methodToKeep.getDefinition(), preconditionSupplier);
rootSetBuilder.addItemToSets(
methodToKeep, context, rule, precondition, ifRulePreconditionMatch);
@@ -843,8 +892,9 @@
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier,
- boolean onlyIncludeProgramClasses,
+ Map<Predicate<DexDefinition>, DexClass> preconditionSupplier,
+ boolean includeClasspathClasses,
+ boolean includeLibraryClasses,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
Set<DexClass> visited = Sets.newIdentityHashSet();
Deque<DexClass> worklist = new ArrayDeque<>();
@@ -857,13 +907,16 @@
if (!visited.add(currentClass)) {
continue;
}
- if (!onlyIncludeProgramClasses && currentClass.isNotProgramClass()) {
+ if (!includeClasspathClasses && currentClass.isClasspathClass()) {
+ continue;
+ }
+ if (!includeLibraryClasses && currentClass.isLibraryClass()) {
continue;
}
currentClass.forEachClassMethodMatching(
DexEncodedMethod::belongsToVirtualPool,
method -> {
- DexProgramClass precondition =
+ DexClass precondition =
testAndGetPrecondition(method.getDefinition(), preconditionSupplier);
markMethod(
method, memberKeepRules, null, rule, precondition, ifRulePreconditionMatch);
@@ -876,11 +929,11 @@
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier,
+ Map<Predicate<DexDefinition>, DexClass> preconditionSupplier,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
clazz.forEachClassMethod(
method -> {
- DexProgramClass precondition =
+ DexClass precondition =
testAndGetPrecondition(method.getDefinition(), preconditionSupplier);
markMethod(method, memberKeepRules, null, rule, precondition, ifRulePreconditionMatch);
});
@@ -890,16 +943,20 @@
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier,
+ Map<Predicate<DexDefinition>, DexClass> preconditionSupplier,
+ boolean includeClasspathClasses,
boolean includeLibraryClasses,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
while (clazz != null) {
- if (!includeLibraryClasses && clazz.isNotProgramClass()) {
+ if (!includeClasspathClasses && clazz.isClasspathClass()) {
+ return;
+ }
+ if (!includeLibraryClasses && clazz.isLibraryClass()) {
return;
}
clazz.forEachClassField(
field -> {
- DexProgramClass precondition =
+ DexClass precondition =
testAndGetPrecondition(field.getDefinition(), preconditionSupplier);
markField(field, memberKeepRules, rule, precondition, ifRulePreconditionMatch);
});
@@ -911,11 +968,11 @@
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- Map<Predicate<DexDefinition>, DexProgramClass> preconditionSupplier,
+ Map<Predicate<DexDefinition>, DexClass> preconditionSupplier,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
clazz.forEachClassField(
field -> {
- DexProgramClass precondition =
+ DexClass precondition =
testAndGetPrecondition(field.getDefinition(), preconditionSupplier);
markField(field, memberKeepRules, rule, precondition, ifRulePreconditionMatch);
});
@@ -1231,7 +1288,7 @@
Collection<ProguardMemberRule> rules,
Set<Wrapper<DexMethod>> methodsMarked,
ProguardConfigurationRule context,
- DexProgramClass precondition,
+ DexClass precondition,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
if (methodsMarked != null
&& methodsMarked.contains(MethodSignatureEquivalence.get().wrap(method.getReference()))) {
@@ -1252,7 +1309,7 @@
DexClassAndField field,
Collection<ProguardMemberRule> rules,
ProguardConfigurationRule context,
- DexProgramClass precondition,
+ DexClass precondition,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
for (ProguardMemberRule rule : rules) {
if (rule.matches(field, appView, this::handleMatchedAnnotation, dexStringCache)) {
@@ -1304,15 +1361,17 @@
}
private void includeDescriptorClasses(
- ProgramDefinition item, ProguardKeepRuleBase rule, EnqueuerEvent preconditionEvent) {
+ ProgramOrClasspathDefinition item,
+ ProguardKeepRuleBase rule,
+ EnqueuerEvent preconditionEvent) {
if (item.isMethod()) {
- ProgramMethod method = item.asProgramMethod();
+ DexClassAndMethod method = item.asMethod();
includeDescriptor(method.getReturnType(), rule, preconditionEvent);
for (DexType value : method.getParameters()) {
includeDescriptor(value, rule, preconditionEvent);
}
} else if (item.isField()) {
- ProgramField field = item.asProgramField();
+ DexClassAndField field = item.asField();
includeDescriptor(field.getType(), rule, preconditionEvent);
} else {
assert item.isClass();
@@ -1323,18 +1382,27 @@
Definition item,
ProguardConfigurationRule context,
ProguardMemberRule rule,
- DexProgramClass precondition,
+ DexClass precondition,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
if (context.isProguardKeepRule()) {
- if (!item.isProgramDefinition()) {
- // Keep rules do not apply to non-program items.
+ if (item.isLibraryDefinition()) {
+ // Keep rules do not apply to library definitions.
return;
}
- evaluateKeepRule(
- item.asProgramDefinition(),
- context.asProguardKeepRule(),
- precondition,
- ifRulePreconditionMatch);
+ ProguardKeepRule keepRule = context.asProguardKeepRule();
+ // Keep rules do not apply the classpath definitions except in the presence of
+ // `,includedescriptorclasses`.
+ if (item.isClasspathDefinition() && !keepRule.getIncludeDescriptorClasses()) {
+ return;
+ }
+ assert item.isProgramDefinition() || item.isClasspathDefinition();
+ if (item.isProgramDefinition()) {
+ evaluateKeepRule(
+ item.asProgramDefinition(), keepRule, precondition, ifRulePreconditionMatch);
+ } else {
+ evaluateKeepRuleOnClasspath(
+ item.asClasspathDefinition(), keepRule, ifRulePreconditionMatch);
+ }
} else if (context instanceof ProguardAssumeMayHaveSideEffectsRule) {
mayHaveSideEffects.put(item.getReference(), rule);
context.markAsUsed();
@@ -1570,9 +1638,22 @@
if (clazz.isProgramClass()) {
evaluateCheckDiscardRule(clazz.asProgramClass(), rule.asProguardCheckDiscardRule());
} else {
+ boolean isR8PartialExcludedClass =
+ clazz.isClasspathClass()
+ && options.partialSubCompilationConfiguration != null
+ && options.partialSubCompilationConfiguration.asR8().isD8Definition(clazz);
StringDiagnostic warning =
- new StringDiagnostic("The rule `" + rule + "` matches a class not in the program.");
+ isR8PartialExcludedClass
+ ? new StringDiagnostic(
+ "The rule `"
+ + rule
+ + "` matches a class that is excluded from optimization in R8.")
+ : new StringDiagnostic(
+ "The rule `" + rule + "` matches a class not in the program.");
appView.reporter().warning(warning);
+
+ // Mark the rule as used to avoid reporting two diagnostics for the same rule.
+ rule.markAsUsed();
}
}
@@ -1709,7 +1790,7 @@
private void evaluateKeepRule(
ProgramDefinition item,
ProguardKeepRule context,
- DexProgramClass precondition,
+ DexClass precondition,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
// The reason for keeping should link to the conditional rule as a whole, if present.
ProguardKeepRuleBase whyAreYouKeepingKeepRule =
@@ -1727,7 +1808,7 @@
private void evaluateKeepRule(
ProgramDefinition item,
- DexProgramClass precondition,
+ DexClass precondition,
ProguardIfRulePreconditionMatch ifRulePreconditionMatch,
ProguardKeepRuleModifiers modifiers,
Action markAsUsed,
@@ -1777,12 +1858,13 @@
}
EnqueuerEvent preconditionEvent;
- if (precondition != null) {
+ if (precondition != null && precondition.isProgramClass()) {
+ DexProgramClass programPrecondition = precondition.asProgramClass();
preconditionEvent =
item.getAccessFlags().isStatic()
|| (item.isMethod() && item.asMethod().getDefinition().isInstanceInitializer())
- ? new LiveClassEnqueuerEvent(precondition)
- : new InstantiatedClassEnqueuerEvent(precondition);
+ ? new LiveClassEnqueuerEvent(programPrecondition)
+ : new InstantiatedClassEnqueuerEvent(programPrecondition);
} else {
preconditionEvent = UnconditionalKeepInfoEvent.get();
}
@@ -1908,6 +1990,23 @@
assert !itemJoiner.isSet() || !itemJoiner.computeIfAbsent().isBottom();
}
+ private void evaluateKeepRuleOnClasspath(
+ ClasspathDefinition item,
+ ProguardKeepRule context,
+ ProguardIfRulePreconditionMatch ifRulePreconditionMatch) {
+ if (context.getIncludeDescriptorClasses()) {
+ // Classpath classes are unconditionally live.
+ EnqueuerEvent preconditionEvent = UnconditionalKeepInfoEvent.get();
+ // The reason for keeping should link to the conditional rule as a whole, if present.
+ ProguardKeepRuleBase whyAreYouKeepingKeepRule =
+ ifRulePreconditionMatch != null
+ ? ifRulePreconditionMatch.getIfRuleWithPreconditionSet()
+ : context;
+ includeDescriptorClasses(item, whyAreYouKeepingKeepRule, preconditionEvent);
+ context.markAsUsed();
+ }
+ }
+
private RetentionInfo getRetentionFromAttributeConfig(boolean visible, boolean invisible) {
if (visible && invisible) {
return RetentionInfo.getRetainAll();
@@ -2490,9 +2589,10 @@
}
@Override
- public MainDexRootSet build(ExecutorService executorService) throws ExecutionException {
+ public MainDexRootSet evaluateRulesAndBuild(ExecutorService executorService)
+ throws ExecutionException {
// Call the super builder to have if-tests calculated automatically.
- RootSet rootSet = super.build(executorService);
+ RootSet rootSet = super.evaluateRulesAndBuild(executorService);
return new MainDexRootSet(
rootSet.getDependentMinimumKeepInfo(),
rootSet.reasonAsked,
diff --git a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/EnqueuerReflectiveIdentificationEventConsumer.java b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/EnqueuerReflectiveIdentificationEventConsumer.java
index 4614b7e..20aa5be 100644
--- a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/EnqueuerReflectiveIdentificationEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/EnqueuerReflectiveIdentificationEventConsumer.java
@@ -7,10 +7,12 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramField;
+import com.android.tools.r8.graph.ProgramMember;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerWorklist;
@@ -216,4 +218,9 @@
}
}
}
+
+ @Override
+ public void onIdentifierNameString(Definition definition, ProgramMember<?, ?> context) {
+ // Intentionally empty. Items that are used by reflection should be kept.
+ }
}
diff --git a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/KeepAllReflectiveIdentificationEventConsumer.java b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/KeepAllReflectiveIdentificationEventConsumer.java
index 10ad31f..ea733a4 100644
--- a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/KeepAllReflectiveIdentificationEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/KeepAllReflectiveIdentificationEventConsumer.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramField;
+import com.android.tools.r8.graph.ProgramMember;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.partial.R8PartialUseCollector;
import java.util.Collection;
@@ -23,7 +24,7 @@
this.useCollector = useCollector;
}
- private void keep(Definition definition, ProgramMethod context) {
+ private void keep(Definition definition, ProgramMember<?, ?> context) {
DefinitionContext referencedFrom = DefinitionContextUtils.create(context);
useCollector.keep(definition, referencedFrom, false);
}
@@ -99,4 +100,9 @@
}
}
}
+
+ @Override
+ public void onIdentifierNameString(Definition definition, ProgramMember<?, ?> context) {
+ keep(definition, context);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentification.java b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentification.java
index 446f12a..5d49cb7 100644
--- a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentification.java
+++ b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentification.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
@@ -17,6 +18,7 @@
import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
@@ -30,13 +32,16 @@
import com.android.tools.r8.ir.code.NewArrayFilled;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.conversion.MethodConversionOptions;
+import com.android.tools.r8.naming.IdentifierNameStringUtils;
import com.android.tools.r8.naming.identifiernamestring.IdentifierNameStringLookupResult;
import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.collections.ProgramFieldMap;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.android.tools.r8.utils.timing.Timing;
import com.google.common.collect.Sets;
import java.lang.reflect.InvocationHandler;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
@@ -46,20 +51,30 @@
private final AppView<? extends AppInfoWithClassHierarchy> appView;
private final DexItemFactory factory;
private final ReflectiveIdentificationEventConsumer eventConsumer;
+ private final Set<DexMember<?, ?>> identifierNameStrings;
- private final Set<DexMember<?, ?>> identifierNameStrings = Sets.newIdentityHashSet();
+ private final Set<DexMember<?, ?>> identifierNameStringAdditions = Sets.newIdentityHashSet();
+ private final ProgramFieldMap<Definition> fieldReferencesWorklist = ProgramFieldMap.create();
private final ProgramMethodSet worklist = ProgramMethodSet.create();
public ReflectiveIdentification(
AppView<? extends AppInfoWithClassHierarchy> appView,
ReflectiveIdentificationEventConsumer eventConsumer) {
+ this(appView, eventConsumer, Collections.emptySet());
+ }
+
+ public ReflectiveIdentification(
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ ReflectiveIdentificationEventConsumer eventConsumer,
+ Set<DexMember<?, ?>> identifierNameStrings) {
this.appView = appView;
this.factory = appView.dexItemFactory();
this.eventConsumer = eventConsumer;
+ this.identifierNameStrings = identifierNameStrings;
}
- public Set<DexMember<?, ?>> getIdentifierNameStrings() {
- return identifierNameStrings;
+ public Set<DexMember<?, ?>> getIdentifierNameStringAdditions() {
+ return identifierNameStringAdditions;
}
public void scanInvoke(DexMethod invokedMethod, ProgramMethod method) {
@@ -72,7 +87,7 @@
} else if (classMethods.isReflectiveClassLookup(invokedMethod)
|| classMethods.isReflectiveMemberLookup(invokedMethod)) {
// Implicitly add -identifiernamestring rule for the Java reflection in use.
- identifierNameStrings.add(invokedMethod);
+ identifierNameStringAdditions.add(invokedMethod);
enqueue(method);
}
} else if (holder.isIdenticalTo(factory.constructorType)) {
@@ -97,29 +112,44 @@
// java.util.concurrent.atomic.AtomicLongFieldUpdater
// java.util.concurrent.atomic.AtomicReferenceFieldUpdater
if (factory.atomicFieldUpdaterMethods.isFieldUpdater(invokedMethod)) {
- identifierNameStrings.add(invokedMethod);
+ identifierNameStringAdditions.add(invokedMethod);
enqueue(method);
}
}
+ if (identifierNameStrings.contains(invokedMethod)) {
+ enqueue(method);
+ }
}
- public void enqueue(ProgramMethod method) {
+ // The given field has a static value that references the given definition. Upon processing the
+ // worklist, emit this to the event consumer.
+ public synchronized void enqueue(ProgramField field, Definition definition) {
+ fieldReferencesWorklist.put(field, definition);
+ }
+
+ public synchronized void enqueue(ProgramMethod method) {
worklist.add(method);
}
+ // TODO(b/414944282): Parallelize reflective identification.
public void processWorklist(Timing timing) {
- if (worklist.isEmpty()) {
- return;
- }
timing.begin("Reflective identification");
- // TODO(b/414944282): Parallelize reflective identification.
- for (ProgramMethod method : worklist) {
- processMethod(method);
- }
+
+ // Process fields.
+ fieldReferencesWorklist.forEach(this::processField);
+ fieldReferencesWorklist.clear();
+
+ // Process methods.
+ worklist.forEach(this::processMethod);
worklist.clear();
+
timing.end();
}
+ private void processField(ProgramField field, Definition definition) {
+ eventConsumer.onIdentifierNameString(definition, field);
+ }
+
private void processMethod(ProgramMethod method) {
IRCode code = method.buildIR(appView, MethodConversionOptions.nonConverting());
for (InvokeMethod invoke : code.<InvokeMethod>instructions(Instruction::isInvokeMethod)) {
@@ -201,6 +231,10 @@
return true;
}
}
+ if (identifierNameStrings.contains(invokedMethod)) {
+ handleIdentifierNameStringMethod(method, invoke);
+ return true;
+ }
return false;
}
@@ -484,4 +518,17 @@
eventConsumer.onJavaUtilServiceLoaderLoad(serviceClass, implementationClasses, context);
}
}
+
+ private void handleIdentifierNameStringMethod(ProgramMethod method, InvokeMethod invoke) {
+ for (Value argument : invoke.arguments()) {
+ DexString string = argument.getConstStringOrNull();
+ if (string != null) {
+ Definition definition =
+ IdentifierNameStringUtils.inferMemberOrTypeFromNameString(appView, string);
+ if (definition != null) {
+ eventConsumer.onIdentifierNameString(definition, method);
+ }
+ }
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentificationEventConsumer.java b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentificationEventConsumer.java
index 0488e06..d6255c3 100644
--- a/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentificationEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/shaking/reflectiveidentification/ReflectiveIdentificationEventConsumer.java
@@ -3,9 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking.reflectiveidentification;
+import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramField;
+import com.android.tools.r8.graph.ProgramMember;
import com.android.tools.r8.graph.ProgramMethod;
import java.util.Collection;
import java.util.Set;
@@ -37,4 +39,6 @@
DexProgramClass serviceClass,
Collection<DexProgramClass> implementationClasses,
ProgramMethod context);
+
+ void onIdentifierNameString(Definition definition, ProgramMember<?, ?> context);
}
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index 6da90de..03c0630 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -3,8 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.synthesis;
-import static com.google.common.base.Predicates.alwaysTrue;
-
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -12,7 +10,6 @@
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMember;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -26,9 +23,11 @@
import com.android.tools.r8.graph.lens.NestedGraphLens;
import com.android.tools.r8.graph.lens.NonIdentityGraphLens;
import com.android.tools.r8.ir.code.NumberGenerator;
+import com.android.tools.r8.partial.R8PartialSubCompilationConfiguration.R8PartialR8SubCompilationConfiguration;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.KeepClassInfo;
import com.android.tools.r8.shaking.KeepInfoCollection;
+import com.android.tools.r8.shaking.KeepMethodInfo.Joiner;
import com.android.tools.r8.shaking.MainDexInfo;
import com.android.tools.r8.shaking.SyntheticKeepClassInfo;
import com.android.tools.r8.synthesis.SyntheticItems.State;
@@ -498,14 +497,24 @@
SyntheticMethodDefinition representative = syntheticGroup.getRepresentative();
assert externalSyntheticClass.getMethodCollection().size() == 1;
assert externalSyntheticClass.getMethodCollection().hasDirectMethods();
- DexEncodedMethod syntheticMethodDefinition =
- externalSyntheticClass.getMethodCollection().getDirectMethod(alwaysTrue());
+ ProgramMethod syntheticMethodDefinition =
+ IterableUtils.first(externalSyntheticClass.directProgramMethods());
addFinalSyntheticMethod.accept(
externalSyntheticClass,
new SyntheticMethodReference(
representative.getKind(),
representative.getContext(),
syntheticMethodDefinition.getReference()));
+
+ // If the synthetic group contains a method that has been synthesized from an excluded
+ // class in R8 partial, then disallow inlining of the shared synthetic method. This
+ // ensures that we do not incorrectly single caller inline the shared synthetic method if
+ // it has a single call site in the included part of R8 partial.
+ if (isSyntheticMethodCalledFromExcludedClassInPartial(appView, syntheticGroup)) {
+ appView
+ .getKeepInfo()
+ .mutate(m -> m.joinMethod(syntheticMethodDefinition, Joiner::disallowInlining));
+ }
});
timing.end();
@@ -542,6 +551,24 @@
return application;
}
+ private static boolean isSyntheticMethodCalledFromExcludedClassInPartial(
+ AppView<?> appView, EquivalenceGroup<SyntheticMethodDefinition> group) {
+ R8PartialR8SubCompilationConfiguration subCompilationConfiguration =
+ appView.options().partialSubCompilationConfiguration != null
+ ? appView.options().partialSubCompilationConfiguration.asR8()
+ : null;
+ if (subCompilationConfiguration != null) {
+ for (SyntheticMethodDefinition member :
+ IterableUtils.append(group.members, group.getRepresentative())) {
+ DexType synthesizingContextType = member.getContext().getSynthesizingContextType();
+ if (subCompilationConfiguration.hasD8DefinitionFor(synthesizingContextType)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private static <T extends SyntheticDefinition<?, T, ?>>
boolean verifyNonRepresentativesRemovedFromApplication(
DexApplication application, Map<DexType, EquivalenceGroup<T>> syntheticGroups) {
diff --git a/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java b/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java
index 2152274..c03b71b 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java
@@ -311,7 +311,7 @@
return appView.appInfo();
}
- private boolean isTargetType(DexType type) {
+ protected final boolean isTargetType(DexType type) {
return targetPredicate.test(type);
}
@@ -428,9 +428,14 @@
dexAnnotation ->
registerAnnotation(
dexAnnotation, field.getHolder(), referencedFrom, eventConsumer));
+ traceFieldValue(field);
traceSignature(field, referencedFrom, eventConsumer);
}
+ protected void traceFieldValue(ProgramField field) {
+ // Intentionally empty. Overridden in R8PartialUseCollector.
+ }
+
private void registerMethod(ProgramMethod method, UseCollectorEventConsumer eventConsumer) {
DefinitionContext referencedFrom = DefinitionContextUtils.create(method);
UseCollectorEventConsumer signatureEventConsumer =
diff --git a/src/test/java/com/android/tools/r8/annotations/SourceDebugExtensionTest.java b/src/test/java/com/android/tools/r8/annotations/SourceDebugExtensionTest.java
index 27b7603..5bc862d 100644
--- a/src/test/java/com/android/tools/r8/annotations/SourceDebugExtensionTest.java
+++ b/src/test/java/com/android/tools/r8/annotations/SourceDebugExtensionTest.java
@@ -38,7 +38,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public SourceDebugExtensionTest(
diff --git a/src/test/java/com/android/tools/r8/cf/bootstrap/KotlinCompilerTreeShakingTest.java b/src/test/java/com/android/tools/r8/cf/bootstrap/KotlinCompilerTreeShakingTest.java
index a49e001..c35f84b 100644
--- a/src/test/java/com/android/tools/r8/cf/bootstrap/KotlinCompilerTreeShakingTest.java
+++ b/src/test/java/com/android/tools/r8/cf/bootstrap/KotlinCompilerTreeShakingTest.java
@@ -44,7 +44,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinCompilerTreeShakingTest(
diff --git a/src/test/java/com/android/tools/r8/debug/ContinuousKotlinSteppingTest.java b/src/test/java/com/android/tools/r8/debug/ContinuousKotlinSteppingTest.java
index a159df8..488944b 100644
--- a/src/test/java/com/android/tools/r8/debug/ContinuousKotlinSteppingTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ContinuousKotlinSteppingTest.java
@@ -21,7 +21,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimes().withAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
private final TestParameters parameters;
diff --git a/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
index 6a33a13..813ef2d 100644
--- a/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
@@ -84,9 +84,7 @@
temp)
.configure(KotlinCompilerTool::includeRuntime);
for (KotlinTestParameters kotlinParameter :
- TestBase.getKotlinTestParameters()
- .withAllCompilersLambdaGenerationsAndTargetVersions()
- .build()) {
+ TestBase.getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build()) {
add(compiledJars.getForConfiguration(kotlinParameter), predicate);
}
return this;
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java b/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java
index aae982c..96b801b 100644
--- a/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java
+++ b/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java
@@ -36,7 +36,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimes().withAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinInlineTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinLoopTest.java b/src/test/java/com/android/tools/r8/debug/KotlinLoopTest.java
index 5756f43..43c3a66 100644
--- a/src/test/java/com/android/tools/r8/debug/KotlinLoopTest.java
+++ b/src/test/java/com/android/tools/r8/debug/KotlinLoopTest.java
@@ -21,7 +21,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimes().withAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinLoopTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinTest.java b/src/test/java/com/android/tools/r8/debug/KotlinTest.java
index a0a9a12..0336fa3 100644
--- a/src/test/java/com/android/tools/r8/debug/KotlinTest.java
+++ b/src/test/java/com/android/tools/r8/debug/KotlinTest.java
@@ -24,7 +24,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimes().withAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinBlogTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinBlogTest.java
index 35de5d0..08b33dc 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinBlogTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinBlogTest.java
@@ -56,7 +56,7 @@
.withDexRuntimesStartingFromIncluding(Version.V5_1_1)
.withAllApiLevels()
.build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
ImmutableList.of(LibraryDesugaringSpecification.JDK11_PATH),
DEFAULT_SPECIFICATIONS);
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinMetadataTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinMetadataTest.java
index f993e24..c91b351 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinMetadataTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/kotlin/KotlinMetadataTest.java
@@ -63,7 +63,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
DEFAULT_SPECIFICATIONS,
ImmutableList.of(LibraryDesugaringSpecification.JDK11));
}
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/kotlin/SimpleKotlinEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/enumunboxing/kotlin/SimpleKotlinEnumUnboxingTest.java
index ae75dfd..c912c03 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/kotlin/SimpleKotlinEnumUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/kotlin/SimpleKotlinEnumUnboxingTest.java
@@ -41,7 +41,7 @@
public static List<Object[]> enumUnboxingTestParameters() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values(),
getAllEnumKeepRules());
}
diff --git a/src/test/java/com/android/tools/r8/internal/ClankDepsTest.java b/src/test/java/com/android/tools/r8/internal/ClankDepsTest.java
index 7bff736..68577b2 100644
--- a/src/test/java/com/android/tools/r8/internal/ClankDepsTest.java
+++ b/src/test/java/com/android/tools/r8/internal/ClankDepsTest.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.UnverifiableCfCodeDiagnostic;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -70,7 +71,21 @@
containsString(
"Unverifiable code in `"
+ "void zzz.com.facebook.litho.ComponentHost"
- + ".refreshAccessibilityDelegatesIfNeeded(boolean)`"))))
+ + ".refreshAccessibilityDelegatesIfNeeded(boolean)`"))),
+ // Identifier name string warnings.
+ allOf(
+ diagnosticType(StringDiagnostic.class),
+ diagnosticMessage(
+ containsString(
+ "Cannot determine what 'zzz.com.google.common.flogger.backend"
+ + ".google.GooglePlatform' refers to"))),
+ // Same, for 'zzz.com.google.common.flogger.backend.system.DefaultPlatform'.
+ allOf(
+ diagnosticType(StringDiagnostic.class),
+ diagnosticMessage(
+ containsString(
+ "Cannot determine what 'zzz.com.google.common.flogger.backend"
+ + ".system.DefaultPlatform' refers to"))))
.assertNoErrors());
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/InlineTest.java b/src/test/java/com/android/tools/r8/ir/InlineTest.java
index 7c1a238..efbccf0 100644
--- a/src/test/java/com/android/tools/r8/ir/InlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InlineTest.java
@@ -88,7 +88,7 @@
profileCollectionAdditions,
subtypingInfo,
ImmutableList.of(ProguardKeepRule.defaultKeepAllRule(unused -> {})))
- .build(executorService));
+ .evaluateRulesAndBuild(executorService));
Timing timing = Timing.empty();
Enqueuer enqueuer =
EnqueuerFactory.createForInitialTreeShaking(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningKotlinTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningKotlinTest.java
index e668727..4d566b9 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningKotlinTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningKotlinTest.java
@@ -46,7 +46,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public SwitchWithSimpleCasesInliningKotlinTest(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedinterfaces/UnusedInterfaceRemovalPackageBoundaryTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedinterfaces/UnusedInterfaceRemovalPackageBoundaryTest.java
index adfe769..f6773e6 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedinterfaces/UnusedInterfaceRemovalPackageBoundaryTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedinterfaces/UnusedInterfaceRemovalPackageBoundaryTest.java
@@ -32,7 +32,7 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ return getTestParameters().withAllRuntimesAndApiLevels().withPartialCompilation().build();
}
public UnusedInterfaceRemovalPackageBoundaryTest(TestParameters parameters) {
@@ -41,16 +41,16 @@
@Test
public void test() throws Exception {
- testForR8(parameters.getBackend())
+ testForR8(parameters)
.addInnerClasses(getClass(), UnusedInterfaceRemovalPackageBoundaryTestClasses.class)
.addKeepMainRule(TestClass.class)
.addKeepClassRules(I_CLASS)
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
- .setMinApi(parameters)
.compile()
- .inspect(
+ .inspectIf(
+ !parameters.isRandomPartialCompilation(),
inspector -> {
ClassSubject iClassSubject = inspector.clazz(I_CLASS);
assertThat(iClassSubject, isPresent());
@@ -72,6 +72,41 @@
.assertSuccessWithOutputLines("A");
}
+ @Test
+ public void testIOnClasspath() throws Exception {
+ testForR8(parameters)
+ .addInnerClasses(getClass())
+ .addProgramClasses(UnusedInterfaceRemovalPackageBoundaryTestClasses.J.class)
+ .addClasspathClasses(UnusedInterfaceRemovalPackageBoundaryTestClasses.getI())
+ .addKeepMainRule(TestClass.class)
+ // TODO(b/410597153): Repackaging does not account for part of a program package being on
+ // classpath. After fixing this, -dontobfuscate should not be needed.
+ .addDontObfuscate()
+ .enableInliningAnnotations()
+ .enableNeverClassInliningAnnotations()
+ .enableNoVerticalClassMergingAnnotations()
+ .compile()
+ .inspectIf(
+ !parameters.isRandomPartialCompilation(),
+ inspector -> {
+ ClassSubject jClassSubject = inspector.clazz(J_CLASS);
+ assertThat(jClassSubject, isPresent());
+
+ ClassSubject kClassSubject = inspector.clazz(K.class);
+ assertThat(kClassSubject, isAbsent());
+
+ ClassSubject aClassSubject = inspector.clazz(A.class);
+ assertThat(aClassSubject, isPresent());
+ assertEquals(1, aClassSubject.getDexProgramClass().getInterfaces().size());
+ assertEquals(
+ jClassSubject.getDexProgramClass().getType(),
+ aClassSubject.getDexProgramClass().getInterfaces().get(0));
+ })
+ .addRunClasspathClasses(UnusedInterfaceRemovalPackageBoundaryTestClasses.getI())
+ .run(parameters.getRuntime(), TestClass.class)
+ .assertSuccessWithOutputLines("A");
+ }
+
static class TestClass {
public static void main(String[] args) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
index 471e37f..9646cc8 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
@@ -52,7 +52,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinClassInlinerTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java
index e71f9a8..99a3f08 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java
@@ -29,7 +29,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineChainTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineChainTest.java
index d1a13ad..27394d6 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineChainTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineChainTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.kotlin;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -32,7 +31,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineTest.java
index d097d6f..19ffda1 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinIntrinsicsInlineTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.kotlin;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
@@ -32,7 +31,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedArgumentsInLambdasTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedArgumentsInLambdasTest.java
index 20ed92d..51b9935 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedArgumentsInLambdasTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedArgumentsInLambdasTest.java
@@ -25,7 +25,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedSingletonTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedSingletonTest.java
index 255063a..cac0c06 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedSingletonTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedSingletonTest.java
@@ -31,7 +31,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinReflectionLibTest.java b/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinReflectionLibTest.java
index 52ee123..010acba 100644
--- a/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinReflectionLibTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinReflectionLibTest.java
@@ -29,7 +29,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public ProcessKotlinReflectionLibTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinStdlibTest.java b/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinStdlibTest.java
index c9ba267..d2e838c 100644
--- a/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinStdlibTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinStdlibTest.java
@@ -26,7 +26,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public ProcessKotlinStdlibTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
index 4493368..42b2876 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
@@ -62,7 +62,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
index 706536e..c373e41 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
@@ -39,7 +39,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
index 1d6ce95..eb55f31 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
@@ -29,7 +29,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
index b1145e2..ce5c5a3 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
@@ -98,7 +98,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java b/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
index b86c119..9f6cede 100644
--- a/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
@@ -27,7 +27,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java b/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
index e2ea45d..cb89c37 100644
--- a/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
+++ b/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
@@ -54,7 +54,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
private final TestParameters parameters;
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java
index 12c547e..e29b3c5 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.kotlin.lambda;
import static com.android.tools.r8.ToolHelper.getJava8RuntimeJar;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.KotlinTestBase;
@@ -26,7 +25,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinLambdaMergerValidationTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingDebugTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingDebugTest.java
index 0aa1a8b..dcb53ea 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingDebugTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingDebugTest.java
@@ -25,7 +25,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimes().withAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinLambdaMergingDebugTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingKeepAttributesKotlinStyleTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingKeepAttributesKotlinStyleTest.java
index d0faa2b..da524c4 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingKeepAttributesKotlinStyleTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingKeepAttributesKotlinStyleTest.java
@@ -44,7 +44,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values(),
ImmutableList.of(
Collections.emptyList(),
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingSingletonTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingSingletonTest.java
index 9292803..c4a70db 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingSingletonTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingSingletonTest.java
@@ -38,7 +38,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithReprocessingTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithReprocessingTest.java
index a17d0d0..9648132 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithReprocessingTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithReprocessingTest.java
@@ -19,7 +19,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithSmallInliningBudgetTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithSmallInliningBudgetTest.java
index 77715854..fb46c82 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithSmallInliningBudgetTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingWithSmallInliningBudgetTest.java
@@ -19,7 +19,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java b/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java
index 9c4f28b..c6c5b43 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java
@@ -54,7 +54,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimes().withAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public B148525512(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
index 1f3d1d6..bc008b4 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
@@ -7,7 +7,6 @@
import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentIf;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -39,7 +38,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimesAndAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
index 414661d..ee1d199 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.kotlin.metadata;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -29,7 +28,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataPrunedFieldsTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteBoxedTypesTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteBoxedTypesTest.java
index ee09d10..656a366 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteBoxedTypesTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteBoxedTypesTest.java
@@ -25,7 +25,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteBoxedTypesTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeepTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeepTest.java
index aceb999..65513b4 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeepTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeepTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.kotlin.metadata;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -27,7 +26,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
private final TestParameters parameters;
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmptyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmptyTest.java
index 01d5403..f6df376 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmptyTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmptyTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.kotlin.metadata;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
@@ -30,7 +29,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
private final TestParameters parameters;
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteEnumTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteEnumTest.java
index 42a281b..637f3f4 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteEnumTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteEnumTest.java
@@ -38,7 +38,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteEnumTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java
index 1282e40..e613cb5 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java
@@ -41,7 +41,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteInFunctionWithDefaultValueTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
index ce01873..54613ac 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
@@ -31,7 +31,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteInLibraryTypeTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
index cd03687..e2a238d 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
@@ -7,7 +7,6 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -35,7 +34,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteInRenamedTypeTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
index ae1db89..1d38e64 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
@@ -42,7 +42,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteInSealedClassTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInlinePropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInlinePropertyTest.java
index feb4a52..0e776bf 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInlinePropertyTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInlinePropertyTest.java
@@ -24,7 +24,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteInlinePropertyTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInnerClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInnerClassTest.java
index 9362fb1..0de9416 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInnerClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInnerClassTest.java
@@ -60,7 +60,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteInnerClassTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepPathTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepPathTest.java
index 82df658..87f96d5 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepPathTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepPathTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.kotlin.metadata;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -28,7 +27,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
index 593d80e..403e0db 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.kotlin.metadata;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -27,7 +26,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
private final TestParameters parameters;
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteLocalDelegatedPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteLocalDelegatedPropertyTest.java
index d1f4700..35c60c1 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteLocalDelegatedPropertyTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteLocalDelegatedPropertyTest.java
@@ -33,7 +33,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataRewriteLocalDelegatedPropertyTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
index 8d9cc75..4dd7a26 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
@@ -34,7 +34,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public MetadataStripTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/syntheticmethodforannotations/KotlinMetadataTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/syntheticmethodforannotations/KotlinMetadataTest.java
index c317784..dda4131 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/syntheticmethodforannotations/KotlinMetadataTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/syntheticmethodforannotations/KotlinMetadataTest.java
@@ -49,7 +49,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinMetadataTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/optimize/defaultarguments/KotlinDefaultArgumentsTest.java b/src/test/java/com/android/tools/r8/kotlin/optimize/defaultarguments/KotlinDefaultArgumentsTest.java
index 5c17b42..edadaec 100644
--- a/src/test/java/com/android/tools/r8/kotlin/optimize/defaultarguments/KotlinDefaultArgumentsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/optimize/defaultarguments/KotlinDefaultArgumentsTest.java
@@ -8,7 +8,6 @@
import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsentIf;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -45,7 +44,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinDefaultArgumentsTest(
diff --git a/src/test/java/com/android/tools/r8/kotlin/optimize/switches/KotlinEnumSwitchTest.java b/src/test/java/com/android/tools/r8/kotlin/optimize/switches/KotlinEnumSwitchTest.java
index 18b20bb..81ea515 100644
--- a/src/test/java/com/android/tools/r8/kotlin/optimize/switches/KotlinEnumSwitchTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/optimize/switches/KotlinEnumSwitchTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.kotlin.optimize.switches;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNotEquals;
@@ -34,7 +33,7 @@
return buildParameters(
BooleanUtils.values(),
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
private static final KotlinCompileMemoizer kotlinJars =
diff --git a/src/test/java/com/android/tools/r8/kotlin/reflection/KotlinReflectTest.java b/src/test/java/com/android/tools/r8/kotlin/reflection/KotlinReflectTest.java
index c30873e..3cb85a1 100644
--- a/src/test/java/com/android/tools/r8/kotlin/reflection/KotlinReflectTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/reflection/KotlinReflectTest.java
@@ -47,7 +47,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinReflectTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/sealed/SealedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/sealed/SealedClassTest.java
index 20f08a8..3cb9eb9 100644
--- a/src/test/java/com/android/tools/r8/kotlin/sealed/SealedClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/sealed/SealedClassTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.kotlin.sealed;
import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass;
-import static org.hamcrest.CoreMatchers.equalTo;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.KotlinTestBase;
@@ -33,7 +32,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public SealedClassTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/stringplus/StringPlusTest.java b/src/test/java/com/android/tools/r8/kotlin/stringplus/StringPlusTest.java
index 08530a7..5ae9399 100644
--- a/src/test/java/com/android/tools/r8/kotlin/stringplus/StringPlusTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/stringplus/StringPlusTest.java
@@ -6,7 +6,6 @@
import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -48,7 +47,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public StringPlusTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
diff --git a/src/test/java/com/android/tools/r8/metadata/R8BuildMetadataTest.java b/src/test/java/com/android/tools/r8/metadata/R8BuildMetadataTest.java
index 208684e..de97ee5 100644
--- a/src/test/java/com/android/tools/r8/metadata/R8BuildMetadataTest.java
+++ b/src/test/java/com/android/tools/r8/metadata/R8BuildMetadataTest.java
@@ -12,8 +12,10 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.KotlinCompilerTool;
import com.android.tools.r8.LibraryDesugaringTestConfiguration;
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
@@ -42,6 +44,12 @@
@RunWith(Parameterized.class)
public class R8BuildMetadataTest extends TestBase {
+ private static final ClassReference mainReference = Reference.classFromClass(Main.class);
+ private static final ExternalArtProfile artProfile =
+ ExternalArtProfile.builder().addClassRule(mainReference).build();
+ private static final List<ExternalStartupItem> startupProfile =
+ ImmutableList.of(ExternalStartupClass.builder().setClassReference(mainReference).build());
+
@Parameter(0)
public TestParameters parameters;
@@ -51,34 +59,15 @@
}
@Test
- public void test() throws Exception {
- ClassReference mainReference = Reference.classFromClass(Main.class);
- List<ExternalStartupItem> startupProfile =
- ImmutableList.of(ExternalStartupClass.builder().setClassReference(mainReference).build());
+ public void testR8() throws Exception {
R8BuildMetadata buildMetadata =
- testForR8(parameters.getBackend())
- .addProgramClasses(Main.class, PostStartup.class)
+ testForR8(parameters)
.addKeepMainRule(Main.class)
- .addArtProfileForRewriting(
- ExternalArtProfile.builder().addClassRule(mainReference).build())
+ .apply(this::configure)
.applyIf(
parameters.isDexRuntime(),
- testBuilder ->
- testBuilder
- .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
- .addAndroidResources(getTestResources())
- .addFeatureSplit(FeatureSplitMain.class)
- .addKeepMainRule(FeatureSplitMain.class)
- .apply(StartupTestingUtils.addStartupProfile(startupProfile))
- .enableCoreLibraryDesugaring(
- LibraryDesugaringTestConfiguration.forSpecification(
- LibraryDesugaringSpecification.JDK11.getSpecification()))
- .enableIsolatedSplits(true)
- .enableOptimizedShrinking())
- .allowDiagnosticInfoMessages(parameters.canUseNativeMultidex())
- .collectBuildMetadata()
+ testBuilder -> testBuilder.addKeepMainRule(FeatureSplitMain.class))
.enableInliningAnnotations()
- .setMinApi(parameters)
.compileWithExpectedDiagnostics(
diagnostics -> {
if (parameters.canUseNativeMultidex()) {
@@ -95,14 +84,62 @@
// property names are unobfuscated when testing with R8lib (!).
assertThat(json, containsString("\"version\":\"" + Version.LABEL + "\""));
buildMetadata = R8BuildMetadata.fromJson(json);
- inspectDeserializedBuildMetadata(buildMetadata);
+ inspectDeserializedBuildMetadata(buildMetadata, false);
+ }
+
+ @Test
+ public void testR8Partial() throws Exception {
+ R8BuildMetadata buildMetadata =
+ testForR8Partial(parameters)
+ .addProgramFiles(KotlinCompilerTool.KotlinCompiler.latest().getKotlinStdlibJar())
+ .setR8PartialConfiguration(
+ builder ->
+ builder
+ .addJavaTypeIncludePattern("androidx.**")
+ .addJavaTypeIncludePattern("kotlin.**")
+ .addJavaTypeIncludePattern("kotlinx.**"))
+ .apply(this::configure)
+ .compileWithExpectedDiagnostics(
+ diagnostics ->
+ diagnostics.assertInfosMatch(
+ diagnosticMessage(containsString("Startup DEX files contains"))))
+ .getBuildMetadata();
+ String json = buildMetadata.toJson();
+ System.out.println(json);
+ // Inspecting the exact contents is not important here, but it *is* important to test that the
+ // property names are unobfuscated when testing with R8lib (!).
+ assertThat(json, containsString("\"version\":\"" + Version.LABEL + "\""));
+ buildMetadata = R8BuildMetadata.fromJson(json);
+ inspectDeserializedBuildMetadata(buildMetadata, true);
+ }
+
+ private void configure(R8TestBuilder<?, ?, ?> builder) {
+ builder
+ .addProgramClasses(Main.class, PostStartup.class)
+ .addArtProfileForRewriting(artProfile)
+ .allowDiagnosticInfoMessages(parameters.canUseNativeMultidex())
+ .applyIf(
+ parameters.isDexRuntime(),
+ testBuilder ->
+ testBuilder
+ .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
+ .addAndroidResources(getTestResources())
+ .addFeatureSplit(FeatureSplitMain.class)
+ .apply(StartupTestingUtils.addStartupProfile(startupProfile))
+ .enableCoreLibraryDesugaring(
+ LibraryDesugaringTestConfiguration.forSpecification(
+ LibraryDesugaringSpecification.JDK11.getSpecification()))
+ .enableIsolatedSplits(true)
+ .enableOptimizedShrinking())
+ .collectBuildMetadata();
}
private AndroidTestResource getTestResources() throws IOException {
return new AndroidTestResourceBuilder().withSimpleManifestAndAppNameString().build(temp);
}
- private void inspectDeserializedBuildMetadata(R8BuildMetadata buildMetadata) {
+ private void inspectDeserializedBuildMetadata(
+ R8BuildMetadata buildMetadata, boolean isR8Partial) {
// Baseline profile rewriting metadata.
assertNotNull(buildMetadata.getBaselineProfileRewritingMetadata());
// Compilation metadata.
@@ -157,6 +194,12 @@
} else {
assertNull(libraryDesugaringMetadata);
}
+ // Partial compilation metadata.
+ if (isR8Partial) {
+ assertNotNull(buildMetadata.getPartialCompilationMetadata());
+ } else {
+ assertNull(buildMetadata.getPartialCompilationMetadata());
+ }
// Resource optimization metadata.
if (parameters.isDexRuntime()) {
R8ResourceOptimizationMetadata resourceOptimizationMetadata =
diff --git a/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java b/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java
index 7ceb706..76f1053 100644
--- a/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java
+++ b/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java
@@ -5,7 +5,6 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -33,7 +32,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
index cc150aa..06d850c 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
@@ -3,7 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
@@ -67,12 +69,14 @@
"const-string v0, \"" + BOO + "\"",
"iput-object v0, p0, LExample;->aClassName:Ljava/lang/String;",
"return-void");
+ builder.addClass(BOO);
List<String> pgConfigs =
ImmutableList.of(
"-identifiernamestring class " + CLASS_NAME + " { java.lang.String aClassName; }",
"-keep class " + CLASS_NAME + " { void <init>(); }",
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { !static <fields>; }",
+ "-keep,allowobfuscation class " + BOO,
"-dontoptimize");
CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
@@ -81,13 +85,16 @@
DexEncodedMethod method = getMethod(inspector, init);
assertNotNull(method);
+ ClassSubject booClass = inspector.clazz(BOO);
+ assertThat(booClass, isPresentAndRenamed());
+
DexCode code = method.getCode().asDexCode();
checkInstructions(
code,
ImmutableList.of(
DexInvokeDirect.class, DexConstString.class, DexIputObject.class, DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[1];
- assertEquals(BOO, constString.getString().toString());
+ assertEquals(booClass.getFinalName(), constString.getString().toString());
}
@Test
@@ -101,12 +108,14 @@
"invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
"iput-object v1, p0, LExample;->aClassName:Ljava/lang/String;",
"return-void");
+ builder.addClass(BOO);
List<String> pgConfigs =
ImmutableList.of(
"-identifiernamestring class " + CLASS_NAME + " { java.lang.String aClassName; }",
"-keep class " + CLASS_NAME + " { void <init>(); }",
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { !static <fields>; }",
+ "-keep,allowobfuscation class " + BOO,
"-dontoptimize");
CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
@@ -115,6 +124,9 @@
DexEncodedMethod method = getMethod(inspector, init);
assertNotNull(method);
+ ClassSubject booClass = inspector.clazz(BOO);
+ assertThat(booClass, isPresentAndRenamed());
+
DexCode code = method.getCode().asDexCode();
checkInstructions(
code,
@@ -123,10 +135,13 @@
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
+ DexConstString.class,
DexIputObject.class,
DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[2];
assertEquals(BOO, constString.getString().toString());
+ DexConstString renamedConstString = (DexConstString) code.instructions[4];
+ assertEquals(booClass.getFinalName(), renamedConstString.getString().toString());
}
@Test
@@ -213,12 +228,17 @@
"invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
"sput-object v1, LExample;->sClassName:Ljava/lang/String;",
"return-void");
+ builder.addClass(BOO);
- List<String> pgConfigs = ImmutableList.of(
- "-identifiernamestring class " + CLASS_NAME + " { static java.lang.String sClassName; }",
- "-keep class " + CLASS_NAME,
- "-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { static <fields>; }",
- "-dontoptimize");
+ List<String> pgConfigs =
+ ImmutableList.of(
+ "-identifiernamestring class "
+ + CLASS_NAME
+ + " { static java.lang.String sClassName; }",
+ "-keep class " + CLASS_NAME,
+ "-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { static <fields>; }",
+ "-keep,allowobfuscation class " + BOO,
+ "-dontoptimize");
CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
@@ -226,6 +246,9 @@
DexEncodedMethod method = getMethod(inspector, clinit);
assertNotNull(method);
+ ClassSubject booClass = inspector.clazz(BOO);
+ assertThat(booClass, isPresentAndRenamed());
+
DexCode code = method.getCode().asDexCode();
checkInstructions(
code,
@@ -233,10 +256,13 @@
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
+ DexConstString.class,
DexSputObject.class,
DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[1];
assertEquals(BOO, constString.getString().toString());
+ DexConstString renamedConstString = (DexConstString) code.instructions[3];
+ assertEquals(booClass.getFinalName(), renamedConstString.getString().toString());
}
@Test
@@ -385,6 +411,7 @@
"const-string v1, \"Mixed/form.Boo\"",
"invoke-static {v0, v1}, LExample;->foo(Ljava/lang/String;Ljava/lang/String;)V",
"return-void");
+ builder.addClass(BOO);
CodeInspector inspector =
compileWithR8(
@@ -397,6 +424,7 @@
+ CLASS_NAME
+ " { static void foo(...); }")
.addKeepClassAndDefaultConstructor(CLASS_NAME)
+ .addKeepClassRulesWithAllowObfuscation(BOO)
.allowDiagnosticWarningMessages())
.assertAllWarningMessagesMatch(
containsString("Cannot determine what 'Mixed/form.Boo' refers to"))
@@ -407,6 +435,9 @@
DexEncodedMethod method = getMethod(inspector, foo);
assertNotNull(method);
+ ClassSubject booClass = inspector.clazz(BOO);
+ assertThat(booClass, isPresentAndRenamed());
+
DexCode code = method.getCode().asDexCode();
checkInstructions(
code,
@@ -416,9 +447,9 @@
DexConstString.class,
DexInvokeStatic.class,
DexReturnVoid.class));
- String s1 = ((DexConstString) code.instructions[1]).getString().toString();
- String s2 = ((DexConstString) code.instructions[2]).getString().toString();
- assertTrue(BOO.equals(s1) || BOO.equals(s2));
+ String s1 = code.instructions[1].asConstString().getString().toString();
+ String s2 = code.instructions[2].asConstString().getString().toString();
+ assertTrue(booClass.getFinalName().equals(s1) || booClass.getFinalName().equals(s2));
assertTrue("Mixed/form.Boo".equals(s1) || "Mixed/form.Boo".equals(s2));
}
@@ -438,11 +469,13 @@
"invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
"invoke-static {v1}, LExample;->foo(Ljava/lang/String;)V",
"return-void");
+ builder.addClass(BOO);
List<String> pgConfigs =
ImmutableList.of(
"-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
"-keep class " + CLASS_NAME + " { void <init>(); }",
+ "-keep,allowobfuscation class " + BOO,
"-dontoptimize");
CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
@@ -451,6 +484,9 @@
DexEncodedMethod method = getMethod(inspector, foo);
assertNotNull(method);
+ ClassSubject booClass = inspector.clazz(BOO);
+ assertThat(booClass, isPresentAndRenamed());
+
DexCode code = method.getCode().asDexCode();
checkInstructions(
code,
@@ -459,10 +495,13 @@
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
+ DexConstString.class,
DexInvokeStatic.class,
DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[2];
assertEquals(BOO, constString.getString().toString());
+ DexConstString renamedConstString = (DexConstString) code.instructions[4];
+ assertEquals(booClass.getFinalName(), renamedConstString.getString().toString());
}
@Test
diff --git a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
index e72a419..2362609 100644
--- a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
+++ b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
@@ -43,7 +43,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/TwoGigabyteMappingFileRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retrace/TwoGigabyteMappingFileRetraceTest.java
new file mode 100644
index 0000000..484b74d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/retrace/TwoGigabyteMappingFileRetraceTest.java
@@ -0,0 +1,123 @@
+// Copyright (c) 2025, 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.retrace;
+
+import static com.android.tools.r8.naming.retrace.StackTrace.isSame;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+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.StackTraceLine;
+import com.android.tools.r8.retrace.InvalidMappingFileException;
+import com.android.tools.r8.retrace.ProguardMapProducer;
+import com.android.tools.r8.retrace.ProguardMappingSupplier;
+import com.google.common.collect.ImmutableList;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class TwoGigabyteMappingFileRetraceTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ // TODO(b/414645291): Should not throw.
+ @Test(expected = InvalidMappingFileException.class)
+ public void test() throws Exception {
+ Path mappingFile = temp.newFile("mapping-file-larger-than-2GB.txt").toPath();
+ Files.write(
+ mappingFile,
+ ImmutableList.of(
+ "# compiler: R8",
+ "# compiler_version: 8.9.21",
+ "# min_api: 21",
+ "# {\"id\":\"com.android.tools.r8.mapping\",\"version\":\"2.2\"}"));
+ // Generate 2GB+ bytes for mapping file.
+ byte[] mapSnippet =
+ new StringBuilder()
+ .append("kotlin.Lazy -> Y0.d:\n")
+ .append("# {\"id\":\"sourceFile\",\"fileName\":\"Lazy.kt\"}\n")
+ .append(" java.lang.Object getValue() -> getValue\n")
+ .append("kotlin.LazyThreadSafetyMode -> Y0.e:\n")
+ .append("# {\"id\":\"sourceFile\")\"fileName\":\"Lazy.kt\"}\n")
+ .append(" kotlin.LazyThreadSafetyMode[] $VALUES -> d\n")
+ .append(
+ " #"
+ + " {\"id\":\"com.android.tools.r8.residualsignature\")\"signature\":\"[LY0/e;\"}\n")
+ .append(" 4:5:void <clinit>():68:68 -> <clinit>\n")
+ .append(" 6:10:void <init>(java.lang.String,int):59:59 -> <clinit>\n")
+ .append(" 6:10:void <clinit>():68 -> <clinit>\n")
+ .append(" 11:12:void <clinit>():76:76 -> <clinit>\n")
+ .append(" 13:17:void <init>(java.lang.String,int):59:59 -> <clinit>\n")
+ .append(" 13:17:void <clinit>():76 -> <clinit>\n")
+ .append(" 18:19:void <clinit>():84:84 -> <clinit>\n")
+ .append(" 20:25:void <init>(java.lang.String,int):59:59 -> <clinit>\n")
+ .append(" 20:25:void <clinit>():84 -> <clinit>\n")
+ .append(" 26:33:kotlin.LazyThreadSafetyMode[] $values():0:0 -> <clinit>\n")
+ .append(" 26:33:void <clinit>():84 -> <clinit>\n")
+ .append(" 34:36:void <clinit>():84:84 -> <clinit>\n")
+ .append(
+ " 7:9:kotlin.LazyThreadSafetyMode valueOf(java.lang.String):85:85 -> valueOf\n")
+ .append(
+ " #"
+ + " {\"id\":\"com.android.tools.r8.residualsignature\")\"signature\":\"(Ljava/lang/String;)LY0/e;\"}\n")
+ .append(" 7:9:kotlin.LazyThreadSafetyMode[] values():85:85 -> values\n")
+ .append(
+ " #"
+ + " {\"id\":\"com.android.tools.r8.residualsignature\")\"signature\":\"()[LY0/e;\"}\n")
+ .toString()
+ .getBytes(StandardCharsets.UTF_8);
+ byte[] snippetX2048 = new byte[mapSnippet.length * 2048];
+ for (int i = 0; i < 2048; i++) {
+ System.arraycopy(mapSnippet, 0, snippetX2048, i * mapSnippet.length, mapSnippet.length);
+ }
+ for (int i = 0; i < 1024; i++) {
+ Files.write(mappingFile, snippetX2048, StandardOpenOption.APPEND);
+ }
+ // Write mapping for the stacktrace below at the end of the file.
+ Files.write(
+ mappingFile,
+ ImmutableList.of(
+ "Test -> a:",
+ "# {\"id\":\"sourceFile\",\"fileName\":\"Test.java\"}\n",
+ " 1:1:void main():100:100 -> a"),
+ StandardOpenOption.APPEND);
+ long twoGB = 2L * 1024L * 1024L * 1024L;
+ assertTrue(Files.size(mappingFile) > twoGB);
+
+ StackTrace retraced =
+ StackTrace.extractFromJvm("X:\n\tat a.a(SourceFile:1)\n")
+ .retrace(
+ ProguardMappingSupplier.builder()
+ .setProguardMapProducer(ProguardMapProducer.fromPath(mappingFile))
+ .build());
+ assertThat(
+ StackTrace.builder()
+ .setExceptionLine("X:")
+ .add(
+ StackTraceLine.builder()
+ .setLineNumber(100)
+ .setMethodName("main")
+ .setClassName("Test")
+ .setFileName("Test.java")
+ .build())
+ .build(),
+ isSame(retraced));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationCalledByNativeTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationCalledByNativeTest.java
new file mode 100644
index 0000000..834ccd6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationCalledByNativeTest.java
@@ -0,0 +1,92 @@
+// Copyright (c) 2025, 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.partial;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static junit.framework.TestCase.assertEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class PartialCompilationCalledByNativeTest extends TestBase {
+
+ private static final String rule =
+ StringUtils.lines(
+ "-keepclasseswithmembers,includedescriptorclasses class * {",
+ " @" + CalledByNative.class.getTypeName() + " <methods>;",
+ "}");
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters)
+ .addInnerClasses(getClass())
+ .addKeepRules(rule)
+ .compile()
+ .inspect(this::inspect);
+ }
+
+ @Test
+ public void testR8PartialIncludedAnnotation() throws Exception {
+ testForR8Partial(parameters)
+ .addR8IncludedClasses(IncludedClass.class, CalledByNative.class)
+ .addR8ExcludedClasses(ExcludedClass.class)
+ .addKeepRules(rule)
+ .compile()
+ .inspect(this::inspect);
+ }
+
+ @Test
+ public void testR8PartialExcludedAnnotation() throws Exception {
+ testForR8Partial(parameters)
+ .addR8IncludedClasses(IncludedClass.class)
+ .addR8ExcludedClasses(ExcludedClass.class, CalledByNative.class)
+ .addKeepRules(rule)
+ .compile()
+ .inspect(this::inspect);
+ }
+
+ private void inspect(CodeInspector inspector) {
+ ClassSubject includedClassSubject = inspector.clazz(IncludedClass.class);
+ assertThat(includedClassSubject, isPresentAndNotRenamed());
+
+ MethodSubject methodSubject =
+ inspector.clazz(ExcludedClass.class).uniqueMethodWithOriginalName("m");
+ assertThat(methodSubject, isPresent());
+ assertEquals(includedClassSubject.asTypeSubject(), methodSubject.getParameter(0));
+ }
+
+ static class ExcludedClass {
+
+ @CalledByNative
+ public static void m(IncludedClass includedClass) {}
+ }
+
+ static class IncludedClass {}
+
+ @Retention(RetentionPolicy.CLASS)
+ @interface CalledByNative {}
+}
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationCheckDiscardTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationCheckDiscardTest.java
new file mode 100644
index 0000000..e3b69b0
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationCheckDiscardTest.java
@@ -0,0 +1,83 @@
+// Copyright (c) 2025, 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.partial;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
+import static com.android.tools.r8.utils.codeinspector.AssertUtils.assertFailsCompilation;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessages;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.errors.CheckDiscardDiagnostic;
+import com.android.tools.r8.utils.StringDiagnostic;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class PartialCompilationCheckDiscardTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ @Test
+ public void testExcludedClass() throws Exception {
+ testForR8Partial(Backend.DEX)
+ .addR8ExcludedClasses(CheckDiscardClass.class)
+ .addKeepRules("-checkdiscard class " + CheckDiscardClass.class.getTypeName())
+ .allowDiagnosticWarningMessages()
+ .setMinApi(apiLevelWithNativeMultiDexSupport())
+ .compileWithExpectedDiagnostics(
+ diagnostics ->
+ diagnostics
+ .assertOnlyWarnings()
+ .assertWarningsMatch(
+ allOf(
+ diagnosticType(StringDiagnostic.class),
+ diagnosticMessage(
+ containsString(
+ "matches a class that is excluded from optimization in R8")))));
+ }
+
+ @Test
+ public void testIncludedClassRemoved() throws Exception {
+ testForR8Partial(Backend.DEX)
+ .addR8IncludedClasses(CheckDiscardClass.class)
+ .addKeepRules("-checkdiscard class " + CheckDiscardClass.class.getTypeName())
+ .setMinApi(apiLevelWithNativeMultiDexSupport())
+ .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages);
+ }
+
+ @Test
+ public void testIncludedClassKept() throws Exception {
+ assertFailsCompilation(
+ () ->
+ testForR8Partial(Backend.DEX)
+ .addR8IncludedClasses(CheckDiscardClass.class)
+ .addKeepRules("-checkdiscard class " + CheckDiscardClass.class.getTypeName())
+ .addKeepClassRules(CheckDiscardClass.class)
+ .setMinApi(apiLevelWithNativeMultiDexSupport())
+ .compileWithExpectedDiagnostics(
+ diagnostics ->
+ diagnostics
+ .assertOnlyErrors()
+ .assertErrorsMatch(
+ allOf(
+ diagnosticType(CheckDiscardDiagnostic.class),
+ diagnosticMessage(containsString("Discard checks failed."))))));
+ }
+
+ static class CheckDiscardClass {}
+}
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationIdentifierNameStringFieldTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationIdentifierNameStringFieldTest.java
new file mode 100644
index 0000000..2db5a6b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationIdentifierNameStringFieldTest.java
@@ -0,0 +1,84 @@
+// Copyright (c) 2025, 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.partial;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class PartialCompilationIdentifierNameStringFieldTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameter(1)
+ public boolean specific;
+
+ @Parameters(name = "{0}, specific:{1}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters)
+ .addInnerClasses(getClass())
+ .addKeepMainRule(ExcludedClass.class)
+ .addKeepClassRulesWithAllowObfuscation(IncludedClass.class)
+ .addKeepRules(getIdentifierNameStringRule())
+ .compile()
+ .inspect(
+ inspector -> assertThat(inspector.clazz(IncludedClass.class), isPresentAndRenamed()))
+ .run(parameters.getRuntime(), ExcludedClass.class)
+ .assertSuccessWithEmptyOutput();
+ }
+
+ @Test
+ public void testR8Partial() throws Exception {
+ testForR8Partial(parameters)
+ .addR8IncludedClasses(IncludedClass.class)
+ .addR8ExcludedClasses(ExcludedClass.class)
+ .addKeepClassRulesWithAllowObfuscation(IncludedClass.class)
+ .addKeepRules(getIdentifierNameStringRule())
+ .compile()
+ .inspect(
+ inspector -> assertThat(inspector.clazz(IncludedClass.class), isPresentAndNotRenamed()))
+ .run(parameters.getRuntime(), ExcludedClass.class)
+ .assertSuccessWithEmptyOutput();
+ }
+
+ private String getIdentifierNameStringRule() {
+ String classNamePattern = specific ? ExcludedClass.class.getTypeName() : "*";
+ return StringUtils.lines(
+ "-identifiernamestring class " + classNamePattern + " {",
+ " static java.lang.String target;",
+ "}");
+ }
+
+ static class ExcludedClass {
+
+ static String target =
+ "com.android.tools.r8.partial.PartialCompilationIdentifierNameStringFieldTest$IncludedClass";
+
+ public static void main(String[] args) throws Exception {
+ String className = System.currentTimeMillis() > 0 ? target : args[0];
+ Class.forName(className);
+ }
+ }
+
+ static class IncludedClass {}
+}
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationIdentifierNameStringMethodTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationIdentifierNameStringMethodTest.java
new file mode 100644
index 0000000..1c11fdf
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationIdentifierNameStringMethodTest.java
@@ -0,0 +1,76 @@
+// Copyright (c) 2025, 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.partial;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class PartialCompilationIdentifierNameStringMethodTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameter(1)
+ public boolean specific;
+
+ @Parameters(name = "{0}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters)
+ .addInnerClasses(getClass())
+ .addKeepMainRule(ExcludedClass.class)
+ .addKeepClassRulesWithAllowObfuscation(IncludedClass.class)
+ .addKeepRules(getIdentifierNameStringRule())
+ .run(parameters.getRuntime(), ExcludedClass.class)
+ .assertSuccessWithEmptyOutput();
+ }
+
+ @Test
+ public void testR8Partial() throws Exception {
+ testForR8Partial(parameters)
+ .addR8IncludedClasses(IncludedClass.class)
+ .addR8ExcludedClasses(ExcludedClass.class)
+ .addKeepClassRulesWithAllowObfuscation(IncludedClass.class)
+ .addKeepRules(getIdentifierNameStringRule())
+ .run(parameters.getRuntime(), ExcludedClass.class)
+ .assertSuccessWithEmptyOutput();
+ }
+
+ private String getIdentifierNameStringRule() {
+ String classNamePattern = specific ? ExcludedClass.class.getTypeName() : "*";
+ return StringUtils.lines(
+ "-identifiernamestring class " + classNamePattern + " {",
+ " static void foo(java.lang.String, java.lang.String);",
+ "}");
+ }
+
+ static class ExcludedClass {
+
+ public static void main(String[] args) throws Exception {
+ String target =
+ "com.android.tools.r8.partial.PartialCompilationIdentifierNameStringMethodTest$IncludedClass";
+ foo(target, null);
+ }
+
+ static void foo(String a, String b) throws Exception {
+ Class.forName(a);
+ }
+ }
+
+ static class IncludedClass {}
+}
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationIncludeDescriptorClassesTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationIncludeDescriptorClassesTest.java
new file mode 100644
index 0000000..34a28f5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationIncludeDescriptorClassesTest.java
@@ -0,0 +1,76 @@
+// Copyright (c) 2025, 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.partial;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static junit.framework.TestCase.assertEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class PartialCompilationIncludeDescriptorClassesTest extends TestBase {
+
+ private static final String rule =
+ StringUtils.lines(
+ "-keep,includedescriptorclasses class " + ExcludedClass.class.getTypeName() + " {",
+ " public static void m(...);",
+ "}");
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters)
+ .addInnerClasses(getClass())
+ .addKeepRules(rule)
+ .compile()
+ .inspect(this::inspect);
+ }
+
+ @Test
+ public void testR8Partial() throws Exception {
+ testForR8Partial(parameters)
+ .addR8IncludedClasses(IncludedClass.class)
+ .addR8ExcludedClasses(ExcludedClass.class)
+ .addKeepRules(rule)
+ .compile()
+ .inspect(this::inspect);
+ }
+
+ private void inspect(CodeInspector inspector) {
+ ClassSubject includedClassSubject = inspector.clazz(IncludedClass.class);
+ assertThat(includedClassSubject, isPresentAndNotRenamed());
+
+ MethodSubject methodSubject =
+ inspector.clazz(ExcludedClass.class).uniqueMethodWithOriginalName("m");
+ assertThat(methodSubject, isPresent());
+ assertEquals(includedClassSubject.asTypeSubject(), methodSubject.getParameter(0));
+ }
+
+ static class ExcludedClass {
+
+ public static void m(IncludedClass includedClass) {}
+ }
+
+ static class IncludedClass {}
+}
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationInlineAfterSyntheticSharingTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationInlineAfterSyntheticSharingTest.java
new file mode 100644
index 0000000..21c11cb
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationInlineAfterSyntheticSharingTest.java
@@ -0,0 +1,76 @@
+// Copyright (c) 2025, 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.partial;
+
+import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
+
+import com.android.tools.r8.LibraryDesugaringTestConfiguration;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class PartialCompilationInlineAfterSyntheticSharingTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ // Only run on runtimes where Function and Predicate are present.
+ return getTestParameters().withDexRuntimes().build();
+ }
+
+ @Test
+ public void test() throws Exception {
+ testForR8Partial(parameters.getBackend())
+ .addR8ExcludedClasses(ExcludedClass.class)
+ .addR8IncludedClasses(IncludedClass.class)
+ .addLibraryClasses(Foo.class)
+ .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
+ .apply(setMockApiLevelForClass(Foo.class, AndroidApiLevel.LATEST))
+ // Enable library desugaring so that API outlining is run lir-to-lir in R8 of R8 partial.
+ .enableCoreLibraryDesugaring(
+ LibraryDesugaringTestConfiguration.forSpecification(
+ LibraryDesugaringSpecification.JDK11.getSpecification()))
+ .setMinApi(apiLevelWithNativeMultiDexSupport())
+ .compile()
+ .addRunClasspathClasses(Foo.class)
+ .run(parameters.getRuntime(), ExcludedClass.class)
+ .assertSuccessWithOutputLines(
+ "class " + Foo.class.getTypeName(), "class " + Foo.class.getTypeName());
+ }
+
+ static class ExcludedClass {
+
+ public static void main(String[] args) {
+ IncludedClass.test();
+ test();
+ }
+
+ static void test() {
+ // Leads to an API outline. The API outline will be shared with the API outline from
+ // IncludedClass.test(). It is important that we don't single caller inline the shared API
+ // outline in R8 of R8 partial, since the API outline has a caller in an excluded class.
+ System.out.println(Foo.class);
+ }
+ }
+
+ static class IncludedClass {
+
+ static void test() {
+ System.out.println(Foo.class);
+ }
+ }
+
+ static class Foo {}
+}
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationSignatureContextTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationSignatureContextTest.java
new file mode 100644
index 0000000..ffa0f55
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationSignatureContextTest.java
@@ -0,0 +1,59 @@
+// Copyright (c) 2025, 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.partial;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessages;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.partial.PartialCompilationSignatureContextTest.ExcludedClass.IncludedClass;
+import java.util.function.Consumer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+// Regression test for b/415703756.
+@RunWith(Parameterized.class)
+public class PartialCompilationSignatureContextTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(Backend.DEX)
+ .addProgramClasses(IncludedClass.class)
+ .addClasspathClasses(ExcludedClass.class)
+ .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
+ .addKeepAllClassesRule()
+ .addKeepAttributeSignature()
+ .setMinApi(apiLevelWithNativeMultiDexSupport())
+ .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages);
+ }
+
+ @Test
+ public void testR8Partial() throws Exception {
+ testForR8Partial(Backend.DEX)
+ .addR8ExcludedClasses(ExcludedClass.class)
+ .addR8IncludedClasses(IncludedClass.class)
+ .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
+ .addKeepAllClassesRule()
+ .addKeepAttributeSignature()
+ .setMinApi(apiLevelWithNativeMultiDexSupport())
+ .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages);
+ }
+
+ static class ExcludedClass<T> {
+
+ abstract class IncludedClass implements Consumer<T> {}
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java b/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java
index 272905c..39d3674 100644
--- a/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java
+++ b/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java
@@ -44,7 +44,7 @@
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java
index cb5bd87..1b50584 100644
--- a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java
@@ -49,7 +49,7 @@
// TODO(b/186018416): Update to support tests retracing with PC mappings.
.withApiLevelsEndingAtExcluding(apiLevelWithPcAsLineNumberSupport())
.build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinInlineFunctionInSameFileRetraceTests(
diff --git a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java
index 387fdd0..cb7999c 100644
--- a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java
@@ -49,7 +49,7 @@
// TODO(b/186018416): Update to support tests retracing with PC mappings.
.withApiLevelsEndingAtExcluding(apiLevelWithPcAsLineNumberSupport())
.build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public KotlinInlineFunctionRetraceTest(
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationAssertionHandlerKotlinTestBase.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationAssertionHandlerKotlinTestBase.java
index 7f8b97b..f362a0c 100644
--- a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationAssertionHandlerKotlinTestBase.java
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationAssertionHandlerKotlinTestBase.java
@@ -30,7 +30,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinCfTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinCfTest.java
index fcda31f..ef76480 100644
--- a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinCfTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinCfTest.java
@@ -25,7 +25,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withCfRuntimes().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values(),
BooleanUtils.values(),
BooleanUtils.values());
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinDexTestBase.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinDexTestBase.java
index 83c92a1..42d0a76 100644
--- a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinDexTestBase.java
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinDexTestBase.java
@@ -18,7 +18,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimesAndAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build());
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build());
}
public AssertionConfigurationKotlinDexTestBase(
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest.java
index af54a7d..940c710 100644
--- a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest.java
@@ -25,7 +25,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimesAndAllApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values(),
BooleanUtils.values());
}
diff --git a/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java b/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
index 7bfc8be..96fc655 100644
--- a/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
@@ -6,7 +6,6 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -63,7 +62,7 @@
public static Collection<Object[]> data() {
return buildParameters(
getTestParameters().withAllRuntimesAndApiLevels().build(),
- getKotlinTestParameters().withAllCompilersLambdaGenerationsAndTargetVersions().build(),
+ getKotlinTestParameters().withAllCompilersAndLambdaGenerations().build(),
BooleanUtils.values());
}
diff --git a/src/test/testbase/java/com/android/tools/r8/KotlinCompilerTool.java b/src/test/testbase/java/com/android/tools/r8/KotlinCompilerTool.java
index 160dd55..c3ddc4f 100644
--- a/src/test/testbase/java/com/android/tools/r8/KotlinCompilerTool.java
+++ b/src/test/testbase/java/com/android/tools/r8/KotlinCompilerTool.java
@@ -4,6 +4,10 @@
package com.android.tools.r8;
import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MAX_SUPPORTED_VERSION;
+import static com.android.tools.r8.KotlinCompilerTool.KotlinLambdaGeneration.CLASS;
+import static com.android.tools.r8.KotlinCompilerTool.KotlinLambdaGeneration.INVOKE_DYNAMIC;
+import static com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion.JAVA_6;
+import static com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion.JAVA_8;
import static com.android.tools.r8.ToolHelper.isWindows;
import static com.google.common.io.Files.getNameWithoutExtension;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -67,20 +71,26 @@
throw new Unimplemented("JvmTarget not specified for " + this);
}
}
+
+ public boolean isDefaultForVersion(KotlinCompilerVersion version) {
+ return this == version.defaultTargetVersion;
+ }
}
public enum KotlinCompilerVersion implements Ordered<KotlinCompilerVersion> {
- KOTLINC_1_3_72("kotlin-compiler-1.3.72", KotlinLambdaGeneration.CLASS),
- KOTLINC_1_4_20("kotlin-compiler-1.4.20", KotlinLambdaGeneration.CLASS),
- KOTLINC_1_5_0("kotlin-compiler-1.5.0", KotlinLambdaGeneration.CLASS),
- KOTLINC_1_6_0("kotlin-compiler-1.6.0", KotlinLambdaGeneration.CLASS),
- KOTLINC_1_7_0("kotlin-compiler-1.7.0", KotlinLambdaGeneration.CLASS),
- KOTLINC_1_8_0("kotlin-compiler-1.8.0", KotlinLambdaGeneration.CLASS),
- KOTLINC_1_9_21("kotlin-compiler-1.9.21", KotlinLambdaGeneration.CLASS),
- KOTLINC_2_0_20("kotlin-compiler-2.0.20", KotlinLambdaGeneration.INVOKE_DYNAMIC),
- KOTLINC_2_1_10("kotlin-compiler-2.1.10", KotlinLambdaGeneration.INVOKE_DYNAMIC),
- KOTLINC_2_2_0_Beta2("kotlin-compiler-2.2.0-Beta2", KotlinLambdaGeneration.INVOKE_DYNAMIC),
- KOTLIN_DEV("kotlin-compiler-dev", KotlinLambdaGeneration.INVOKE_DYNAMIC);
+ KOTLINC_1_3_72("kotlin-compiler-1.3.72", CLASS, JAVA_6),
+ KOTLINC_1_4_20("kotlin-compiler-1.4.20", CLASS, JAVA_6),
+ // JVM target 1,8 default from Kotlin 1.5.0,
+ // https://kotlinlang.org/docs/whatsnew15.html#new-default-jvm-target-1-8
+ KOTLINC_1_5_0("kotlin-compiler-1.5.0", CLASS, JAVA_8),
+ KOTLINC_1_6_0("kotlin-compiler-1.6.0", CLASS, JAVA_8),
+ KOTLINC_1_7_0("kotlin-compiler-1.7.0", CLASS, JAVA_8),
+ KOTLINC_1_8_0("kotlin-compiler-1.8.0", CLASS, JAVA_8),
+ KOTLINC_1_9_21("kotlin-compiler-1.9.21", CLASS, JAVA_8),
+ KOTLINC_2_0_20("kotlin-compiler-2.0.20", INVOKE_DYNAMIC, JAVA_8),
+ KOTLINC_2_1_10("kotlin-compiler-2.1.10", INVOKE_DYNAMIC, JAVA_8),
+ KOTLINC_2_2_0_Beta2("kotlin-compiler-2.2.0-Beta2", INVOKE_DYNAMIC, JAVA_8),
+ KOTLIN_DEV("kotlin-compiler-dev", INVOKE_DYNAMIC, JAVA_8);
public static final KotlinCompilerVersion MIN_SUPPORTED_VERSION = KOTLINC_2_1_10;
public static final KotlinCompilerVersion MAX_SUPPORTED_VERSION = KOTLINC_2_1_10;
@@ -89,10 +99,15 @@
private final String folder;
private final KotlinLambdaGeneration defaultLambdaGeneration;
+ private final KotlinTargetVersion defaultTargetVersion;
- KotlinCompilerVersion(String folder, KotlinLambdaGeneration defaultLambdaGeneration) {
+ KotlinCompilerVersion(
+ String folder,
+ KotlinLambdaGeneration defaultLambdaGeneration,
+ KotlinTargetVersion defaultTargetVersion) {
this.folder = folder;
this.defaultLambdaGeneration = defaultLambdaGeneration;
+ this.defaultTargetVersion = defaultTargetVersion;
}
public static KotlinCompilerVersion latest() {
@@ -333,17 +348,17 @@
// This forces using invokedynamic for Kotlin lambdas.
public KotlinCompilerTool generateLambdaClasses() {
- assert !additionalArguments.contains(KotlinLambdaGeneration.CLASS.getKotlincFlag())
- && !additionalArguments.contains(KotlinLambdaGeneration.INVOKE_DYNAMIC.getKotlincFlag());
- addArguments(KotlinLambdaGeneration.CLASS.getKotlincFlag());
+ assert !additionalArguments.contains(CLASS.getKotlincFlag())
+ && !additionalArguments.contains(INVOKE_DYNAMIC.getKotlincFlag());
+ addArguments(CLASS.getKotlincFlag());
return this;
}
// This forces generation kotlinc of lambda classes for Kotlin lambdas
public KotlinCompilerTool generateInvokeDynamic() {
- assert !additionalArguments.contains(KotlinLambdaGeneration.CLASS.getKotlincFlag())
- && !additionalArguments.contains(KotlinLambdaGeneration.INVOKE_DYNAMIC.getKotlincFlag());
- addArguments(KotlinLambdaGeneration.INVOKE_DYNAMIC.getKotlincFlag());
+ assert !additionalArguments.contains(CLASS.getKotlincFlag())
+ && !additionalArguments.contains(INVOKE_DYNAMIC.getKotlincFlag());
+ addArguments(INVOKE_DYNAMIC.getKotlincFlag());
return this;
}
diff --git a/src/test/testbase/java/com/android/tools/r8/KotlinTestParameters.java b/src/test/testbase/java/com/android/tools/r8/KotlinTestParameters.java
index 3d7cc45..78c69ad 100644
--- a/src/test/testbase/java/com/android/tools/r8/KotlinTestParameters.java
+++ b/src/test/testbase/java/com/android/tools/r8/KotlinTestParameters.java
@@ -92,10 +92,14 @@
public static class Builder {
+ private static Predicate<KotlinLambdaGeneration> defaultLambdaGenerationFilter = t -> false;
+ private static Predicate<KotlinTargetVersion> defaultTargetVersionFilter = t -> false;
+
private Predicate<KotlinCompilerVersion> compilerFilter = c -> false;
private Predicate<KotlinCompilerVersion> oldCompilerFilter = c -> true;
- private Predicate<KotlinTargetVersion> targetVersionFilter = t -> false;
- private Predicate<KotlinLambdaGeneration> lambdaGenerationFilter = t -> false;
+ private Predicate<KotlinTargetVersion> targetVersionFilter = defaultTargetVersionFilter;
+ private Predicate<KotlinLambdaGeneration> lambdaGenerationFilter =
+ defaultLambdaGenerationFilter;
private boolean withDevCompiler =
System.getProperty("com.android.tools.r8.kotlincompilerdev") != null;
private boolean withOldCompilers =
@@ -138,8 +142,8 @@
return this;
}
- public Builder withAllCompilersLambdaGenerationsAndTargetVersions() {
- return withAllCompilers().withAllLambdaGenerations().withAllTargetVersions();
+ public Builder withAllCompilersAndLambdaGenerations() {
+ return withAllCompilers().withAllLambdaGenerations();
}
public Builder withDevCompiler() {
@@ -181,6 +185,15 @@
return withTargetVersion(KotlinTargetVersion.NONE);
}
+ public Builder withLatestCompiler() {
+ return withCompiler(KotlinCompilerVersion.MAX_SUPPORTED_VERSION);
+ }
+
+ public Builder withCompiler(KotlinCompilerVersion version) {
+ withCompilerFilter(c -> c.isEqualTo(version));
+ return this;
+ }
+
public Builder withCompilersStartingFromIncluding(KotlinCompilerVersion version) {
withCompilerFilter(c -> c.isGreaterThanOrEqualTo(version));
return this;
@@ -217,7 +230,7 @@
&& kotlinVersion.isGreaterThanOrEqualTo(KotlinCompilerVersion.KOTLINC_1_5_0)) {
continue;
}
- // Only test lambda both types of lambda generation with the latest version and the dev
+ // Only test both types of lambda generation with the latest version and the dev
// version.
assert KotlinCompilerVersion.KOTLIN_DEV.isGreaterThan(
KotlinCompilerVersion.MAX_SUPPORTED_VERSION);
@@ -225,8 +238,12 @@
&& kotlinVersion.isLessThan(KotlinCompilerVersion.MAX_SUPPORTED_VERSION)) {
continue;
}
- if (targetVersionFilter.test(targetVersion)) {
- if (lambdaGenerationFilter.test(lambdaGeneration)) {
+ if (targetVersionFilter.test(targetVersion)
+ || (targetVersionFilter == defaultTargetVersionFilter
+ && targetVersion.isDefaultForVersion(kotlinVersion))) {
+ if (lambdaGenerationFilter.test(lambdaGeneration)
+ || (lambdaGenerationFilter == defaultLambdaGenerationFilter
+ && lambdaGeneration.isDefaultForVersion(kotlinVersion))) {
testParameters.add(
new KotlinTestParameters(
new KotlinCompiler(kotlinVersion),
diff --git a/src/test/testbase/java/com/android/tools/r8/TestBase.java b/src/test/testbase/java/com/android/tools/r8/TestBase.java
index e0bdbb1..0ba9f8a 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestBase.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestBase.java
@@ -999,7 +999,7 @@
profileCollectionAdditions,
ImmediateAppSubtypingInfo.create(appView),
appView.options().getProguardConfiguration().getRules())
- .build(executor);
+ .evaluateRulesAndBuild(executor);
appView.setRootSet(rootSet);
appView.rebuildAppInfo();
EnqueuerResult enqueuerResult =
diff --git a/tools/perf.py b/tools/perf.py
index 36e6cfc..cc8196c 100755
--- a/tools/perf.py
+++ b/tools/perf.py
@@ -254,15 +254,16 @@
ArchiveOutputFile(result_file,
GetArtifactLocation(benchmark, target, options.version,
'result.json'),
- outdir=options.outdir)
+ outdir=options.outdir, options=options)
-def ArchiveOutputFile(file, dest, bucket=BUCKET, header=None, outdir=None):
+def ArchiveOutputFile(file, dest, bucket=BUCKET, header=None, outdir=None,
+ options=None):
if outdir:
dest_in_outdir = os.path.join(outdir, dest)
os.makedirs(os.path.dirname(dest_in_outdir), exist_ok=True)
shutil.copyfile(file, dest_in_outdir)
- else:
+ elif not options or not options.no_upload_benchmark_data_to_google_storage:
utils.upload_file_to_cloud_storage(file,
GetGSLocation(dest, bucket=bucket),
header=header)