Merge commit '4f8d9cc38b58363e5810c4734f95350fc9b1e889' into dev-release
diff --git a/.gitignore b/.gitignore index 080826a..7a9429b 100644 --- a/.gitignore +++ b/.gitignore
@@ -114,6 +114,8 @@ third_party/kotlin/kotlin-compiler-1.4.20 third_party/kotlin/kotlin-compiler-1.5.0.tar.gz third_party/kotlin/kotlin-compiler-1.5.0 +third_party/kotlin/kotlin-compiler-dev.tar.gz +third_party/kotlin/kotlin-compiler-dev third_party/kotlinx-coroutines-1.3.6.tar.gz third_party/kotlinx-coroutines-1.3.6 third_party/nest/*
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index c5485c1..ae6487f 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -489,6 +489,14 @@ } } builders { + name: "linux-kotlin-dev" + mixins: "linux" + mixins: "normal" + recipe { + properties_j: "test_options:[\"--no_internal\", \"--runtimes=dex-default:jdk11\", \"--kotlin-compiler-dev\", \"--one_line_per_test\", \"--archive_failures\", \"*kotlin*\"]" + } + } + builders { name: "windows" mixins: "win" recipe {
diff --git a/infra/config/global/generated/cr-buildbucket.cfg b/infra/config/global/generated/cr-buildbucket.cfg index c105138..3d645b7 100644 --- a/infra/config/global/generated/cr-buildbucket.cfg +++ b/infra/config/global/generated/cr-buildbucket.cfg
@@ -83,6 +83,48 @@ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" } builders { + name: "desugared_library_head" + swarming_host: "chrome-swarming.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.r8.ci" + recipe { + name: "rex" + cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build_limited/scripts/slave" + cipd_version: "refs/heads/master" + properties_j: "builder_group:\"internal.client.r8\"" + properties_j: "test_options:[\"--no_internal\",\"--desugared-library\",\"HEAD\"]" + } + priority: 26 + execution_timeout_secs: 43200 + expiration_secs: 126000 + build_numbers: YES + service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + } + builders { + name: "desugared_library_jdk11_head" + swarming_host: "chrome-swarming.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.r8.ci" + recipe { + name: "rex" + cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build_limited/scripts/slave" + cipd_version: "refs/heads/master" + properties_j: "builder_group:\"internal.client.r8\"" + properties_j: "test_options:[\"--no_internal\",\"--desugared-library\",\"HEAD\",\"--desugared-library-configuration\",\"jdk11\"]" + } + priority: 26 + execution_timeout_secs: 43200 + expiration_secs: 126000 + build_numbers: YES + service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + } + builders { name: "linux-android-4.0.4" swarming_host: "chrome-swarming.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -747,6 +789,27 @@ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" } builders { + name: "linux-kotlin-dev" + swarming_host: "chrome-swarming.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.r8.ci" + recipe { + name: "rex" + cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build_limited/scripts/slave" + cipd_version: "refs/heads/master" + properties_j: "builder_group:\"internal.client.r8\"" + properties_j: "test_options:[\"--runtimes=dex-default:jdk11\",\"--kotlin-compiler-dev\",\"--one_line_per_test\",\"--archive_failures\",\"--no-internal\",\"*kotlin*\"]" + } + priority: 26 + execution_timeout_secs: 43200 + expiration_secs: 126000 + build_numbers: YES + service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + } + builders { name: "linux-none" swarming_host: "chrome-swarming.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -839,6 +902,50 @@ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" } builders { + name: "linux-run-on-app-dump" + swarming_host: "chrome-swarming.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.r8.ci" + recipe { + name: "rex" + cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build_limited/scripts/slave" + cipd_version: "refs/heads/master" + properties_j: "builder_group:\"internal.client.r8\"" + properties_j: "test_options:[\"--bot\"]" + properties_j: "test_wrapper:\"tools/run_on_app_dump.py\"" + } + priority: 26 + execution_timeout_secs: 43200 + expiration_secs: 126000 + build_numbers: YES + service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + } + builders { + name: "linux-run-on-app-dump_release" + swarming_host: "chrome-swarming.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.r8.ci" + recipe { + name: "rex" + cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build_limited/scripts/slave" + cipd_version: "refs/heads/master" + properties_j: "builder_group:\"internal.client.r8\"" + properties_j: "test_options:[\"--bot\"]" + properties_j: "test_wrapper:\"tools/run_on_app_dump.py\"" + } + priority: 26 + execution_timeout_secs: 43200 + expiration_secs: 126000 + build_numbers: YES + service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + } + builders { name: "windows" 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 7ffcae6..736c8cc 100644 --- a/infra/config/global/generated/luci-milo.cfg +++ b/infra/config/global/generated/luci-milo.cfg
@@ -31,6 +31,26 @@ short_name: "r8cf_jctf_release" } builders { + name: "buildbucket/luci.r8.ci/linux-run-on-app-dump" + category: "R8" + short_name: "dump" + } + builders { + name: "buildbucket/luci.r8.ci/linux-run-on-app-dump_release" + category: "R8 release" + short_name: "dump_release" + } + builders { + name: "buildbucket/luci.r8.ci/desugared_library_head" + category: "R8" + short_name: "desugared_library_head" + } + builders { + name: "buildbucket/luci.r8.ci/desugared_library_jdk11_head" + category: "R8" + short_name: "desugared_library_jdk11_head" + } + builders { name: "buildbucket/luci.r8.ci/archive" category: "R8" short_name: "archive" @@ -205,4 +225,9 @@ category: "R8 release" short_name: "windows_release" } + builders { + name: "buildbucket/luci.r8.ci/linux-kotlin-dev" + category: "R8" + short_name: "dev" + } }
diff --git a/infra/config/global/generated/luci-notify.cfg b/infra/config/global/generated/luci-notify.cfg index 25f83b5..8228f3e 100644 --- a/infra/config/global/generated/luci-notify.cfg +++ b/infra/config/global/generated/luci-notify.cfg
@@ -36,6 +36,30 @@ } builders { bucket: "ci" + name: "desugared_library_head" + repository: "https://r8.googlesource.com/r8" + } +} +notifiers { + notifications { + on_failure: true + on_new_failure: true + notify_blamelist {} + } + builders { + bucket: "ci" + name: "desugared_library_jdk11_head" + repository: "https://r8.googlesource.com/r8" + } +} +notifiers { + notifications { + on_failure: true + on_new_failure: true + notify_blamelist {} + } + builders { + bucket: "ci" name: "linux-android-4.0.4" repository: "https://r8.googlesource.com/r8" } @@ -396,6 +420,18 @@ } builders { bucket: "ci" + name: "linux-kotlin-dev" + repository: "https://r8.googlesource.com/r8" + } +} +notifiers { + notifications { + on_failure: true + on_new_failure: true + notify_blamelist {} + } + builders { + bucket: "ci" name: "linux-none" repository: "https://r8.googlesource.com/r8" } @@ -444,6 +480,30 @@ } builders { bucket: "ci" + name: "linux-run-on-app-dump" + repository: "https://r8.googlesource.com/r8" + } +} +notifiers { + notifications { + on_failure: true + on_new_failure: true + notify_blamelist {} + } + builders { + bucket: "ci" + name: "linux-run-on-app-dump_release" + repository: "https://r8.googlesource.com/r8" + } +} +notifiers { + notifications { + on_failure: true + on_new_failure: true + notify_blamelist {} + } + builders { + bucket: "ci" name: "windows" 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 e915f53..46abc44 100644 --- a/infra/config/global/generated/luci-scheduler.cfg +++ b/infra/config/global/generated/luci-scheduler.cfg
@@ -47,6 +47,24 @@ } } job { + id: "desugared_library_head" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.r8.ci" + builder: "desugared_library_head" + } +} +job { + id: "desugared_library_jdk11_head" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.r8.ci" + builder: "desugared_library_jdk11_head" + } +} +job { id: "linux-android-4.0.4" acl_sets: "ci" buildbucket { @@ -327,6 +345,15 @@ } } job { + id: "linux-kotlin-dev" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.r8.ci" + builder: "linux-kotlin-dev" + } +} +job { id: "linux-none" acl_sets: "ci" buildbucket { @@ -363,6 +390,24 @@ } } job { + id: "linux-run-on-app-dump" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.r8.ci" + builder: "linux-run-on-app-dump" + } +} +job { + id: "linux-run-on-app-dump_release" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.r8.ci" + builder: "linux-run-on-app-dump_release" + } +} +job { id: "windows" acl_sets: "ci" buildbucket { @@ -401,6 +446,7 @@ triggers: "linux-jdk9_release" triggers: "linux-none_release" triggers: "linux-r8cf_jctf_release" + triggers: "linux-run-on-app-dump_release" triggers: "windows_release" gitiles { repo: "https://r8.googlesource.com/r8" @@ -412,6 +458,8 @@ id: "main-gitiles-trigger" acl_sets: "ci" triggers: "archive" + triggers: "desugared_library_head" + triggers: "desugared_library_jdk11_head" triggers: "linux-android-4.0.4" triggers: "linux-android-4.4.4" triggers: "linux-android-5.1.1" @@ -427,12 +475,14 @@ triggers: "linux-jdk11" triggers: "linux-jdk8" triggers: "linux-jdk9" + triggers: "linux-kotlin-dev" triggers: "linux-none" triggers: "linux-r8cf_jctf" + triggers: "linux-run-on-app-dump" triggers: "windows" gitiles { repo: "https://r8.googlesource.com/r8" - refs: "regexp:refs/heads/master" + refs: "regexp:refs/heads/main" } } acl_sets {
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index 3c2ad37..2dd3fcb 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -101,6 +101,11 @@ short_name: "cf-jctf" } builders { + name: "buildbucket/luci.r8.ci/linux-kotlin-dev" + category: "R8" + short_name: "kotlin-dev" + } + builders { name: "buildbucket/luci.r8.ci/windows" category: "win" short_name: "win"
diff --git a/infra/config/global/luci-notify.cfg b/infra/config/global/luci-notify.cfg index 1e0eb27..2ed0fc7 100644 --- a/infra/config/global/luci-notify.cfg +++ b/infra/config/global/luci-notify.cfg
@@ -174,6 +174,11 @@ repository: "https://r8.googlesource.com/r8" } builders { + name: "linux-kotlin-dev" + bucket: "ci" + repository: "https://r8.googlesource.com/r8" + } + builders { name: "windows" bucket: "ci" repository: "https://r8.googlesource.com/r8"
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index f585e8d..6af1a32 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -44,6 +44,7 @@ triggers: "linux-internal" triggers: "linux-jctf" triggers: "r8cf-linux-jctf" + triggers: "linux-kotlin-dev" triggers: "windows" triggers: "desugared_library_head" triggers: "desugared_library_jdk11_head" @@ -687,6 +688,20 @@ } job { + id: "linux-kotlin-dev" + acl_sets: "default" + triggering_policy: { + kind: GREEDY_BATCHING + max_concurrent_invocations: 2 + } + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.r8.ci" + builder: "linux-kotlin-dev" + } +} + +job { id: "windows" triggering_policy: { kind: GREEDY_BATCHING
diff --git a/infra/config/global/main.star b/infra/config/global/main.star index beda63e..5e790b5 100755 --- a/infra/config/global/main.star +++ b/infra/config/global/main.star
@@ -169,6 +169,41 @@ ) jctf() +def app_dump(): + for release in ["", "_release"]: + properties = { + "builder_group" : "internal.client.r8", + "test_options" : ["--bot"], + "test_wrapper" : "tools/run_on_app_dump.py" + } + name = "linux-run-on-app-dump" + release + r8_builder( + name, + dimensions = get_dimensions(), + execution_timeout = time.hour * 12, + expiration_timeout = time.hour * 35, + properties = properties, + ) +app_dump() + +def desugared_library(): + for name in ["head", "jdk11_head"]: + test_options = ["--no_internal", "--desugared-library", "HEAD"] + if "jdk11" in name: + test_options = test_options + ["--desugared-library-configuration", "jdk11"] + properties = { + "builder_group" : "internal.client.r8", + "test_options" : test_options, + } + name = "desugared_library_" + name + r8_builder( + name, + dimensions = get_dimensions(), + execution_timeout = time.hour * 12, + expiration_timeout = time.hour * 35, + properties = properties, + ) +desugared_library() def archivers(): for name in ["archive", "archive_release", "archive_lib_desugar"]: @@ -242,3 +277,14 @@ r8_tester_with_default("windows", ["--all_tests"], dimensions=get_dimensions(windows=True)) + +r8_builder( + "linux-kotlin-dev", + dimensions = get_dimensions(), + execution_timeout = time.hour * 12, + expiration_timeout = time.hour * 35, + properties = { + "builder_group" : "internal.client.r8", + "test_options" : ["--runtimes=dex-default:jdk11", "--kotlin-compiler-dev", "--one_line_per_test", "--archive_failures", "--no-internal", "*kotlin*"] + } +)
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java index 02ef891..65a9a2f 100644 --- a/src/main/java/com/android/tools/r8/R8.java +++ b/src/main/java/com/android/tools/r8/R8.java
@@ -57,8 +57,6 @@ import com.android.tools.r8.ir.optimize.SwitchMapCollector; import com.android.tools.r8.ir.optimize.UninstantiatedTypeOptimization; import com.android.tools.r8.ir.optimize.UninstantiatedTypeOptimization.UninstantiatedTypeOptimizationGraphLens; -import com.android.tools.r8.ir.optimize.UnusedArgumentsCollector; -import com.android.tools.r8.ir.optimize.UnusedArgumentsCollector.UnusedArgumentsGraphLens; import com.android.tools.r8.ir.optimize.enums.EnumUnboxingCfMethods; import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple; import com.android.tools.r8.ir.optimize.templates.CfUtilityMethodsForCodeOptimizations; @@ -512,32 +510,15 @@ } assert appView.verticallyMergedClasses() != null; - if (options.enableArgumentRemoval) { - SubtypingInfo subtypingInfo = appViewWithLiveness.appInfo().computeSubtypingInfo(); - { - timing.begin("UnusedArgumentRemoval"); - UnusedArgumentsGraphLens lens = - new UnusedArgumentsCollector( - appViewWithLiveness, - new MethodPoolCollection(appViewWithLiveness, subtypingInfo)) - .run(executorService, timing); - assert lens == null || getDirectApp(appView).verifyNothingToRewrite(appView, lens); - appView.rewriteWithLens(lens); - timing.end(); - } - if (options.enableUninstantiatedTypeOptimization) { - timing.begin("UninstantiatedTypeOptimization"); - UninstantiatedTypeOptimizationGraphLens lens = - new UninstantiatedTypeOptimization(appViewWithLiveness) - .strenghtenOptimizationInfo() - .run( - new MethodPoolCollection(appViewWithLiveness, subtypingInfo), - executorService, - timing); - assert lens == null || getDirectApp(appView).verifyNothingToRewrite(appView, lens); - appView.rewriteWithLens(lens); - timing.end(); - } + if (options.enableUninstantiatedTypeOptimization) { + timing.begin("UninstantiatedTypeOptimization"); + UninstantiatedTypeOptimizationGraphLens lens = + new UninstantiatedTypeOptimization(appViewWithLiveness) + .strenghtenOptimizationInfo() + .run(new MethodPoolCollection(appViewWithLiveness), executorService, timing); + assert lens == null || getDirectApp(appView).verifyNothingToRewrite(appView, lens); + appView.rewriteWithLens(lens); + timing.end(); } HorizontalClassMerger.createForInitialClassMerging(appViewWithLiveness)
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java b/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java index 71bc104..227270d 100644 --- a/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java +++ b/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java
@@ -28,6 +28,7 @@ INVOKE_DIRECT((short) 0x07), INVOKE_INTERFACE((short) 0x08), // Internal method handle needed by lambda desugaring. + // TODO(b/200254463): Remove this now that lambda desugaring is CF/CF. INVOKE_SUPER((short) 0x09); private final short value;
diff --git a/src/main/java/com/android/tools/r8/graph/InvalidCode.java b/src/main/java/com/android/tools/r8/graph/InvalidCode.java index 418de86..5363897 100644 --- a/src/main/java/com/android/tools/r8/graph/InvalidCode.java +++ b/src/main/java/com/android/tools/r8/graph/InvalidCode.java
@@ -44,7 +44,11 @@ @Override public String toString(DexEncodedMethod method, ClassNameMapper naming) { - return toString(); + StringBuilder builder = new StringBuilder(); + if (method != null) { + builder.append(method.toSourceString()).append("\n"); + } + return builder.append(this).toString(); } @Override
diff --git a/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java index 1133b65..a4a886f 100644 --- a/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java +++ b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java
@@ -18,9 +18,9 @@ import com.android.tools.r8.utils.IteratorUtils; import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; -import it.unimi.dsi.fastutil.ints.Int2ReferenceMap.Entry; -import it.unimi.dsi.fastutil.ints.Int2ReferenceRBTreeMap; -import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry; +import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntBidirectionalIterator; import it.unimi.dsi.fastutil.ints.IntCollection; @@ -31,14 +31,35 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.function.Consumer; public class RewrittenPrototypeDescription { - public interface ArgumentInfo { + public abstract static class ArgumentInfo { + + static final ArgumentInfo NO_INFO = + new ArgumentInfo() { + + @Override + public ArgumentInfo combine(ArgumentInfo info) { + assert false : "ArgumentInfo NO_INFO should not be combined"; + return info; + } + + @Override + public boolean equals(Object obj) { + return obj == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + }; @SuppressWarnings("ConstantConditions") - static ArgumentInfo combine(ArgumentInfo arg1, ArgumentInfo arg2) { + public static ArgumentInfo combine(ArgumentInfo arg1, ArgumentInfo arg2) { if (arg1 == null) { assert arg2 != null; return arg2; @@ -50,33 +71,33 @@ return arg1.combine(arg2); } - ArgumentInfo NO_INFO = - info -> { - assert false : "ArgumentInfo NO_INFO should not be combined"; - return info; - }; - - default boolean isRemovedArgumentInfo() { + public boolean isRemovedArgumentInfo() { return false; } - default RemovedArgumentInfo asRemovedArgumentInfo() { + public RemovedArgumentInfo asRemovedArgumentInfo() { return null; } - default boolean isRewrittenTypeInfo() { + public boolean isRewrittenTypeInfo() { return false; } - default RewrittenTypeInfo asRewrittenTypeInfo() { + public RewrittenTypeInfo asRewrittenTypeInfo() { return null; } // ArgumentInfo are combined with `this` first, and the `info` argument second. - ArgumentInfo combine(ArgumentInfo info); + public abstract ArgumentInfo combine(ArgumentInfo info); + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract int hashCode(); } - public static class RemovedArgumentInfo implements ArgumentInfo { + public static class RemovedArgumentInfo extends ArgumentInfo { public static class Builder { @@ -142,9 +163,23 @@ assert false : "Once the argument is removed one cannot modify it any further."; return this; } + + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + RemovedArgumentInfo other = (RemovedArgumentInfo) obj; + return type == other.type && Objects.equals(singleValue, other.singleValue); + } + + @Override + public int hashCode() { + return Objects.hash(singleValue, type); + } } - public static class RewrittenTypeInfo implements ArgumentInfo { + public static class RewrittenTypeInfo extends ArgumentInfo { private final DexType oldType; private final DexType newType; @@ -201,6 +236,20 @@ return new RewrittenTypeInfo(oldType, rewrittenTypeInfo.newType); } + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + RewrittenTypeInfo other = (RewrittenTypeInfo) obj; + return oldType == other.oldType && newType == other.newType; + } + + @Override + public int hashCode() { + return Objects.hash(oldType, newType); + } + public boolean verifyIsDueToUnboxing(DexItemFactory dexItemFactory) { assert oldType.toBaseType(dexItemFactory).isClassType(); assert newType.toBaseType(dexItemFactory).isIntType(); @@ -212,14 +261,14 @@ private static final ArgumentInfoCollection EMPTY = new ArgumentInfoCollection(); - private final Int2ReferenceSortedMap<ArgumentInfo> argumentInfos; + private final Int2ObjectSortedMap<ArgumentInfo> argumentInfos; // Specific constructor for empty. private ArgumentInfoCollection() { - this.argumentInfos = new Int2ReferenceRBTreeMap<>(); + this.argumentInfos = new Int2ObjectRBTreeMap<>(); } - private ArgumentInfoCollection(Int2ReferenceSortedMap<ArgumentInfo> argumentInfos) { + private ArgumentInfoCollection(Int2ObjectSortedMap<ArgumentInfo> argumentInfos) { assert argumentInfos != null : "should use empty."; assert !argumentInfos.isEmpty() : "should use empty."; this.argumentInfos = argumentInfos; @@ -230,7 +279,7 @@ } public void forEach(IntObjConsumer<ArgumentInfo> consumer) { - for (Entry<ArgumentInfo> entry : argumentInfos.int2ReferenceEntrySet()) { + for (Entry<ArgumentInfo> entry : argumentInfos.int2ObjectEntrySet()) { consumer.accept(entry.getIntKey(), entry.getValue()); } } @@ -267,7 +316,7 @@ } public Iterator<Entry<ArgumentInfo>> iterator() { - return argumentInfos.int2ReferenceEntrySet().iterator(); + return argumentInfos.int2ObjectEntrySet().iterator(); } public boolean hasRemovedArguments() { @@ -301,17 +350,31 @@ return argumentInfos.size(); } + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + ArgumentInfoCollection other = (ArgumentInfoCollection) obj; + return argumentInfos.equals(other.argumentInfos); + } + + @Override + public int hashCode() { + return argumentInfos.hashCode(); + } + public static Builder builder() { return new Builder(); } public static class Builder { - private Int2ReferenceSortedMap<ArgumentInfo> argumentInfos; + private Int2ObjectSortedMap<ArgumentInfo> argumentInfos; public Builder addArgumentInfo(int argIndex, ArgumentInfo argInfo) { if (argumentInfos == null) { - argumentInfos = new Int2ReferenceRBTreeMap<>(); + argumentInfos = new Int2ObjectRBTreeMap<>(); } assert !argumentInfos.containsKey(argIndex); argumentInfos.put(argIndex, argInfo); @@ -377,7 +440,7 @@ } } - Int2ReferenceSortedMap<ArgumentInfo> newArgInfos = new Int2ReferenceRBTreeMap<>(); + Int2ObjectSortedMap<ArgumentInfo> newArgInfos = new Int2ObjectRBTreeMap<>(); newArgInfos.putAll(argumentInfos); IntBidirectionalIterator iterator = argumentInfos.keySet().iterator(); int offset = 0; @@ -477,7 +540,7 @@ assert !isEmpty(); } - private static RewrittenPrototypeDescription create( + public static RewrittenPrototypeDescription create( List<ExtraParameter> extraParameters, RewrittenTypeInfo rewrittenReturnInfo, ArgumentInfoCollection argumentsInfo) { @@ -507,6 +570,11 @@ return NONE; } + public Consumer<DexEncodedMethod.Builder> createParameterAnnotationsRemover( + DexEncodedMethod method) { + return getArgumentInfoCollection().createParameterAnnotationsRemover(method); + } + public MethodOptimizationInfoFixer createMethodOptimizationInfoFixer() { return new RewrittenPrototypeDescriptionMethodOptimizationInfoFixer(this); } @@ -661,4 +729,20 @@ return new RewrittenPrototypeDescription( newExtraParameters, rewrittenReturnInfo, argumentInfoCollection); } + + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + RewrittenPrototypeDescription other = (RewrittenPrototypeDescription) obj; + return extraParameters.equals(other.extraParameters) + && Objects.equals(rewrittenReturnInfo, other.rewrittenReturnInfo) + && argumentInfoCollection.equals(other.argumentInfoCollection); + } + + @Override + public int hashCode() { + return Objects.hash(extraParameters, rewrittenReturnInfo, argumentInfoCollection); + } }
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java index 83dfa77..0f2e98a 100644 --- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java +++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -46,6 +46,10 @@ || result == null; } + public static Builder builder() { + return new Builder(); + } + @Override public int opcode() { return Opcodes.INVOKE_DIRECT; @@ -210,4 +214,17 @@ return LibraryMethodReadSetModeling.getModeledReadSetOrUnknown(appView, this); } + + public static class Builder extends InvokeMethod.Builder<Builder, InvokeDirect> { + + @Override + public InvokeDirect build() { + return amend(new InvokeDirect(method, outValue, arguments)); + } + + @Override + public Builder self() { + return this; + } + } }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java index 5d49406..fa59829 100644 --- a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java +++ b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
@@ -12,6 +12,7 @@ import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer; +import com.android.tools.r8.ir.desugar.itf.InterfaceProcessor; import com.android.tools.r8.utils.ThreadUtils; import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; @@ -26,18 +27,28 @@ protected final AppView<?> appView; private final IRConverter converter; private final D8MethodProcessor methodProcessor; + private final InterfaceProcessor interfaceProcessor; - ClassConverter(AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) { + ClassConverter( + AppView<?> appView, + IRConverter converter, + D8MethodProcessor methodProcessor, + InterfaceProcessor interfaceProcessor) { this.appView = appView; this.converter = converter; this.methodProcessor = methodProcessor; + this.interfaceProcessor = interfaceProcessor; } public static ClassConverter create( - AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) { + AppView<?> appView, + IRConverter converter, + D8MethodProcessor methodProcessor, + InterfaceProcessor interfaceProcessor) { return appView.options().desugarSpecificOptions().allowAllDesugaredInput - ? new LibraryDesugaredClassConverter(appView, converter, methodProcessor) - : new DefaultClassConverter(appView, converter, methodProcessor); + ? new LibraryDesugaredClassConverter( + appView, converter, methodProcessor, interfaceProcessor) + : new DefaultClassConverter(appView, converter, methodProcessor, interfaceProcessor); } public ClassConverterResult convertClasses(ExecutorService executorService) @@ -125,7 +136,7 @@ void convertMethods( DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer) { - converter.convertMethods(clazz, desugaringEventConsumer, methodProcessor); + converter.convertMethods(clazz, desugaringEventConsumer, methodProcessor, interfaceProcessor); } abstract void notifyAllClassesConverted(); @@ -133,8 +144,11 @@ static class DefaultClassConverter extends ClassConverter { DefaultClassConverter( - AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) { - super(appView, converter, methodProcessor); + AppView<?> appView, + IRConverter converter, + D8MethodProcessor methodProcessor, + InterfaceProcessor interfaceProcessor) { + super(appView, converter, methodProcessor, interfaceProcessor); } @Override @@ -154,8 +168,11 @@ private final Set<DexType> alreadyLibraryDesugared = Sets.newConcurrentHashSet(); LibraryDesugaredClassConverter( - AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) { - super(appView, converter, methodProcessor); + AppView<?> appView, + IRConverter converter, + D8MethodProcessor methodProcessor, + InterfaceProcessor interfaceProcessor) { + super(appView, converter, methodProcessor, interfaceProcessor); } @Override
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ExtraConstantIntParameter.java b/src/main/java/com/android/tools/r8/ir/conversion/ExtraConstantIntParameter.java index d698e7a..b0544d9 100644 --- a/src/main/java/com/android/tools/r8/ir/conversion/ExtraConstantIntParameter.java +++ b/src/main/java/com/android/tools/r8/ir/conversion/ExtraConstantIntParameter.java
@@ -10,7 +10,8 @@ import com.android.tools.r8.ir.analysis.value.SingleNumberValue; public class ExtraConstantIntParameter extends ExtraParameter { - long value; + + private final long value; public ExtraConstantIntParameter(long value) { this.value = value; @@ -26,4 +27,18 @@ public SingleNumberValue getValue(AppView<?> appView) { return appView.abstractValueFactory().createSingleNumberValue(value); } + + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + ExtraConstantIntParameter other = (ExtraConstantIntParameter) obj; + return value == other.value; + } + + @Override + public int hashCode() { + return Long.hashCode(value); + } }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ExtraParameter.java b/src/main/java/com/android/tools/r8/ir/conversion/ExtraParameter.java index 93f52df..6211fa3 100644 --- a/src/main/java/com/android/tools/r8/ir/conversion/ExtraParameter.java +++ b/src/main/java/com/android/tools/r8/ir/conversion/ExtraParameter.java
@@ -10,7 +10,14 @@ import com.android.tools.r8.ir.analysis.value.SingleNumberValue; public abstract class ExtraParameter { + public abstract TypeElement getTypeElement(AppView<?> appView, DexType argType); public abstract SingleNumberValue getValue(AppView<?> appView); + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract int hashCode(); }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ExtraUnusedNullParameter.java b/src/main/java/com/android/tools/r8/ir/conversion/ExtraUnusedNullParameter.java index f478661..a543a0c 100644 --- a/src/main/java/com/android/tools/r8/ir/conversion/ExtraUnusedNullParameter.java +++ b/src/main/java/com/android/tools/r8/ir/conversion/ExtraUnusedNullParameter.java
@@ -21,4 +21,14 @@ public SingleNumberValue getValue(AppView<?> appView) { return appView.abstractValueFactory().createNullValue(); } + + @Override + public boolean equals(Object obj) { + return obj != null && getClass() == obj.getClass(); + } + + @Override + public int hashCode() { + return 0; + } }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java index a165209..ee74491 100644 --- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java +++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -57,6 +57,7 @@ import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter; import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceApplicationRewriter; import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade; +import com.android.tools.r8.ir.desugar.itf.InterfaceProcessor; import com.android.tools.r8.ir.desugar.lambda.LambdaDeserializationMethodRemover; import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring; import com.android.tools.r8.ir.optimize.AssertionsRewriter; @@ -94,6 +95,7 @@ import com.android.tools.r8.ir.regalloc.RegisterAllocator; import com.android.tools.r8.logging.Log; import com.android.tools.r8.naming.IdentifierNameStringMarker; +import com.android.tools.r8.optimize.argumentpropagation.ArgumentPropagator; import com.android.tools.r8.position.MethodPosition; import com.android.tools.r8.shaking.AppInfoWithLiveness; import com.android.tools.r8.shaking.LibraryMethodOverrideAnalysis; @@ -362,17 +364,21 @@ executor, OptimizationFeedbackIgnore.getInstance()); DexApplication application = appView.appInfo().app(); D8MethodProcessor methodProcessor = new D8MethodProcessor(this, executor); + InterfaceProcessor interfaceProcessor = + appView.options().isInterfaceMethodDesugaringEnabled() + ? new InterfaceProcessor(appView) + : null; timing.begin("IR conversion"); - convertClasses(methodProcessor, executor); + convertClasses(methodProcessor, interfaceProcessor, executor); reportNestDesugarDependencies(); clearNestAttributes(); application = commitPendingSyntheticItemsD8(appView, application); - postProcessingDesugaringForD8(methodProcessor, executor); + postProcessingDesugaringForD8(methodProcessor, interfaceProcessor, executor); application = commitPendingSyntheticItemsD8(appView, application); @@ -424,13 +430,16 @@ } private void postProcessingDesugaringForD8( - D8MethodProcessor methodProcessor, ExecutorService executorService) + D8MethodProcessor methodProcessor, + InterfaceProcessor interfaceProcessor, + ExecutorService executorService) throws ExecutionException { D8CfPostProcessingDesugaringEventConsumer eventConsumer = CfPostProcessingDesugaringEventConsumer.createForD8(methodProcessor, instructionDesugaring); methodProcessor.newWave(); InterfaceMethodProcessorFacade interfaceDesugaring = - instructionDesugaring.getInterfaceMethodPostProcessingDesugaringD8(ExcludeDexResources); + instructionDesugaring.getInterfaceMethodPostProcessingDesugaringD8( + ExcludeDexResources, interfaceProcessor); CfPostProcessingDesugaringCollection.create( appView, interfaceDesugaring, instructionDesugaring.getRetargetingInfo()) .postProcessingDesugaring( @@ -439,10 +448,14 @@ eventConsumer.finalizeDesugaring(); } - private void convertClasses(D8MethodProcessor methodProcessor, ExecutorService executorService) + private void convertClasses( + D8MethodProcessor methodProcessor, + InterfaceProcessor interfaceProcessor, + ExecutorService executorService) throws ExecutionException { ClassConverterResult classConverterResult = - ClassConverter.create(appView, this, methodProcessor).convertClasses(executorService); + ClassConverter.create(appView, this, methodProcessor, interfaceProcessor) + .convertClasses(executorService); // The synthesis of accessibility bridges in nest based access desugaring will schedule and // await the processing of synthesized methods. @@ -475,7 +488,8 @@ void convertMethods( DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer, - D8MethodProcessor methodProcessor) { + D8MethodProcessor methodProcessor, + InterfaceProcessor interfaceProcessor) { boolean isReachabilitySensitive = clazz.hasReachabilitySensitiveAnnotation(options.itemFactory); // When converting all methods on a class always convert <clinit> first. ProgramMethod classInitializer = clazz.getProgramClassInitializer(); @@ -499,6 +513,9 @@ DexEncodedMethod definition = method.getDefinition(); definition.getMutableOptimizationInfo().setReachabilitySensitive(isReachabilitySensitive); methodProcessor.processMethod(method, desugaringEventConsumer); + if (interfaceProcessor != null) { + interfaceProcessor.processMethod(method, desugaringEventConsumer); + } } } @@ -835,6 +852,7 @@ if (options.enableFieldAssignmentTracker) { fieldAccessAnalysis.fieldAssignmentTracker().waveDone(wave, delayedOptimizationFeedback); } + appView.withArgumentPropagator(ArgumentPropagator::publishDelayedReprocessingCriteria); if (appView.options().protoShrinking().enableRemoveProtoEnumSwitchMap()) { appView.protoShrinker().protoEnumSwitchMapRemover.updateVisibleStaticFieldValues(); }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java index 9b2a145..2e9fcab 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -75,6 +75,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (!instruction.isInvoke()) { return null;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java index ea1cd46..4d9ec0e 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java
@@ -38,6 +38,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (!isInvokeCandidate(instruction)) { return null;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java index 513a9d5..810812a 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java
@@ -40,6 +40,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory); /**
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java index ada494f..8328e9b 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java
@@ -5,6 +5,7 @@ package com.android.tools.r8.ir.desugar; import com.android.tools.r8.androidapi.AndroidApiLevelCompute; +import com.android.tools.r8.cf.code.CfInstruction; import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext; import com.android.tools.r8.graph.AppView; import com.android.tools.r8.graph.ProgramMethod; @@ -15,6 +16,7 @@ import com.android.tools.r8.ir.desugar.itf.InterfaceProcessor; import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring; import com.android.tools.r8.utils.ThrowingConsumer; +import java.util.Collection; import java.util.function.Consumer; import java.util.function.Predicate; @@ -56,6 +58,15 @@ MethodProcessingContext methodProcessingContext, CfInstructionDesugaringEventConsumer eventConsumer); + /** Selective desugaring of a single invoke instruction assuming a given context. */ + public abstract Collection<CfInstruction> desugarInstruction( + CfInstruction instruction, + FreshLocalProvider freshLocalProvider, + LocalStackAllocator localStackAllocator, + CfInstructionDesugaringEventConsumer eventConsumer, + ProgramMethod context, + MethodProcessingContext methodProcessingContext); + public boolean isEmpty() { return false; } @@ -67,7 +78,7 @@ ThrowingConsumer<D8NestBasedAccessDesugaring, T> consumer) throws T; public abstract InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaringD8( - Flavor flavor); + Flavor flavor, InterfaceProcessor interfaceProcessor); public abstract InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaringR8( Flavor flavor, Predicate<ProgramMethod> isLiveMethod, InterfaceProcessor processor);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java index 8f5178e..31b8c3c 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
@@ -92,16 +92,6 @@ } @Override - public void acceptCompanionClassClinit(ProgramMethod method) { - addMethodToReprocess(method); - } - - @Override - public void acceptCompanionMethod(ProgramMethod method, ProgramMethod companion) { - // Intentionally empty. The method must be processed on the interface definition. - } - - @Override public void finalizeDesugaring() throws ExecutionException { assert methodProcessor.verifyNoPendingMethodProcessing(); methodProcessor.newWave(); @@ -170,18 +160,6 @@ } @Override - public void acceptCompanionClassClinit(ProgramMethod method) { - // Generation of this method must have been done during enqueuing. - assert false; - } - - @Override - public void acceptCompanionMethod(ProgramMethod method, ProgramMethod companion) { - // Generation of this method must have been done during enqueuing. - assert false; - } - - @Override public void acceptAPIConversionCallback(ProgramMethod method) { assert !desugaring.needsDesugaring(method); additions.addLiveMethod(method);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java index 027b27c..27b646f 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java
@@ -4,6 +4,7 @@ package com.android.tools.r8.ir.desugar; +import com.android.tools.r8.cf.code.CfInstruction; import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext; import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter; @@ -13,6 +14,7 @@ import com.android.tools.r8.ir.desugar.itf.InterfaceProcessor; import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring; import com.android.tools.r8.utils.ThrowingConsumer; +import java.util.Collection; import java.util.function.Consumer; import java.util.function.Predicate; @@ -47,6 +49,18 @@ } @Override + public Collection<CfInstruction> desugarInstruction( + CfInstruction instruction, + FreshLocalProvider freshLocalProvider, + LocalStackAllocator localStackAllocator, + CfInstructionDesugaringEventConsumer eventConsumer, + ProgramMethod context, + MethodProcessingContext methodProcessingContext) { + // Nothing to desugar. + return null; + } + + @Override public boolean isEmpty() { return true; } @@ -64,7 +78,7 @@ @Override public InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaringD8( - Flavor flavor) { + Flavor flavor, InterfaceProcessor interfaceProcessor) { return null; }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java index 7fd31a8..65f23dc 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java
@@ -35,6 +35,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (!instruction.isInvokeVirtual() && !instruction.isInvokeInterface()) { return null;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java index afedd24..bbc30e8 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -33,6 +33,7 @@ import com.android.tools.r8.ir.code.Invoke.Type; import com.android.tools.r8.ir.desugar.lambda.ForcefullyMovedLambdaMethodConsumer; import com.android.tools.r8.ir.desugar.lambda.LambdaInstructionDesugaring; +import com.android.tools.r8.ir.desugar.lambda.LambdaInstructionDesugaring.DesugarInvoke; import com.android.tools.r8.ir.optimize.info.OptimizationFeedback; import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple; import com.android.tools.r8.synthesis.SyntheticProgramClassBuilder; @@ -40,6 +41,7 @@ import java.util.Collections; import java.util.List; import java.util.function.Consumer; +import org.objectweb.asm.Opcodes; /** * Represents lambda class generated for a lambda descriptor in context of lambda instantiation @@ -81,7 +83,8 @@ AppView<?> appView, LambdaInstructionDesugaring desugaring, ProgramMethod accessedFrom, - LambdaDescriptor descriptor) { + LambdaDescriptor descriptor, + DesugarInvoke desugarInvoke) { assert desugaring != null; assert descriptor != null; this.type = builder.getType(); @@ -105,7 +108,7 @@ !stateless ? null : factory.createField(type, type, factory.lambdaInstanceFieldName); // Synthesize the program class once all fields are set. - synthesizeLambdaClass(builder); + synthesizeLambdaClass(builder, desugarInvoke); } public final DexProgramClass getLambdaProgramClass() { @@ -124,12 +127,13 @@ this.clazz = clazz; } - private void synthesizeLambdaClass(SyntheticProgramClassBuilder builder) { + private void synthesizeLambdaClass( + SyntheticProgramClassBuilder builder, DesugarInvoke desugarInvoke) { builder.setInterfaces(descriptor.interfaces); synthesizeStaticFields(builder); synthesizeInstanceFields(builder); synthesizeDirectMethods(builder); - synthesizeVirtualMethods(builder); + synthesizeVirtualMethods(builder, desugarInvoke); } final DexField getCaptureField(int index) { @@ -146,7 +150,8 @@ } // Synthesize virtual methods. - private void synthesizeVirtualMethods(SyntheticProgramClassBuilder builder) { + private void synthesizeVirtualMethods( + SyntheticProgramClassBuilder builder, DesugarInvoke desugarInvoke) { DexMethod mainMethod = appView.dexItemFactory().createMethod(type, descriptor.erasedProto, descriptor.name); @@ -159,7 +164,7 @@ .setAccessFlags( MethodAccessFlags.fromSharedAccessFlags( Constants.ACC_PUBLIC | Constants.ACC_FINAL, false)) - .setCode(LambdaMainMethodSourceCode.build(this, mainMethod)) + .setCode(LambdaMainMethodSourceCode.build(this, mainMethod, desugarInvoke)) // The api level is computed when tracing. .disableAndroidApiLevelCheck() .build()); @@ -261,6 +266,21 @@ } } + public static int getAsmOpcodeForInvokeType(MethodHandleType type) { + switch (type) { + case INVOKE_INTERFACE: + return Opcodes.INVOKEINTERFACE; + case INVOKE_STATIC: + return Opcodes.INVOKESTATIC; + case INVOKE_DIRECT: + return Opcodes.INVOKESPECIAL; + case INVOKE_INSTANCE: + return Opcodes.INVOKEVIRTUAL; + default: + throw new Unreachable("Unexpected method handle type: " + type); + } + } + // Creates a delegation target for this particular lambda class. Note that we // should always be able to create targets for the lambdas we support. private Target createTarget(ProgramMethod accessedFrom) { @@ -287,12 +307,22 @@ } private boolean doesNotNeedAccessor(ProgramMethod accessedFrom) { - return canAccessModifyLambdaImplMethod() || !descriptor.needsAccessor(accessedFrom); + return canAccessModifyLambdaImplMethod() + || isPrivateOrStaticInterfaceMethodInvokeThatWillBeDesugared() + || !descriptor.needsAccessor(accessedFrom); + } + + private boolean isPrivateOrStaticInterfaceMethodInvokeThatWillBeDesugared() { + return appView.options().isInterfaceMethodDesugaringEnabled() + && descriptor.implHandle.isInterface + && (descriptor.implHandle.type.isInvokeDirect() + || descriptor.implHandle.type.isInvokeStatic()); } private boolean canAccessModifyLambdaImplMethod() { MethodHandleType invokeType = descriptor.implHandle.type; return appView.options().canAccessModifyLambdaImplementationMethods(appView) + && !isPrivateOrStaticInterfaceMethodInvokeThatWillBeDesugared() && (invokeType.isInvokeDirect() || invokeType.isInvokeStatic()) && descriptor.delegatesToLambdaImplMethod(appView.dexItemFactory()) && !desugaring.isDirectTargetedLambdaImplementationMethod(descriptor.implHandle); @@ -328,7 +358,7 @@ assert implHandle.type.isInvokeDirect(); // If the lambda$ method is an instance-private method on an interface we convert it into a - // public static method as it will be placed on the companion class. + // public static method so it is accessible. if (appView.definitionFor(implMethod.holder).isInterface()) { DexProto implProto = implMethod.proto; DexType[] implParams = implProto.parameters.values; @@ -367,8 +397,13 @@ if (doesNotNeedAccessor(accessedFrom)) { return new NoAccessorMethodTarget( - descriptor.implHandle.asMethod(), Type.VIRTUAL, descriptor.implHandle.isInterface); + descriptor.implHandle.asMethod(), + descriptor.implHandle.type.isInvokeDirect() + ? Type.DIRECT + : descriptor.implHandle.type.isInvokeStatic() ? Type.STATIC : Type.VIRTUAL, + descriptor.implHandle.isInterface); } + // We need to generate an accessor method in `accessedFrom` class/interface // for accessing the original instance impl-method. Note that impl-method's // holder does not have to be the same as `accessedFrom`. @@ -523,7 +558,7 @@ } // Used for targeting methods referenced directly without creating accessors. - private static final class NoAccessorMethodTarget extends Target { + public static final class NoAccessorMethodTarget extends Target { NoAccessorMethodTarget(DexMethod method, Type invokeType, boolean isInterface) { super(method, invokeType, isInterface);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java index e0a9c07..acfee7b 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
@@ -25,13 +25,18 @@ import com.android.tools.r8.graph.DexProto; import com.android.tools.r8.graph.DexType; import com.android.tools.r8.ir.code.Invoke; +import com.android.tools.r8.ir.code.Invoke.Type; import com.android.tools.r8.ir.code.NumericType; import com.android.tools.r8.ir.code.ValueType; import com.android.tools.r8.ir.desugar.LambdaClass.InvalidLambdaImplTarget; +import com.android.tools.r8.ir.desugar.LambdaClass.NoAccessorMethodTarget; +import com.android.tools.r8.ir.desugar.lambda.LambdaInstructionDesugaring.DesugarInvoke; +import com.android.tools.r8.utils.IntBox; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.Lists; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.objectweb.asm.Opcodes; @@ -166,7 +171,8 @@ } } - public static CfCode build(LambdaClass lambda, DexMethod mainMethod) { + public static CfCode build( + LambdaClass lambda, DexMethod mainMethod, DesugarInvoke desugarInvoke) { DexItemFactory factory = lambda.appView.dexItemFactory(); LambdaClass.Target target = lambda.target; if (target instanceof InvalidLambdaImplTarget) { @@ -184,11 +190,13 @@ // Only constructor call should use direct invoke type since super // and private methods require accessor methods. - boolean constructorTarget = target.invokeType == Invoke.Type.DIRECT; - assert !constructorTarget || methodToCall.name == factory.constructorMethodName; + boolean constructorTarget = methodToCall.name == factory.constructorMethodName; + assert !constructorTarget || target.invokeType == Type.DIRECT; boolean targetWithReceiver = - target.invokeType == Invoke.Type.VIRTUAL || target.invokeType == Invoke.Type.INTERFACE; + target.invokeType == Invoke.Type.VIRTUAL + || target.invokeType == Invoke.Type.INTERFACE + || (target.invokeType == Type.DIRECT && !constructorTarget); List<DexType> implReceiverAndArgs = new ArrayList<>(); if (targetWithReceiver) { implReceiverAndArgs.add(methodToCall.holder); @@ -241,8 +249,24 @@ erasedParams[i], enforcedParams[i], expectedParamType, instructions, factory); } - instructions.add( - new CfInvoke(target.invokeType.getCfOpcode(), methodToCall, target.isInterface())); + CfInvoke invoke = + new CfInvoke(target.invokeType.getCfOpcode(), methodToCall, target.isInterface()); + if (target instanceof NoAccessorMethodTarget) { + IntBox locals = new IntBox(); + IntBox stack = new IntBox(); + Collection<CfInstruction> is = + desugarInvoke.desugarInvoke(invoke, locals::getAndIncrement, stack::getAndIncrement); + if (is != null) { + instructions.addAll(is); + maxLocals += locals.get(); + maxStack += stack.get(); + } else { + instructions.add(invoke); + } + } else { + instructions.add(invoke); + } + DexType methodToCallReturnType = methodToCall.getReturnType(); if (!methodToCallReturnType.isVoidType()) { maxStack =
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java index da0a96a..62b65d4 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
@@ -254,7 +254,8 @@ return true; } - private Collection<CfInstruction> desugarInstruction( + @Override + public Collection<CfInstruction> desugarInstruction( CfInstruction instruction, FreshLocalProvider freshLocalProvider, LocalStackAllocator localStackAllocator, @@ -273,6 +274,7 @@ eventConsumer, context, methodProcessingContext, + this, appView.dexItemFactory()); if (replacement != null) { assert desugaring.needsDesugaring(instruction, context); @@ -346,9 +348,9 @@ @Override public InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaringD8( - Flavor flavor) { + Flavor flavor, InterfaceProcessor interfaceProcessor) { return interfaceMethodRewriter != null - ? interfaceMethodRewriter.getPostProcessingDesugaringD8(flavor) + ? interfaceMethodRewriter.getPostProcessingDesugaringD8(flavor, interfaceProcessor) : null; }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java index 8ef2e18..1d55e7e 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java
@@ -13,6 +13,7 @@ import com.android.tools.r8.graph.DexType; import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LocalStackAllocator; @@ -46,6 +47,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (instruction.isConstDynamic()) { return desugarConstDynamicInstruction(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java index 4634977..2b6c9d4 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java
@@ -30,6 +30,7 @@ import com.android.tools.r8.ir.code.MemberType; import com.android.tools.r8.ir.code.ValueType; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LocalStackAllocator; @@ -97,6 +98,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (needsDesugaring(instruction, context)) { assert instruction.isInvoke();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java index 73d7f8f..5c6d6c1 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java
@@ -20,6 +20,7 @@ import com.android.tools.r8.graph.MethodResolutionResult; import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LocalStackAllocator; @@ -69,6 +70,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { InvokeRetargetingResult invokeRetargetingResult = computeNewInvokeTarget(instruction, context);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java index 28b6981..5c89290 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java
@@ -21,6 +21,7 @@ import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.code.ValueType; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.DesugarDescription; import com.android.tools.r8.ir.desugar.FreshLocalProvider; @@ -47,6 +48,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { return computeDesugarDescription(instruction) .desugarInstruction(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java index dfb797c..428bdd0 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java
@@ -15,6 +15,7 @@ import com.android.tools.r8.graph.DexProgramClass; import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LocalStackAllocator; @@ -73,6 +74,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (instruction.isInvokeSpecial()) { return desugarInvokeInstruction(instruction.asInvoke(), eventConsumer, context);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java index d32b3d3..e1462ea 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
@@ -65,7 +65,7 @@ * In other words, the traversal is in top-down (edges from type to its subtypes) topological order. * The traversal is lazy, starting from the unordered set of program classes. */ -final class ClassProcessor implements InterfaceDesugaringProcessor { +final class ClassProcessor { // Collection for method signatures that may cause forwarding methods to be created. private static class MethodSignatures { @@ -402,7 +402,6 @@ return !needsLibraryInfo; } - @Override public void process( DexProgramClass clazz, InterfaceProcessingDesugaringEventConsumer eventConsumer) { if (!clazz.isInterface()) { @@ -417,7 +416,6 @@ // We introduce forwarding methods only once all desugaring has been performed to avoid // confusing the look-up with inserted forwarding methods. - @Override public final void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) { newSyntheticMethods.forEach( (clazz, newForwardingMethods) -> {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringProcessor.java deleted file mode 100644 index 4f4ba32..0000000 --- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringProcessor.java +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.android.tools.r8.ir.desugar.itf; - -import com.android.tools.r8.graph.DexProgramClass; - -public interface InterfaceDesugaringProcessor { - - // The process phase can be performed before, concurrently or after code desugaring. It can be - // executed concurrently on all classes. Each processing may require to read other classes, - // so this phase cannot modify the classes themselves (for example insertion/removal of methods). - // The phase can insert new classes with new methods, such as emulated interface dispatch classes - // or companion classes with their methods. - void process(DexProgramClass clazz, InterfaceProcessingDesugaringEventConsumer eventConsumer); - - // The finalization phase is done at a join point, after all code desugaring have been performed. - // All finalization phases of all desugaring processors are performed sequentially. - // Complex computations should be avoided if possible here and be moved to the concurrent phase. - // Classes may be mutated here (new methods can be inserted, etc.). - void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer); -}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java index 94a4e60..41668bd 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
@@ -11,10 +11,8 @@ import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor; import com.android.tools.r8.utils.ThreadUtils; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.Collection; -import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.function.Predicate; @@ -23,14 +21,8 @@ private final AppView<?> appView; private final Flavor flavour; - private final List<InterfaceDesugaringProcessor> interfaceDesugaringProcessors; - - InterfaceMethodProcessorFacade( - AppView<?> appView, Flavor flavour, Predicate<ProgramMethod> isLiveMethod) { - this.appView = appView; - this.flavour = flavour; - interfaceDesugaringProcessors = instantiateInterfaceDesugaringProcessors(appView, isLiveMethod); - } + private final InterfaceProcessor interfaceProcessor; + private final ClassProcessor classProcessor; InterfaceMethodProcessorFacade( AppView<?> appView, @@ -39,25 +31,8 @@ InterfaceProcessor interfaceProcessor) { this.appView = appView; this.flavour = flavour; - interfaceDesugaringProcessors = - ImmutableList.of(new ClassProcessor(appView, isLiveMethod), interfaceProcessor); - } - - private List<InterfaceDesugaringProcessor> instantiateInterfaceDesugaringProcessors( - AppView<?> appView, Predicate<ProgramMethod> isLiveMethod) { - - // Process all classes first. Add missing forwarding methods to - // replace desugared default interface methods. - ClassProcessor classProcessor = new ClassProcessor(appView, isLiveMethod); - - // Process interfaces, create companion or dispatch class if needed, move static - // methods to companion class, copy default interface methods to companion classes, - // make original default methods abstract, remove bridge methods, create dispatch - // classes if needed. - InterfaceProcessor interfaceProcessor = new InterfaceProcessor(appView); - - // The processors can be listed in any order. - return ImmutableList.of(classProcessor, interfaceProcessor); + this.interfaceProcessor = interfaceProcessor; + this.classProcessor = new ClassProcessor(appView, isLiveMethod); } private boolean shouldProcess(DexProgramClass clazz, Flavor flavour) { @@ -72,17 +47,14 @@ InterfaceProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService) throws ExecutionException { + // TODO(b/183998768): Would be nice to use the ClassProcessing for the processing of classes, + // and do here only the finalization. ThreadUtils.processItems( Iterables.filter(programClasses, (DexProgramClass clazz) -> shouldProcess(clazz, flavour)), - clazz -> { - for (InterfaceDesugaringProcessor processor : interfaceDesugaringProcessors) { - processor.process(clazz, eventConsumer); - } - }, + clazz -> classProcessor.process(clazz, eventConsumer), executorService); - for (InterfaceDesugaringProcessor processor : interfaceDesugaringProcessors) { - processor.finalizeProcessing(eventConsumer); - } + classProcessor.finalizeProcessing(eventConsumer); + interfaceProcessor.finalizeProcessing(); } @Override @@ -91,8 +63,6 @@ CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService) throws ExecutionException { - // TODO(b/183998768): Would be nice to use the ClassProcessing for the processing of classes, - // and do here only the finalization. processClassesConcurrently(programClasses, eventConsumer, executorService); } }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java index 87e0d65..6ab7f62 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -30,6 +30,7 @@ import com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult; import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.DesugarDescription; import com.android.tools.r8.ir.desugar.FreshLocalProvider; @@ -248,6 +249,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { assert !isSyntheticMethodThatShouldNotBeDoubleProcessed(context); return computeDescription(instruction, context) @@ -907,8 +909,9 @@ return singleCandidate != null ? singleCandidate : method; } - public InterfaceMethodProcessorFacade getPostProcessingDesugaringD8(Flavor flavour) { - return new InterfaceMethodProcessorFacade(appView, flavour, m -> true); + public InterfaceMethodProcessorFacade getPostProcessingDesugaringD8( + Flavor flavour, InterfaceProcessor interfaceProcessor) { + return new InterfaceMethodProcessorFacade(appView, flavour, m -> true, interfaceProcessor); } public InterfaceMethodProcessorFacade getPostProcessingDesugaringR8(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java index 49d843d..8115626 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
@@ -9,11 +9,7 @@ import com.android.tools.r8.graph.DexType; import com.android.tools.r8.graph.ProgramMethod; -// TODO(b/183998768): Consider forcing the processing of interface methods in D8 akin to R8. -// That would avoid the need to reiterate the interface methods to collect info and this -// could avoid the "base" methods. -public interface InterfaceProcessingDesugaringEventConsumer - extends InterfaceMethodDesugaringBaseEventConsumer { +public interface InterfaceProcessingDesugaringEventConsumer { void acceptForwardingMethod(ProgramMethod method);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java index dd4a7a9..7513257 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java
@@ -51,7 +51,7 @@ // a companion class. Removes bridge default methods. // // Also moves static interface methods into a companion class. -public final class InterfaceProcessor implements InterfaceDesugaringProcessor { +public final class InterfaceProcessor { private final AppView<?> appView; private final InterfaceDesugaringSyntheticHelper helper; @@ -67,36 +67,23 @@ return helper; } - @Override - public void process( - DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) { - if (appView.enableWholeProgramOptimizations()) { - // R8 populates all info as part of enqueuing. - return; - } - if (!iface.isInterface()) { - return; - } - analyzeBridges(iface); - ensureCompanionClassMethods(iface, eventConsumer); - } - - private void analyzeBridges(DexProgramClass iface) { + public void processMethod( + ProgramMethod method, InterfaceMethodDesugaringBaseEventConsumer eventConsumer) { assert !appView.enableWholeProgramOptimizations(); - for (ProgramMethod method : iface.virtualProgramMethods()) { - if (!interfaceMethodRemovalChangesApi(method, iface)) { - getPostProcessingInterfaceInfo(iface).setHasBridgesToRemove(); - return; + if (!method.getHolder().isInterface()) { + return; + } + if (method.getDefinition().belongsToDirectPool()) { + processDirectInterfaceMethod(method, eventConsumer); + } else { + assert method.getDefinition().belongsToVirtualPool(); + processVirtualInterfaceMethod(method); + if (!interfaceMethodRemovalChangesApi(method)) { + getPostProcessingInterfaceInfo(method.getHolder()).setHasBridgesToRemove(); } } } - private void ensureCompanionClassMethods( - DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) { - processVirtualInterfaceMethods(iface); - processDirectInterfaceMethods(iface, eventConsumer); - } - static ProgramMethod ensureCompanionMethod( DexProgramClass iface, DexString methodName, @@ -124,29 +111,21 @@ newMethodCallback); } - private void processVirtualInterfaceMethods(DexProgramClass iface) { - assert !appView.enableWholeProgramOptimizations(); - for (ProgramMethod method : iface.virtualProgramMethods()) { - DexEncodedMethod virtual = method.getDefinition(); - if (helper.isCompatibleDefaultMethod(virtual)) { - // Create a new method in a companion class to represent default method implementation. - ProgramMethod companion = helper.ensureDefaultAsMethodOfProgramCompanionClassStub(method); - finalizeMoveToCompanionMethod(method, companion); - } + private void processVirtualInterfaceMethod(ProgramMethod method) { + if (helper.isCompatibleDefaultMethod(method.getDefinition())) { + // Create a new method in a companion class to represent default method implementation. + ProgramMethod companion = helper.ensureDefaultAsMethodOfProgramCompanionClassStub(method); + finalizeMoveToCompanionMethod(method, companion); } } - private void processDirectInterfaceMethods( - DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) { - assert !appView.enableWholeProgramOptimizations(); - for (ProgramMethod method : iface.directProgramMethods()) { - DexEncodedMethod definition = method.getDefinition(); - if (!definition.isClassInitializer()) { - getPostProcessingInterfaceInfo(iface).setHasNonClinitDirectMethods(); - ProgramMethod companion = - helper.ensureMethodOfProgramCompanionClassStub(method, eventConsumer); - finalizeMoveToCompanionMethod(method, companion); - } + private void processDirectInterfaceMethod( + ProgramMethod method, InterfaceMethodDesugaringBaseEventConsumer eventConsumer) { + if (!method.getDefinition().isClassInitializer()) { + getPostProcessingInterfaceInfo(method.getHolder()).setHasNonClinitDirectMethods(); + ProgramMethod companion = + helper.ensureMethodOfProgramCompanionClassStub(method, eventConsumer); + finalizeMoveToCompanionMethod(method, companion); } } @@ -238,8 +217,9 @@ // implementation to the companion class of [iface]. This is always the case for non-bridge // methods. Bridge methods that does not override an implementation in a super-interface must // also be kept (such a situation can happen if the vertical class merger merges two interfaces). - private boolean interfaceMethodRemovalChangesApi(ProgramMethod method, DexClass iface) { + private boolean interfaceMethodRemovalChangesApi(ProgramMethod method) { assert !appView.enableWholeProgramOptimizations(); + DexProgramClass iface = method.getHolder(); if (method.getAccessFlags().isBridge()) { if (appView.options().cfToCfDesugar) { // TODO(b/187176895): Find the compilation causing this to not be removed. @@ -309,7 +289,7 @@ List<DexEncodedMethod> newVirtualMethods = new ArrayList<>(); for (ProgramMethod method : iface.virtualProgramMethods()) { // Remove bridge methods. - if (interfaceMethodRemovalChangesApi(method, iface)) { + if (interfaceMethodRemovalChangesApi(method)) { newVirtualMethods.add(method.getDefinition()); } } @@ -325,8 +305,7 @@ } } - @Override - public void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) { + public void finalizeProcessing() { // TODO(b/196337368): Simplify this fix-up to be specific for the move of companion methods // rather than be based on a graph lens. InterfaceProcessorNestedGraphLens graphLens = postProcessInterfaces();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java index 71010c3..206c276 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
@@ -24,6 +24,7 @@ import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.code.ValueType; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LambdaClass; @@ -75,6 +76,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (instruction.isInvokeDynamic()) { return desugarInvokeDynamicInstruction( @@ -83,19 +85,36 @@ localStackAllocator, eventConsumer, context, - methodProcessingContext); + methodProcessingContext, + (invoke, localProvider, stackAllocator) -> + desugaringCollection.desugarInstruction( + invoke, + localProvider, + stackAllocator, + eventConsumer, + context, + methodProcessingContext)); } return null; } + public interface DesugarInvoke { + Collection<CfInstruction> desugarInvoke( + CfInvoke invoke, + FreshLocalProvider freshLocalProvider, + LocalStackAllocator localStackAllocator); + } + private Collection<CfInstruction> desugarInvokeDynamicInstruction( CfInvokeDynamic invoke, FreshLocalProvider freshLocalProvider, LocalStackAllocator localStackAllocator, LambdaDesugaringEventConsumer eventConsumer, ProgramMethod context, - MethodProcessingContext methodProcessingContext) { - LambdaClass lambdaClass = createLambdaClass(invoke, context, methodProcessingContext); + MethodProcessingContext methodProcessingContext, + DesugarInvoke desugarInvoke) { + LambdaClass lambdaClass = + createLambdaClass(invoke, context, methodProcessingContext, desugarInvoke); if (lambdaClass == null) { return null; } @@ -134,7 +153,8 @@ private LambdaClass createLambdaClass( CfInvokeDynamic invoke, ProgramMethod context, - MethodProcessingContext methodProcessingContext) { + MethodProcessingContext methodProcessingContext, + DesugarInvoke desugarInvoke) { LambdaDescriptor descriptor = LambdaDescriptor.tryInfer(invoke.getCallSite(), appView.appInfoForDesugaring(), context); if (descriptor == null) { @@ -149,7 +169,10 @@ SyntheticNaming.SyntheticKind.LAMBDA, methodProcessingContext.createUniqueContext(), appView, - builder -> box.set(new LambdaClass(builder, appView, this, context, descriptor))); + builder -> + box.set( + new LambdaClass( + builder, appView, this, context, descriptor, desugarInvoke))); // Immediately set the actual program class on the lambda. LambdaClass lambdaClass = box.get(); lambdaClass.setClass(clazz);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java index 87adb53..f9ca2e9 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
@@ -31,6 +31,7 @@ import com.android.tools.r8.graph.ProgramField; import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LocalStackAllocator; @@ -268,6 +269,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (instruction.isFieldInstruction()) { return desugarFieldInstruction(instruction.asFieldInstruction(), context, eventConsumer);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java index adab36a..ed388b8 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordCfMethods.java
@@ -123,7 +123,7 @@ new int[] {0, 1, 2}, new FrameType[] { FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")), - FrameType.initialized(options.itemFactory.stringType), + FrameType.initialized(options.itemFactory.classType), FrameType.initialized(options.itemFactory.stringType) }), new ArrayDeque<>(Arrays.asList())), @@ -144,7 +144,7 @@ new int[] {0, 1, 2}, new FrameType[] { FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")), - FrameType.initialized(options.itemFactory.stringType), + FrameType.initialized(options.itemFactory.classType), FrameType.initialized(options.itemFactory.stringType) }), new ArrayDeque<>( @@ -169,6 +169,13 @@ new CfInvoke( 182, options.itemFactory.createMethod( + options.itemFactory.classType, + options.itemFactory.createProto(options.itemFactory.stringType), + options.itemFactory.createString("getSimpleName")), + false), + new CfInvoke( + 182, + options.itemFactory.createMethod( options.itemFactory.stringBuilderType, options.itemFactory.createProto( options.itemFactory.stringBuilderType, options.itemFactory.stringType), @@ -193,7 +200,7 @@ new int[] {0, 1, 2, 3, 4, 5}, new FrameType[] { FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")), - FrameType.initialized(options.itemFactory.stringType), + FrameType.initialized(options.itemFactory.classType), FrameType.initialized(options.itemFactory.stringType), FrameType.initialized(options.itemFactory.createType("[Ljava/lang/String;")), FrameType.initialized(options.itemFactory.stringBuilderType), @@ -263,7 +270,7 @@ new int[] {0, 1, 2, 3, 4, 5}, new FrameType[] { FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")), - FrameType.initialized(options.itemFactory.stringType), + FrameType.initialized(options.itemFactory.classType), FrameType.initialized(options.itemFactory.stringType), FrameType.initialized(options.itemFactory.createType("[Ljava/lang/String;")), FrameType.initialized(options.itemFactory.stringBuilderType), @@ -278,7 +285,7 @@ new int[] {0, 1, 2, 3, 4}, new FrameType[] { FrameType.initialized(options.itemFactory.createType("[Ljava/lang/Object;")), - FrameType.initialized(options.itemFactory.stringType), + FrameType.initialized(options.itemFactory.classType), FrameType.initialized(options.itemFactory.stringType), FrameType.initialized(options.itemFactory.createType("[Ljava/lang/String;")), FrameType.initialized(options.itemFactory.stringBuilderType)
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java index 1f16c1b..f508ca6 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java
@@ -7,6 +7,7 @@ import static com.android.tools.r8.cf.code.CfStackInstruction.Opcode.Dup; import static com.android.tools.r8.cf.code.CfStackInstruction.Opcode.Swap; +import com.android.tools.r8.cf.code.CfConstClass; import com.android.tools.r8.cf.code.CfConstString; import com.android.tools.r8.cf.code.CfFieldInstruction; import com.android.tools.r8.cf.code.CfInstruction; @@ -39,6 +40,7 @@ import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaring; import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaring; import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer; @@ -50,7 +52,6 @@ import com.android.tools.r8.ir.synthetic.RecordCfCodeProvider.RecordEqualsCfCodeProvider; import com.android.tools.r8.ir.synthetic.RecordCfCodeProvider.RecordGetFieldsAsObjectsCfCodeProvider; import com.android.tools.r8.ir.synthetic.SyntheticCfCodeProvider; -import com.android.tools.r8.naming.dexitembasedstring.ClassNameComputationInfo; import com.android.tools.r8.synthesis.SyntheticNaming; import com.android.tools.r8.utils.InternalOptions; import com.google.common.collect.ImmutableList; @@ -89,7 +90,7 @@ factory = appView.dexItemFactory(); recordToStringHelperProto = factory.createProto( - factory.stringType, factory.objectArrayType, factory.stringType, factory.stringType); + factory.stringType, factory.objectArrayType, factory.classType, factory.stringType); recordHashCodeHelperProto = factory.createProto(factory.intType, factory.classType, factory.objectArrayType); } @@ -167,6 +168,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { assert !instruction.isInitClass(); if (!needsDesugaring(instruction, context)) { @@ -252,7 +254,6 @@ return desugarInvokeRecordToString( recordInvokeDynamic, localStackAllocator, - context, eventConsumer, methodProcessingContext); } @@ -382,21 +383,15 @@ private List<CfInstruction> desugarInvokeRecordToString( RecordInvokeDynamic recordInvokeDynamic, LocalStackAllocator localStackAllocator, - ProgramMethod context, RecordInstructionDesugaringEventConsumer eventConsumer, MethodProcessingContext methodProcessingContext) { - DexString simpleName = - ClassNameComputationInfo.ClassNameMapping.SIMPLE_NAME.map( - recordInvokeDynamic.getRecordClass().type.toDescriptorString(), - context.getHolder(), - factory); localStackAllocator.allocateLocalStack(2); DexMethod getFieldsAsObjects = getFieldsAsObjectsMethod(recordInvokeDynamic.getRecordClass().type); assert recordInvokeDynamic.getRecordClass().lookupProgramMethod(getFieldsAsObjects) != null; ArrayList<CfInstruction> instructions = new ArrayList<>(); instructions.add(new CfInvoke(Opcodes.INVOKESPECIAL, getFieldsAsObjects, false)); - instructions.add(new CfConstString(simpleName)); + instructions.add(new CfConstClass(recordInvokeDynamic.getRecordClass().type)); instructions.add(new CfConstString(recordInvokeDynamic.getFieldNames())); ProgramMethod programMethod = synthesizeRecordHelper(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java index 607b088..065fc4c 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java
@@ -29,6 +29,7 @@ import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.code.ValueType; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LocalStackAllocator; @@ -76,6 +77,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (instruction.isInvokeDynamic()) { // We are interested in bootstrap methods StringConcatFactory::makeConcat
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java index ee71bc0..716b6e2 100644 --- a/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java +++ b/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java
@@ -21,6 +21,7 @@ import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.ir.code.ValueType; import com.android.tools.r8.ir.desugar.CfInstructionDesugaring; +import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection; import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer; import com.android.tools.r8.ir.desugar.FreshLocalProvider; import com.android.tools.r8.ir.desugar.LocalStackAllocator; @@ -57,6 +58,7 @@ CfInstructionDesugaringEventConsumer eventConsumer, ProgramMethod context, MethodProcessingContext methodProcessingContext, + CfInstructionDesugaringCollection desugaringCollection, DexItemFactory dexItemFactory) { if (!instruction.isInvoke()) { return null;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java index 7bf0e38..d36206d 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -1095,8 +1095,7 @@ if (inlineeMayHaveInvokeMethod && options.applyInliningToInlinee) { if (inlineeStack.size() + 1 > options.applyInliningToInlineeMaxDepth - && appView.appInfo().hasNoAlwaysInlineMethods() - && appView.appInfo().hasNoForceInlineMethods()) { + && appView.appInfo().hasNoAlwaysInlineMethods()) { continue; } // Record that we will be inside the inlinee until the next block.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java index 9608eed..9e8d052 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -17,11 +17,13 @@ import com.android.tools.r8.graph.FieldResolutionResult.SuccessfulFieldResolutionResult; import com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult; import com.android.tools.r8.graph.ProgramMethod; +import com.android.tools.r8.ir.analysis.type.ClassTypeElement; import com.android.tools.r8.ir.analysis.type.TypeAnalysis; import com.android.tools.r8.ir.analysis.type.TypeElement; import com.android.tools.r8.ir.analysis.value.AbstractValue; import com.android.tools.r8.ir.analysis.value.SingleValue; import com.android.tools.r8.ir.analysis.value.UnknownValue; +import com.android.tools.r8.ir.code.ArrayGet; import com.android.tools.r8.ir.code.BasicBlock; import com.android.tools.r8.ir.code.FieldInstruction; import com.android.tools.r8.ir.code.IRCode; @@ -63,6 +65,63 @@ this.reporter = appView.options().reporter; } + private void rewriteArrayGet( + IRCode code, + ProgramMethod context, + Set<Value> affectedValues, + ListIterator<BasicBlock> blocks, + InstructionListIterator iterator, + ArrayGet arrayGet) { + TypeElement arrayType = arrayGet.array().getType(); + if (!arrayType.isArrayType()) { + // Does not type check. + return; + } + + TypeElement memberType = arrayType.asArrayType().getMemberType(); + if (!memberType.isClassType()) { + // We don't know what the value of the element is. + return; + } + + boolean isAlwaysNull = false; + ClassTypeElement memberClassType = memberType.asClassType(); + if (memberClassType.getClassType().isAlwaysNull(appView)) { + isAlwaysNull = true; + } else if (memberClassType.getInterfaces().hasSingleKnownInterface()) { + isAlwaysNull = + memberClassType.getInterfaces().getSingleKnownInterface().isAlwaysNull(appView); + } + + if (!isAlwaysNull) { + // We don't know what the value of the element is. + return; + } + + BasicBlock block = arrayGet.getBlock(); + Position position = arrayGet.getPosition(); + + // All usages are replaced by the replacement value. + Instruction replacement = + appView + .abstractValueFactory() + .createNullValue() + .createMaterializingInstruction(appView, code, arrayGet); + affectedValues.addAll(arrayGet.outValue().affectedValues()); + arrayGet.outValue().replaceUsers(replacement.outValue()); + + // Insert the definition of the replacement. + replacement.setPosition(position); + if (block.hasCatchHandlers()) { + iterator + .splitCopyCatchHandlers(code, blocks, appView.options()) + .listIterator(code) + .add(replacement); + } else { + iterator.add(replacement); + } + } + private boolean mayPropagateValueFor(DexClassAndField field) { if (field.isProgramField()) { return appView.appInfo().mayPropagateValueFor(field.getReference()); @@ -472,7 +531,10 @@ InstructionListIterator iterator = block.listIterator(code); while (iterator.hasNext()) { Instruction current = iterator.next(); - if (current.isInvokeMethod()) { + if (current.isArrayGet()) { + rewriteArrayGet( + code, context, affectedValues, blockIterator, iterator, current.asArrayGet()); + } else if (current.isInvokeMethod()) { rewriteInvokeMethodWithConstantValues( code, context, affectedValues, blockIterator, iterator, current.asInvokeMethod()); } else if (current.isFieldGet()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MethodPoolCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/MethodPoolCollection.java index 652c185..2b439a6 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/MethodPoolCollection.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/MethodPoolCollection.java
@@ -34,6 +34,10 @@ private final Predicate<DexEncodedMethod> methodTester; + public MethodPoolCollection(AppView<AppInfoWithLiveness> appView) { + this(appView, appView.appInfo().computeSubtypingInfo()); + } + public MethodPoolCollection(AppView<AppInfoWithLiveness> appView, SubtypingInfo subtypingInfo) { this(appView, subtypingInfo, Predicates.alwaysTrue()); }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java deleted file mode 100644 index 052e196..0000000 --- a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java +++ /dev/null
@@ -1,333 +0,0 @@ -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.android.tools.r8.ir.optimize; - -import com.android.tools.r8.graph.AppView; -import com.android.tools.r8.graph.ArgumentUse; -import com.android.tools.r8.graph.DexEncodedMethod; -import com.android.tools.r8.graph.DexMethod; -import com.android.tools.r8.graph.DexProgramClass; -import com.android.tools.r8.graph.DexProto; -import com.android.tools.r8.graph.DexString; -import com.android.tools.r8.graph.DexType; -import com.android.tools.r8.graph.NestedGraphLens; -import com.android.tools.r8.graph.RewrittenPrototypeDescription; -import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection; -import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo; -import com.android.tools.r8.ir.optimize.MemberPoolCollection.MemberPool; -import com.android.tools.r8.shaking.AppInfoWithLiveness; -import com.android.tools.r8.utils.MethodSignatureEquivalence; -import com.android.tools.r8.utils.SymbolGenerationUtils; -import com.android.tools.r8.utils.SymbolGenerationUtils.MixedCasing; -import com.android.tools.r8.utils.ThreadUtils; -import com.android.tools.r8.utils.Timing; -import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap; -import com.android.tools.r8.utils.collections.BidirectionalOneToOneMap; -import com.android.tools.r8.utils.collections.MutableBidirectionalOneToOneMap; -import com.google.common.base.Equivalence.Wrapper; -import com.google.common.collect.Streams; -import java.util.BitSet; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.stream.Collectors; - -public class UnusedArgumentsCollector { - - private static final MethodSignatureEquivalence equivalence = MethodSignatureEquivalence.get(); - - private final AppView<AppInfoWithLiveness> appView; - private final MethodPoolCollection methodPoolCollection; - - private final MutableBidirectionalOneToOneMap<DexMethod, DexMethod> methodMapping = - new BidirectionalOneToOneHashMap<>(); - private final Map<DexMethod, ArgumentInfoCollection> removedArguments = new IdentityHashMap<>(); - - public static class UnusedArgumentsGraphLens extends NestedGraphLens { - - private final Map<DexMethod, ArgumentInfoCollection> removedArguments; - - UnusedArgumentsGraphLens( - AppView<?> appView, - BidirectionalOneToOneMap<DexMethod, DexMethod> methodMap, - Map<DexMethod, ArgumentInfoCollection> removedArguments) { - super(appView, EMPTY_FIELD_MAP, methodMap, EMPTY_TYPE_MAP); - this.removedArguments = removedArguments; - } - - @Override - protected RewrittenPrototypeDescription internalDescribePrototypeChanges( - RewrittenPrototypeDescription prototypeChanges, DexMethod method) { - return prototypeChanges.withRemovedArguments( - removedArguments.getOrDefault(method, ArgumentInfoCollection.empty())); - } - } - - public UnusedArgumentsCollector( - AppView<AppInfoWithLiveness> appView, MethodPoolCollection methodPoolCollection) { - this.appView = appView; - this.methodPoolCollection = methodPoolCollection; - } - - public UnusedArgumentsGraphLens run(ExecutorService executorService, Timing timing) - throws ExecutionException { - ThreadUtils.awaitFutures( - Streams.stream(appView.appInfo().classes()) - .map(this::runnableForClass) - .map(executorService::submit) - // Materialize list such that all runnables are submitted to the executor service - // before calling awaitFutures(). - .collect(Collectors.toList())); - - // Build method pool collection to enable unused argument removal for virtual methods. - methodPoolCollection.buildAll(executorService, timing); - - // Visit classes in deterministic order to ensure deterministic output. - appView.appInfo().classesWithDeterministicOrder().forEach(this::processVirtualMethods); - - if (!methodMapping.isEmpty()) { - return new UnusedArgumentsGraphLens(appView, methodMapping, removedArguments); - } - - return null; - } - - private class UsedSignatures { - - private final MethodSignatureEquivalence equivalence = MethodSignatureEquivalence.get(); - private final Set<Wrapper<DexMethod>> usedSignatures = new HashSet<>(); - - private boolean isMethodSignatureAvailable(DexMethod method) { - return !usedSignatures.contains(equivalence.wrap(method)); - } - - private void markSignatureAsUsed(DexMethod method) { - usedSignatures.add(equivalence.wrap(method)); - } - - DexMethod getNewSignature(DexEncodedMethod method, DexProto newProto) { - DexMethod newSignature; - int count = 0; - DexString newName = null; - do { - if (newName == null) { - newName = method.getReference().name; - } else if (!appView.dexItemFactory().isConstructor(method.getReference())) { - newName = - appView - .dexItemFactory() - .createString( - SymbolGenerationUtils.numberToIdentifier( - count, - MixedCasing.USE_MIXED_CASE, - method.getReference().name.toSourceString().toCharArray())); - } else { - // Constructors must be named `<init>`. - return null; - } - newSignature = - appView.dexItemFactory().createMethod(method.getHolderType(), newProto, newName); - count++; - } while (!isMethodSignatureAvailable(newSignature)); - return newSignature; - } - - DexEncodedMethod removeArguments( - DexEncodedMethod method, DexMethod newSignature, ArgumentInfoCollection unused) { - boolean removed = usedSignatures.remove(equivalence.wrap(method.getReference())); - assert removed; - - markSignatureAsUsed(newSignature); - - return method.toTypeSubstitutedMethod( - newSignature, unused.createParameterAnnotationsRemover(method)); - } - } - - private class GloballyUsedSignatures { - - private final MemberPool<DexMethod> methodPool; - - GloballyUsedSignatures(MemberPool<DexMethod> methodPool) { - this.methodPool = methodPool; - } - - DexMethod getNewSignature(DexEncodedMethod method, DexProto newProto) { - DexMethod newSignature; - int count = 0; - DexString newName = null; - do { - if (newName == null) { - newName = method.getReference().name; - } else if (!appView.dexItemFactory().isConstructor(method.getReference())) { - newName = - appView - .dexItemFactory() - .createString(method.getReference().name.toSourceString() + count); - } else { - // Constructors must be named `<init>`. - return null; - } - newSignature = - appView.dexItemFactory().createMethod(method.getHolderType(), newProto, newName); - count++; - } while (methodPool.hasSeen(equivalence.wrap(newSignature))); - return newSignature; - } - - DexEncodedMethod removeArguments( - DexEncodedMethod method, DexMethod newSignature, ArgumentInfoCollection unused) { - methodPool.seen(equivalence.wrap(newSignature)); - return method.toTypeSubstitutedMethod( - newSignature, unused.createParameterAnnotationsRemover(method)); - } - } - - private Runnable runnableForClass(DexProgramClass clazz) { - return () -> this.processDirectMethods(clazz); - } - - private void processDirectMethods(DexProgramClass clazz) { - UsedSignatures signatures = new UsedSignatures(); - for (DexEncodedMethod method : clazz.methods()) { - signatures.markSignatureAsUsed(method.getReference()); - } - - clazz - .getMethodCollection() - .replaceDirectMethods( - method -> { - - // If this is a method with known resolution issues, then don't remove any unused - // arguments. - if (appView.appInfo().isFailedResolutionTarget(method.getReference())) { - return method; - } - - ArgumentInfoCollection unused = collectUnusedArguments(method); - if (unused != null && unused.hasRemovedArguments()) { - DexProto newProto = createProtoWithRemovedArguments(method, unused); - DexMethod newSignature = signatures.getNewSignature(method, newProto); - if (newSignature == null) { - assert appView.dexItemFactory().isConstructor(method.getReference()); - return method; - } - DexEncodedMethod newMethod = - signatures.removeArguments(method, newSignature, unused); - synchronized (this) { - methodMapping.put(method.getReference(), newMethod.getReference()); - removedArguments.put(newMethod.getReference(), unused); - } - return newMethod; - } - return method; - }); - } - - private void processVirtualMethods(DexProgramClass clazz) { - MemberPool<DexMethod> methodPool = methodPoolCollection.get(clazz); - GloballyUsedSignatures signatures = new GloballyUsedSignatures(methodPool); - - clazz - .getMethodCollection() - .replaceVirtualMethods( - method -> { - ArgumentInfoCollection unused = collectUnusedArguments(method, methodPool); - if (unused != null && unused.hasRemovedArguments()) { - DexProto newProto = createProtoWithRemovedArguments(method, unused); - DexMethod newSignature = signatures.getNewSignature(method, newProto); - - // Double-check that the new method signature is in fact available. - assert !methodPool.hasSeenStrictlyAbove(equivalence.wrap(newSignature)); - assert !methodPool.hasSeenStrictlyBelow(equivalence.wrap(newSignature)); - - DexEncodedMethod newMethod = - signatures.removeArguments( - method, signatures.getNewSignature(method, newProto), unused); - - methodMapping.put(method.getReference(), newMethod.getReference()); - removedArguments.put(newMethod.getReference(), unused); - return newMethod; - } - return method; - }); - } - - private ArgumentInfoCollection collectUnusedArguments(DexEncodedMethod method) { - return collectUnusedArguments(method, null); - } - - private ArgumentInfoCollection collectUnusedArguments( - DexEncodedMethod method, MemberPool<DexMethod> methodPool) { - if (ArgumentRemovalUtils.isPinned(method, appView) - || appView.appInfo().isKeepUnusedArgumentsMethod(method.getReference())) { - return null; - } - // Only process classfile code objects. - if (method.getCode() == null || !method.getCode().isCfCode()) { - return null; - } - if (method.isNonPrivateVirtualMethod()) { - // Abort if the method overrides another method, or if the method is overridden. In both cases - // an unused argument cannot be removed unless it is unused in all of the related methods in - // the hierarchy. - assert methodPool != null; - Wrapper<DexMethod> wrapper = equivalence.wrap(method.getReference()); - if (methodPool.hasSeenStrictlyAbove(wrapper) || methodPool.hasSeenStrictlyBelow(wrapper)) { - return null; - } - } - int offset = method.getFirstNonReceiverArgumentIndex(); - int argumentCount = method.getReference().proto.parameters.size() + offset; - CollectUsedArguments collector = new CollectUsedArguments(); - if (!method.accessFlags.isStatic()) { - // TODO(65810338): The receiver cannot be removed without transforming the method to being - // static. - collector.register(0); - } - method.getCode().registerArgumentReferences(method, collector); - BitSet used = collector.getUsedArguments(); - if (used.cardinality() < argumentCount) { - ArgumentInfoCollection.Builder argInfosBuilder = ArgumentInfoCollection.builder(); - for (int argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) { - if (!used.get(argumentIndex)) { - RemovedArgumentInfo removedArg = - RemovedArgumentInfo.builder() - .setType(method.getReference().proto.parameters.values[argumentIndex - offset]) - .build(); - argInfosBuilder.addArgumentInfo(argumentIndex, removedArg); - } - } - return argInfosBuilder.build(); - } - return null; - } - - private DexProto createProtoWithRemovedArguments( - DexEncodedMethod encodedMethod, ArgumentInfoCollection unused) { - DexType[] parameters = unused.rewriteParameters(encodedMethod); - return appView - .dexItemFactory() - .createProto(encodedMethod.getReference().proto.returnType, parameters); - } - - private static class CollectUsedArguments extends ArgumentUse { - - private final BitSet used = new BitSet(); - - BitSet getUsedArguments() { - return used; - } - - @Override - public boolean register(int argument) { - used.set(argument); - return true; - } - } -}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java index 65f0d3f..1f4064f 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -316,10 +316,9 @@ return user; // Not eligible. } - if (AccessControl.isClassAccessible(singleProgramTarget.getHolder(), method, appView) - .isPossiblyFalse()) { - return user; // Not eligible. - } + // The target access is checked in isEligibleSingleTarget above. + assert AccessControl.isClassAccessible(singleProgramTarget.getHolder(), method, appView) + .isTrue(); // Eligible constructor call (for new instance roots only). if (user.isInvokeConstructor(dexItemFactory)) { @@ -1215,6 +1214,10 @@ if (methodProcessor.isProcessedConcurrently(singleTarget)) { return false; } + if (AccessControl.isMemberAccessible(singleTarget, singleTarget.getHolder(), method, appView) + .isPossiblyFalse()) { + return false; + } if (!singleTarget .getDefinition() .isInliningCandidate(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EmptyEnumUnboxer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EmptyEnumUnboxer.java index 2fb3b5a..9320e54 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EmptyEnumUnboxer.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EmptyEnumUnboxer.java
@@ -16,7 +16,7 @@ import com.android.tools.r8.ir.conversion.PostMethodProcessor.Builder; import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackDelayed; import com.android.tools.r8.shaking.AppInfoWithLiveness; -import java.util.Collections; +import com.google.common.collect.Sets; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -47,8 +47,7 @@ @Override public Set<Phi> rewriteCode(IRCode code, MethodProcessor methodProcessor) { - // Intentionally empty. - return Collections.emptySet(); + return Sets.newIdentityHashSet(); } @Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java index 8a97aef..d2a73ed 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java
@@ -20,6 +20,7 @@ import com.android.tools.r8.graph.DexType; import com.android.tools.r8.graph.DexValue; import com.android.tools.r8.graph.FieldResolutionResult.SuccessfulFieldResolutionResult; +import com.android.tools.r8.graph.GraphLens.MethodLookupResult; import com.android.tools.r8.graph.MethodAccessFlags; import com.android.tools.r8.graph.ProgramField; import com.android.tools.r8.graph.ProgramMethod; @@ -56,13 +57,14 @@ import com.android.tools.r8.utils.collections.ProgramMethodMap; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import com.google.common.collect.Sets; import java.util.ArrayList; import java.util.Collection; +import java.util.IdentityHashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -241,13 +243,22 @@ // Rewrite enum instantiations + remove static-puts to pruned fields. IRCode code = classInitializer.buildIR(appView); ListIterator<BasicBlock> blockIterator = code.listIterator(); - Set<Instruction> instructionsToRemove = Sets.newIdentityHashSet(); + + // A mapping from instructions-to-be-removed from the IR to their lens-rewritten + // instruction (if any). If an instruction-to-be-removed has a lens-rewritten instruction, the + // lens-rewritten instruction must also be detached from the IR. + Map<Instruction, Optional<Instruction>> instructionsToRemove = new IdentityHashMap<>(); while (blockIterator.hasNext()) { BasicBlock block = blockIterator.next(); InstructionListIterator instructionIterator = block.listIterator(code); while (instructionIterator.hasNext()) { Instruction instruction = instructionIterator.next(); - if (instructionsToRemove.remove(instruction)) { + if (instructionsToRemove.containsKey(instruction)) { + Optional<Instruction> rewrittenInstruction = instructionsToRemove.remove(instruction); + if (rewrittenInstruction.isPresent()) { + instructionIterator.replaceCurrentInstruction(rewrittenInstruction.get()); + instructionIterator.previous(); + } instructionIterator.removeOrReplaceByDebugLocalRead(); continue; } @@ -294,8 +305,47 @@ newInstance.getUniqueConstructorInvoke(appView.dexItemFactory()); assert constructorInvoke != null; + DexMethod invokedMethod = constructorInvoke.getInvokedMethod(); + + // Rewrite the constructor invoke in case there are any removed arguments. This is + // required since we find the argument index of the ordinal value below, and use this to + // find the ordinal of the current enum instance. + MethodLookupResult lookupResult = + appView.graphLens().lookupInvokeDirect(invokedMethod, classInitializer); + if (lookupResult.getReference() != invokedMethod) { + List<Value> rewrittenArguments = + new ArrayList<>(constructorInvoke.arguments().size()); + for (int i = 0; i < constructorInvoke.arguments().size(); i++) { + Value argument = constructorInvoke.getArgument(i); + if (!lookupResult + .getPrototypeChanges() + .getArgumentInfoCollection() + .isArgumentRemoved(i)) { + rewrittenArguments.add(argument); + } + } + InvokeDirect originalConstructorInvoke = constructorInvoke; + constructorInvoke = + InvokeDirect.builder() + .setArguments(rewrittenArguments) + .setMethod(lookupResult.getReference()) + .build(); + + // Record that the original constructor invoke has been rewritten into the new + // constructor invoke, and that these instructions need to be removed from the IR. + // Note that although the rewritten constructor invoke has not been inserted into the + // IR, the creation of it has added it as a user of each of the operands. To undo this + // we replace the original constructor invoke by the rewritten constructor invoke and + // then remove the rewritten constructor invoke from the IR. + instructionsToRemove.put(originalConstructorInvoke, Optional.of(constructorInvoke)); + } else { + assert lookupResult.getPrototypeChanges().isEmpty(); + // Record that the constructor invoke needs to be removed. + instructionsToRemove.put(constructorInvoke, Optional.empty()); + } + ProgramMethod constructor = - unboxedEnum.lookupProgramMethod(constructorInvoke.getInvokedMethod()); + unboxedEnum.lookupProgramMethod(lookupResult.getReference()); assert constructor != null; InstanceFieldInitializationInfo ordinalInitializationInfo = @@ -334,8 +384,6 @@ code.createValue( ClassTypeElement.create( unboxedEnum.getType(), definitelyNotNull(), appView)))); - - instructionsToRemove.add(constructorInvoke); } } else if (instruction.isStaticPut()) { StaticPut staticPut = instruction.asStaticPut(); @@ -358,7 +406,13 @@ if (!instructionsToRemove.isEmpty()) { InstructionListIterator instructionIterator = code.instructionListIterator(); while (instructionIterator.hasNext()) { - if (instructionsToRemove.remove(instructionIterator.next())) { + Instruction instruction = instructionIterator.next(); + if (instructionsToRemove.containsKey(instruction)) { + Optional<Instruction> rewrittenInstruction = instructionsToRemove.get(instruction); + if (rewrittenInstruction.isPresent()) { + instructionIterator.replaceCurrentInstruction(rewrittenInstruction.get()); + instructionIterator.previous(); + } instructionIterator.removeOrReplaceByDebugLocalRead(); } }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java index e6b5afe..c6b0aa4 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java
@@ -34,9 +34,7 @@ InvokeMethod invoke, ProgramMethod target, ProgramMethod context) { DexEncodedMethod targetMethod = target.getDefinition(); DexMethod targetReference = target.getReference(); - if (targetMethod.getOptimizationInfo().forceInline() - || (appView.appInfo().hasLiveness() - && appView.withLiveness().appInfo().isForceInlineMethod(targetReference))) { + if (targetMethod.getOptimizationInfo().forceInline()) { assert !appView.appInfo().isNeverInlineMethod(targetReference); return Reason.FORCE; }
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java b/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java index 7a0a20c..00028ff 100644 --- a/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java +++ b/src/main/java/com/android/tools/r8/naming/ClassNamingForNameMapper.java
@@ -8,8 +8,10 @@ import com.android.tools.r8.naming.MemberNaming.Signature; import com.android.tools.r8.naming.MemberNaming.Signature.SignatureKind; import com.android.tools.r8.naming.mappinginformation.MappingInformation; +import com.android.tools.r8.naming.mappinginformation.RewriteFrameMappingInformation; import com.android.tools.r8.utils.ChainableStringConsumer; import com.android.tools.r8.utils.ThrowingConsumer; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import java.util.ArrayList; @@ -453,6 +455,16 @@ return false; } + public List<RewriteFrameMappingInformation> getRewriteFrameMappingInformation() { + ImmutableList.Builder<RewriteFrameMappingInformation> builder = ImmutableList.builder(); + for (MappingInformation mappingInformation : additionalMappingInfo) { + if (mappingInformation.isRewriteFrameMappingInformation()) { + builder.add(mappingInformation.asRewriteFrameMappingInformation()); + } + } + return builder.build(); + } + public int getOriginalLineNumber(int lineNumberAfterMinification) { if (minifiedRange == null) { // General mapping without concrete line numbers: "a() -> b"
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java index 13bcfe9..9232500 100644 --- a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java +++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java
@@ -30,6 +30,10 @@ return false; } + public boolean isRewriteFrameMappingInformation() { + return false; + } + public boolean isCompilerSynthesizedMappingInformation() { return false; } @@ -50,6 +54,10 @@ return null; } + public RewriteFrameMappingInformation asRewriteFrameMappingInformation() { + return null; + } + public abstract boolean allowOther(MappingInformation information); public static void fromJsonObject( @@ -102,6 +110,9 @@ case CompilerSynthesizedMappingInformation.ID: CompilerSynthesizedMappingInformation.deserialize(version, onMappingInfo); return; + case RewriteFrameMappingInformation.ID: + RewriteFrameMappingInformation.deserialize(version, object, onMappingInfo); + return; default: diagnosticsHandler.info(MappingInformationDiagnostics.noHandlerFor(lineNumber, id)); UnknownJsonMappingInformation.deserialize(id, object, onMappingInfo);
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/RewriteFrameMappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/RewriteFrameMappingInformation.java new file mode 100644 index 0000000..8dccf93 --- /dev/null +++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/RewriteFrameMappingInformation.java
@@ -0,0 +1,262 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.naming.mappinginformation; + +import com.android.tools.r8.errors.CompilationError; +import com.android.tools.r8.errors.Unimplemented; +import com.android.tools.r8.naming.MapVersion; +import com.android.tools.r8.retrace.internal.RetraceStackTraceContextImpl; +import com.android.tools.r8.retrace.internal.RetraceStackTraceCurrentEvaluationInformation; +import com.android.tools.r8.utils.DescriptorUtils; +import com.google.common.collect.ImmutableList; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.util.List; +import java.util.function.Consumer; + +public class RewriteFrameMappingInformation extends MappingInformation { + + public static final MapVersion SUPPORTED_VERSION = MapVersion.MAP_VERSION_EXPERIMENTAL; + public static final String ID = "com.android.tools.r8.rewriteFrame"; + private static final String CONDITIONS_KEY = "conditions"; + private static final String ACTIONS_KEY = "actions"; + + private final List<Condition> conditions; + private final List<RewriteAction> actions; + + private RewriteFrameMappingInformation(List<Condition> conditions, List<RewriteAction> actions) { + this.conditions = conditions; + this.actions = actions; + } + + public List<Condition> getConditions() { + return conditions; + } + + public List<RewriteAction> getActions() { + return actions; + } + + @Override + public String getId() { + return ID; + } + + @Override + public String serialize() { + JsonObject object = new JsonObject(); + object.add(MAPPING_ID_KEY, new JsonPrimitive(ID)); + JsonArray conditionsArray = new JsonArray(); + conditions.forEach(condition -> conditionsArray.add(condition.serialize())); + object.add(CONDITIONS_KEY, conditionsArray); + JsonArray actionsArray = new JsonArray(); + actions.forEach(action -> actionsArray.add(action.serialize())); + object.add(ACTIONS_KEY, actionsArray); + return object.toString(); + } + + public static boolean isSupported(MapVersion version) { + return version.isGreaterThanOrEqualTo(SUPPORTED_VERSION); + } + + @Override + public boolean allowOther(MappingInformation information) { + return !information.isRewriteFrameMappingInformation(); + } + + public static void deserialize( + MapVersion mapVersion, JsonObject object, Consumer<MappingInformation> onMappingInfo) { + if (!isSupported(mapVersion)) { + return; + } + ImmutableList.Builder<Condition> conditions = ImmutableList.builder(); + object + .get(CONDITIONS_KEY) + .getAsJsonArray() + .forEach( + element -> { + conditions.add(Condition.deserialize(element)); + }); + ImmutableList.Builder<RewriteAction> actions = ImmutableList.builder(); + object + .get(ACTIONS_KEY) + .getAsJsonArray() + .forEach(element -> actions.add(RewriteAction.deserialize(element))); + onMappingInfo.accept(new RewriteFrameMappingInformation(conditions.build(), actions.build())); + } + + @Override + public boolean isRewriteFrameMappingInformation() { + return true; + } + + @Override + public RewriteFrameMappingInformation asRewriteFrameMappingInformation() { + return this; + } + + public abstract static class Condition { + + protected abstract JsonPrimitive serialize(); + + private static Condition deserialize(JsonElement element) { + String elementString = element.getAsString(); + int argIndex = elementString.indexOf('('); + if (argIndex < 1 || !elementString.endsWith(")")) { + throw new CompilationError("Invalid formatted condition: " + elementString); + } + String functionName = elementString.substring(0, argIndex); + String contents = elementString.substring(argIndex + 1, elementString.length() - 1); + if (ThrowsCondition.FUNCTION_NAME.equals(functionName)) { + return ThrowsCondition.deserialize(contents); + } + throw new Unimplemented("Unexpected condition: " + elementString); + } + + public boolean isThrowsCondition() { + return false; + } + + public ThrowsCondition asThrowsCondition() { + return null; + } + + public abstract boolean evaluate(RetraceStackTraceContextImpl context); + } + + public static class ThrowsCondition extends Condition { + + static final String FUNCTION_NAME = "throws"; + + private final String descriptor; + + private ThrowsCondition(String descriptor) { + this.descriptor = descriptor; + } + + @Override + protected JsonPrimitive serialize() { + return new JsonPrimitive(FUNCTION_NAME + "(" + asThrowsCondition().getDescriptor() + ")"); + } + + @Override + public boolean isThrowsCondition() { + return true; + } + + public String getDescriptor() { + return descriptor; + } + + @Override + public ThrowsCondition asThrowsCondition() { + return this; + } + + @Override + public boolean evaluate(RetraceStackTraceContextImpl context) { + return context.getSeenException() != null + && context.getSeenException().getDescriptor().equals(descriptor); + } + + public static ThrowsCondition deserialize(String conditionString) { + if (!DescriptorUtils.isClassDescriptor(conditionString)) { + throw new CompilationError("Unexpected throws-descriptor: " + conditionString); + } + return new ThrowsCondition(conditionString); + } + } + + public abstract static class RewriteAction { + + static final String REMOVE_INNER_FRAMES_SERIALIZED_NAME = "removeInnerFrames"; + + private static final String FUNCTION_KEY = "function"; + private static final String ARGUMENTS_KEY = "arguments"; + + abstract String serializeName(); + + abstract JsonArray getArguments(); + + JsonElement serialize() { + JsonObject jsonObject = new JsonObject(); + jsonObject.add(FUNCTION_KEY, new JsonPrimitive(serializeName())); + jsonObject.add(ARGUMENTS_KEY, getArguments()); + return jsonObject; + } + + private static RewriteAction deserialize(JsonElement element) { + String functionString = element.getAsString(); + int startArgsIndex = functionString.indexOf("("); + int endArgsIndex = functionString.indexOf(")"); + if (endArgsIndex <= startArgsIndex) { + throw new Unimplemented("Unexpected action: " + functionString); + } + String functionName = functionString.substring(0, startArgsIndex); + String args = functionString.substring(startArgsIndex + 1, endArgsIndex); + if (REMOVE_INNER_FRAMES_SERIALIZED_NAME.equals(functionName)) { + return RemoveInnerFramesAction.create(args); + } + assert false : "Unknown function " + functionName; + throw new Unimplemented("Unexpected action: " + functionName); + } + + public boolean isRemoveInnerFramesAction() { + return false; + } + + public RemoveInnerFramesAction asRemoveInnerFramesRewriteAction() { + return null; + } + + public abstract void evaluate(RetraceStackTraceCurrentEvaluationInformation.Builder builder); + } + + public static class RemoveInnerFramesAction extends RewriteAction { + + private final int numberOfFrames; + + public RemoveInnerFramesAction(int numberOfFrames) { + this.numberOfFrames = numberOfFrames; + } + + public int getNumberOfFrames() { + return numberOfFrames; + } + + @Override + String serializeName() { + return REMOVE_INNER_FRAMES_SERIALIZED_NAME; + } + + @Override + JsonArray getArguments() { + JsonArray arguments = new JsonArray(); + arguments.add(numberOfFrames); + return arguments; + } + + static RemoveInnerFramesAction create(String args) { + return new RemoveInnerFramesAction(Integer.parseInt(args)); + } + + @Override + public boolean isRemoveInnerFramesAction() { + return true; + } + + @Override + public RemoveInnerFramesAction asRemoveInnerFramesRewriteAction() { + return this; + } + + @Override + public void evaluate(RetraceStackTraceCurrentEvaluationInformation.Builder builder) { + builder.incrementRemoveInnerFramesCount(numberOfFrames); + } + } +}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java index cabc28f..645bac0 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
@@ -67,8 +67,8 @@ timing.begin("Argument propagator"); timing.begin("Initialize code scanner"); - codeScanner = new ArgumentPropagatorCodeScanner(appView); reprocessingCriteriaCollection = new ArgumentPropagatorReprocessingCriteriaCollection(appView); + codeScanner = new ArgumentPropagatorCodeScanner(appView, reprocessingCriteriaCollection); ImmediateProgramSubtypingInfo immediateSubtypingInfo = ImmediateProgramSubtypingInfo.create(appView); @@ -110,6 +110,11 @@ } } + public void publishDelayedReprocessingCriteria() { + assert reprocessingCriteriaCollection != null; + reprocessingCriteriaCollection.publishDelayedReprocessingCriteria(); + } + public void transferArgumentInformation(ProgramMethod from, ProgramMethod to) { assert codeScanner != null; MethodStateCollectionByReference methodStates = codeScanner.getMethodStates(); @@ -125,6 +130,8 @@ Timing timing) throws ExecutionException { assert !appView.getSyntheticItems().hasPendingSyntheticClasses(); + assert reprocessingCriteriaCollection.verifyNoDelayedReprocessingCriteria(); + timing.begin("Argument propagator"); // Compute the strongly connected program components for parallel execution.
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java index beb3003..890cb48 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java
@@ -8,7 +8,7 @@ import com.android.tools.r8.graph.DexMethod; import com.android.tools.r8.graph.DexProgramClass; import com.android.tools.r8.graph.MethodCollection; -import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection; +import com.android.tools.r8.graph.RewrittenPrototypeDescription; import com.android.tools.r8.shaking.AppInfoWithLiveness; import com.android.tools.r8.utils.ThreadUtils; import com.android.tools.r8.utils.Timing; @@ -66,12 +66,12 @@ return method.toTypeSubstitutedMethod( methodReferenceAfterParameterRemoval, builder -> { - ArgumentInfoCollection removedParameters = - graphLens.getRemovedParameters(methodReferenceAfterParameterRemoval); + RewrittenPrototypeDescription prototypeChanges = + graphLens.getPrototypeChanges(methodReferenceAfterParameterRemoval); builder - .apply(removedParameters.createParameterAnnotationsRemover(method)) + .apply(prototypeChanges.createParameterAnnotationsRemover(method)) .fixupOptimizationInfo( - appView, removedParameters.createMethodOptimizationInfoFixer()); + appView, prototypeChanges.createMethodOptimizationInfoFixer()); }); }); }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java index a61d0b4..4d19a71 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
@@ -40,6 +40,9 @@ import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodStateCollectionByReference; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ParameterState; import com.android.tools.r8.optimize.argumentpropagation.codescanner.UnknownMethodState; +import com.android.tools.r8.optimize.argumentpropagation.reprocessingcriteria.ArgumentPropagatorReprocessingCriteriaCollection; +import com.android.tools.r8.optimize.argumentpropagation.reprocessingcriteria.MethodReprocessingCriteria; +import com.android.tools.r8.optimize.argumentpropagation.reprocessingcriteria.ParameterReprocessingCriteria; import com.android.tools.r8.optimize.argumentpropagation.utils.WideningUtils; import com.android.tools.r8.shaking.AppInfoWithLiveness; import com.android.tools.r8.utils.Timing; @@ -68,6 +71,8 @@ private final Set<DexMethod> monomorphicVirtualMethods = Sets.newIdentityHashSet(); + private final ArgumentPropagatorReprocessingCriteriaCollection reprocessingCriteriaCollection; + /** * Maps each non-private virtual method to the upper most method in the class hierarchy with the * same method signature. Virtual methods that do not override other virtual methods are mapped to @@ -82,8 +87,11 @@ private final MethodStateCollectionByReference methodStates = MethodStateCollectionByReference.createConcurrent(); - ArgumentPropagatorCodeScanner(AppView<AppInfoWithLiveness> appView) { + ArgumentPropagatorCodeScanner( + AppView<AppInfoWithLiveness> appView, + ArgumentPropagatorReprocessingCriteriaCollection reprocessingCriteriaCollection) { this.appView = appView; + this.reprocessingCriteriaCollection = reprocessingCriteriaCollection; } public synchronized void addMonomorphicVirtualMethods(Set<DexMethod> extension) { @@ -259,7 +267,11 @@ assert existingMethodState.isBottom() || existingMethodState.isMonomorphic(); result = computeMonomorphicMethodState( - invoke, resolvedMethod, context, existingMethodState.asMonomorphicOrBottom()); + invoke, + resolvedMethod, + invoke.lookupSingleProgramTarget(appView, context), + context, + existingMethodState.asMonomorphicOrBottom()); } timing.end(); return result; @@ -276,9 +288,10 @@ DynamicType dynamicReceiverType = invoke.getReceiver().getDynamicType(appView); assert !dynamicReceiverType.getDynamicUpperBoundType().nullability().isDefinitelyNull(); + ProgramMethod singleTarget = invoke.lookupSingleProgramTarget(appView, context); DynamicType bounds = computeBoundsForPolymorphicMethodState( - invoke, resolvedMethod, context, dynamicReceiverType); + invoke, resolvedMethod, singleTarget, context, dynamicReceiverType); MethodState existingMethodStateForBounds = existingMethodState.isPolymorphic() ? existingMethodState.asPolymorphic().getMethodStateForBounds(bounds) @@ -299,6 +312,7 @@ computeMonomorphicMethodState( invoke, resolvedMethod, + singleTarget, context, existingMethodStateForBounds.asMonomorphicOrBottom(), dynamicReceiverType); @@ -308,9 +322,9 @@ private DynamicType computeBoundsForPolymorphicMethodState( InvokeMethodWithReceiver invoke, ProgramMethod resolvedMethod, + ProgramMethod singleTarget, ProgramMethod context, DynamicType dynamicReceiverType) { - ProgramMethod singleTarget = invoke.lookupSingleProgramTarget(appView, context); DynamicType bounds = singleTarget != null ? DynamicType.createExact( @@ -343,11 +357,13 @@ private ConcreteMonomorphicMethodStateOrUnknown computeMonomorphicMethodState( InvokeMethod invoke, ProgramMethod resolvedMethod, + ProgramMethod singleTarget, ProgramMethod context, ConcreteMonomorphicMethodStateOrBottom existingMethodState) { return computeMonomorphicMethodState( invoke, resolvedMethod, + singleTarget, context, existingMethodState, invoke.isInvokeMethodWithReceiver() @@ -358,11 +374,17 @@ private ConcreteMonomorphicMethodStateOrUnknown computeMonomorphicMethodState( InvokeMethod invoke, ProgramMethod resolvedMethod, + ProgramMethod singleTarget, ProgramMethod context, ConcreteMonomorphicMethodStateOrBottom existingMethodState, DynamicType dynamicReceiverType) { List<ParameterState> parameterStates = new ArrayList<>(invoke.arguments().size()); + MethodReprocessingCriteria methodReprocessingCriteria = + singleTarget != null + ? reprocessingCriteriaCollection.getReprocessingCriteria(singleTarget) + : MethodReprocessingCriteria.alwaysReprocess(); + int argumentIndex = 0; if (invoke.isInvokeMethodWithReceiver()) { assert dynamicReceiverType != null; @@ -371,7 +393,8 @@ invoke.asInvokeMethodWithReceiver(), resolvedMethod, dynamicReceiverType, - existingMethodState)); + existingMethodState, + methodReprocessingCriteria.getParameterReprocessingCriteria(0))); argumentIndex++; } @@ -382,7 +405,8 @@ argumentIndex, invoke.getArgument(argumentIndex), context, - existingMethodState)); + existingMethodState, + methodReprocessingCriteria.getParameterReprocessingCriteria(argumentIndex))); } // If all parameter states are unknown, then return a canonicalized unknown method state that @@ -402,13 +426,20 @@ InvokeMethodWithReceiver invoke, ProgramMethod resolvedMethod, DynamicType dynamicReceiverType, - ConcreteMonomorphicMethodStateOrBottom existingMethodState) { + ConcreteMonomorphicMethodStateOrBottom existingMethodState, + ParameterReprocessingCriteria parameterReprocessingCriteria) { // Don't compute a state for this parameter if the stored state is already unknown. if (existingMethodState.isMonomorphic() && existingMethodState.asMonomorphic().getParameterState(0).isUnknown()) { return ParameterState.unknown(); } + // For receivers we only track the dynamic type. Therefore, if there is no need to track the + // dynamic type of the receiver of the targeted method, then just return unknown. + if (!parameterReprocessingCriteria.shouldReprocessDueToDynamicType()) { + return ParameterState.unknown(); + } + DynamicType widenedDynamicReceiverType = WideningUtils.widenDynamicReceiverType(appView, resolvedMethod, dynamicReceiverType); return widenedDynamicReceiverType.isUnknown() @@ -421,7 +452,8 @@ int argumentIndex, Value argument, ProgramMethod context, - ConcreteMonomorphicMethodStateOrBottom existingMethodState) { + ConcreteMonomorphicMethodStateOrBottom existingMethodState, + ParameterReprocessingCriteria parameterReprocessingCriteria) { // Don't compute a state for this parameter if the stored state is already unknown. if (existingMethodState.isMonomorphic() && existingMethodState.asMonomorphic().getParameterState(argumentIndex).isUnknown()) { @@ -469,6 +501,12 @@ // then use UnknownParameterState. if (parameterTypeElement.isClassType()) { DynamicType dynamicType = argument.getDynamicType(appView); + if (!parameterReprocessingCriteria.shouldReprocessDueToDynamicType()) { + dynamicType = + parameterReprocessingCriteria.widenDynamicClassType( + appView, dynamicType, parameterTypeElement.asClassType()); + } + DynamicType widenedDynamicType = WideningUtils.widenDynamicNonReceiverType(appView, dynamicType, parameterType); return abstractValue.isUnknown() && widenedDynamicType.isUnknown()
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorGraphLens.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorGraphLens.java index a00c016..c3fe41b 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorGraphLens.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorGraphLens.java
@@ -8,7 +8,6 @@ import com.android.tools.r8.graph.DexMethod; import com.android.tools.r8.graph.NestedGraphLens; import com.android.tools.r8.graph.RewrittenPrototypeDescription; -import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection; import com.android.tools.r8.shaking.AppInfoWithLiveness; import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap; import com.android.tools.r8.utils.collections.BidirectionalOneToOneMap; @@ -18,23 +17,23 @@ public class ArgumentPropagatorGraphLens extends NestedGraphLens { - private final Map<DexMethod, ArgumentInfoCollection> removedParameters; + private final Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges; ArgumentPropagatorGraphLens( AppView<AppInfoWithLiveness> appView, BidirectionalOneToOneMap<DexMethod, DexMethod> methodMap, - Map<DexMethod, ArgumentInfoCollection> removedParameters) { + Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges) { super(appView, EMPTY_FIELD_MAP, methodMap, EMPTY_TYPE_MAP); - this.removedParameters = removedParameters; + this.prototypeChanges = prototypeChanges; } public static Builder builder(AppView<AppInfoWithLiveness> appView) { return new Builder(appView); } - public ArgumentInfoCollection getRemovedParameters(DexMethod method) { + public RewrittenPrototypeDescription getPrototypeChanges(DexMethod method) { assert method != internalGetPreviousMethodSignature(method); - return removedParameters.getOrDefault(method, ArgumentInfoCollection.empty()); + return prototypeChanges.getOrDefault(method, RewrittenPrototypeDescription.none()); } @Override @@ -42,10 +41,10 @@ RewrittenPrototypeDescription prototypeChanges, DexMethod method) { DexMethod previous = internalGetPreviousMethodSignature(method); if (previous == method) { - assert !removedParameters.containsKey(method); + assert !this.prototypeChanges.containsKey(method); return prototypeChanges; } - return prototypeChanges.withRemovedArguments(getRemovedParameters(method)); + return prototypeChanges.combine(getPrototypeChanges(method)); } @Override @@ -63,7 +62,7 @@ private final AppView<AppInfoWithLiveness> appView; private final MutableBidirectionalOneToOneMap<DexMethod, DexMethod> newMethodSignatures = new BidirectionalOneToOneHashMap<>(); - private final Map<DexMethod, ArgumentInfoCollection> removedParameters = + private final Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges = new IdentityHashMap<>(); Builder(AppView<AppInfoWithLiveness> appView) { @@ -77,16 +76,16 @@ public ArgumentPropagatorGraphLens.Builder mergeDisjoint( ArgumentPropagatorGraphLens.Builder partialGraphLensBuilder) { newMethodSignatures.putAll(partialGraphLensBuilder.newMethodSignatures); - removedParameters.putAll(partialGraphLensBuilder.removedParameters); + prototypeChanges.putAll(partialGraphLensBuilder.prototypeChanges); return this; } public Builder recordMove( - DexMethod from, DexMethod to, ArgumentInfoCollection removedParametersForMethod) { + DexMethod from, DexMethod to, RewrittenPrototypeDescription prototypeChangesForMethod) { assert from != to; newMethodSignatures.put(from, to); - if (!removedParametersForMethod.isEmpty()) { - removedParameters.put(to, removedParametersForMethod); + if (!prototypeChangesForMethod.isEmpty()) { + prototypeChanges.put(to, prototypeChangesForMethod); } return this; } @@ -94,7 +93,7 @@ public ArgumentPropagatorGraphLens build() { return isEmpty() ? null - : new ArgumentPropagatorGraphLens(appView, newMethodSignatures, removedParameters); + : new ArgumentPropagatorGraphLens(appView, newMethodSignatures, prototypeChanges); } } }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java index 6f97143..ae2a8aa 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
@@ -18,6 +18,7 @@ import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteClassTypeParameterState; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteMethodState; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteMonomorphicMethodState; +import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteMonomorphicMethodStateOrUnknown; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteParameterState; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcretePrimitiveTypeParameterState; import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodState; @@ -159,6 +160,11 @@ return; } + // Do not optimize @KeepConstantArgument methods. + if (appView.appInfo().isKeepConstantArgumentsMethod(method)) { + methodState = MethodState.unknown(); + } + methodState = getMethodStateAfterUnusedParameterRemoval(method, methodState); if (methodState.isUnknown()) { @@ -208,12 +214,9 @@ // before reenqueing. MethodReprocessingCriteria reprocessingCriteria = reprocessingCriteriaCollection.getReprocessingCriteria(method); - if (!reprocessingCriteria.shouldReprocess(appView, method, monomorphicMethodState)) { - return; - } - - // Do not optimize @KeepConstantArgument methods. - if (appView.appInfo().isKeepConstantArgumentsMethod(method)) { + ConcreteMonomorphicMethodStateOrUnknown widenedMethodState = + reprocessingCriteria.widenMethodState(appView, method, monomorphicMethodState); + if (widenedMethodState.isUnknown()) { return; } @@ -221,7 +224,7 @@ .getDefinition() .setCallSiteOptimizationInfo( ConcreteCallSiteOptimizationInfo.fromMethodState( - appView, method, monomorphicMethodState)); + appView, method, widenedMethodState.asMonomorphic())); } private MethodState getMethodStateAfterUnusedParameterRemoval(
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java index 5f14c9d..055013f 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
@@ -16,6 +16,7 @@ import com.android.tools.r8.graph.ImmediateProgramSubtypingInfo; import com.android.tools.r8.graph.ObjectAllocationInfoCollection; import com.android.tools.r8.graph.ProgramMethod; +import com.android.tools.r8.graph.RewrittenPrototypeDescription; import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection; import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo; import com.android.tools.r8.ir.analysis.value.AbstractValue; @@ -54,7 +55,8 @@ private final AppView<AppInfoWithLiveness> appView; private final ImmediateProgramSubtypingInfo immediateSubtypingInfo; - private final Map<DexClass, DexMethodSignatureSet> libraryMethods = new ConcurrentHashMap<>(); + private final Map<DexClass, DexMethodSignatureSet> libraryVirtualMethods = + new ConcurrentHashMap<>(); public ArgumentPropagatorProgramOptimizer( AppView<AppInfoWithLiveness> appView, ImmediateProgramSubtypingInfo immediateSubtypingInfo) { @@ -88,25 +90,25 @@ return graphLens; } - private DexMethodSignatureSet getOrComputeLibraryMethods(DexClass clazz) { - DexMethodSignatureSet libraryMethodsOnClass = libraryMethods.get(clazz); + private DexMethodSignatureSet getOrComputeLibraryVirtualMethods(DexClass clazz) { + DexMethodSignatureSet libraryMethodsOnClass = libraryVirtualMethods.get(clazz); if (libraryMethodsOnClass != null) { return libraryMethodsOnClass; } - return computeLibraryMethods(clazz); + return computeLibraryVirtualMethods(clazz); } - private DexMethodSignatureSet computeLibraryMethods(DexClass clazz) { + private DexMethodSignatureSet computeLibraryVirtualMethods(DexClass clazz) { DexMethodSignatureSet libraryMethodsOnClass = DexMethodSignatureSet.create(); immediateSubtypingInfo.forEachImmediateSuperClassMatching( clazz, (supertype, superclass) -> superclass != null, (supertype, superclass) -> - libraryMethodsOnClass.addAll(getOrComputeLibraryMethods(superclass))); + libraryMethodsOnClass.addAll(getOrComputeLibraryVirtualMethods(superclass))); clazz.forEachClassMethodMatching( DexEncodedMethod::belongsToVirtualPool, method -> libraryMethodsOnClass.add(method.getMethodSignature())); - libraryMethods.put(clazz, libraryMethodsOnClass); + libraryVirtualMethods.put(clazz, libraryMethodsOnClass); return libraryMethodsOnClass; } @@ -182,7 +184,8 @@ DexMethodSignatureSet pinnedMethodSignatures = DexMethodSignatureSet.create(); Set<DexClass> seenLibraryClasses = Sets.newIdentityHashSet(); for (DexProgramClass clazz : stronglyConnectedProgramClasses) { - clazz.forEachProgramMethod( + clazz.forEachProgramMethodMatching( + method -> !method.isInstanceInitializer(), method -> { if (!appView.getKeepInfo(method).isShrinkingAllowed(options)) { pinnedMethodSignatures.add(method.getMethodSignature()); @@ -195,7 +198,7 @@ && !superclass.isProgramClass() && seenLibraryClasses.add(superclass), (supertype, superclass) -> - pinnedMethodSignatures.addAll(getOrComputeLibraryMethods(superclass))); + pinnedMethodSignatures.addAll(getOrComputeLibraryVirtualMethods(superclass))); } pinnedMethodSignatures.forEach( signature -> reserveMethodSignature(signature, signature, IntSets.EMPTY_SET)); @@ -266,6 +269,7 @@ private boolean isParameterRemovalAllowed(ProgramMethod method) { return appView.getKeepInfo(method).isParameterRemovalAllowed(options) && !method.getDefinition().isLibraryMethodOverride().isPossiblyTrue() + && !appView.appInfo().isBootstrapMethod(method) && !appView.appInfo().isMethodTargetedByInvokeDynamic(method); } @@ -306,16 +310,19 @@ private boolean visitClass( DexProgramClass clazz, ArgumentPropagatorGraphLens.Builder partialGraphLensBuilder) { BooleanBox affected = new BooleanBox(); + DexMethodSignatureSet instanceInitializerSignatures = DexMethodSignatureSet.create(); + clazz.forEachProgramInstanceInitializer(instanceInitializerSignatures::add); clazz.forEachProgramMethod( method -> { - ArgumentInfoCollection removableParameters = + RewrittenPrototypeDescription prototypeChanges = method.getDefinition().belongsToDirectPool() - ? computeRemovableParametersFromDirectMethod(method) + ? computeRemovableParametersFromDirectMethod( + method, instanceInitializerSignatures) : computeRemovableParametersFromVirtualMethod(method); - DexMethod newMethodSignature = getNewMethodSignature(method, removableParameters); + DexMethod newMethodSignature = getNewMethodSignature(method, prototypeChanges); if (newMethodSignature != method.getReference()) { partialGraphLensBuilder.recordMove( - method.getReference(), newMethodSignature, removableParameters); + method.getReference(), newMethodSignature, prototypeChanges); affected.set(); } }); @@ -323,30 +330,32 @@ } private DexMethod getNewMethodSignature( - ProgramMethod method, ArgumentInfoCollection removableParameters) { - DexMethodSignature methodSignatureWithoutParametersRemoved = method.getMethodSignature(); - IntSet removableParameterIndices = removableParameters.getKeys(); + ProgramMethod method, RewrittenPrototypeDescription prototypeChanges) { + DexMethodSignature methodSignatureWithoutPrototypeChanges = method.getMethodSignature(); + IntSet removableParameterIndices = prototypeChanges.getArgumentInfoCollection().getKeys(); // Check if there is a reserved signature for this already. DexMethodSignature reservedSignature = newMethodSignatures - .getOrDefault(methodSignatureWithoutParametersRemoved, Collections.emptyMap()) + .getOrDefault(methodSignatureWithoutPrototypeChanges, Collections.emptyMap()) .get(removableParameterIndices); if (reservedSignature != null) { return reservedSignature.withHolder(method.getHolderType(), dexItemFactory); } DexMethod methodReferenceWithParametersRemoved = - removableParameters.rewriteMethod(method, dexItemFactory); + prototypeChanges.getArgumentInfoCollection().rewriteMethod(method, dexItemFactory); DexMethodSignature methodSignatureWithParametersRemoved = methodReferenceWithParametersRemoved.getSignature(); // Find a method signature. First check if the current signature is available. if (!occupiedMethodSignatures.containsKey(methodSignatureWithParametersRemoved)) { - reserveMethodSignature( - methodSignatureWithParametersRemoved, - methodSignatureWithoutParametersRemoved, - removableParameterIndices); + if (!method.getDefinition().isInstanceInitializer()) { + reserveMethodSignature( + methodSignatureWithParametersRemoved, + methodSignatureWithoutPrototypeChanges, + removableParameterIndices); + } return methodReferenceWithParametersRemoved; } @@ -354,7 +363,7 @@ occupiedMethodSignatures.get(methodSignatureWithParametersRemoved); // In this case we should have found a reserved method signature above. assert !(occupant.getFirst().equals(removableParameterIndices) - && occupant.getSecond().equals(methodSignatureWithoutParametersRemoved)); + && occupant.getSecond().equals(methodSignatureWithoutPrototypeChanges)); // We need to find a new name for this method, since the signature is already occupied. // TODO(b/190154391): Instead of generating a new name, we could also try permuting the order @@ -371,45 +380,55 @@ return true; } return candidateOccupant.getFirst().equals(removableParameterIndices) - && candidateOccupant - .getSecond() - .equals(methodSignatureWithoutParametersRemoved); + && candidateOccupant.getSecond().equals(methodSignatureWithoutPrototypeChanges); }); // Reserve the newly generated method signature. - reserveMethodSignature( - newMethod.getSignature(), - methodSignatureWithoutParametersRemoved, - removableParameterIndices); + if (!method.getDefinition().isInstanceInitializer()) { + reserveMethodSignature( + newMethod.getSignature(), + methodSignatureWithoutPrototypeChanges, + removableParameterIndices); + } return newMethod; } - private ArgumentInfoCollection computeRemovableParametersFromDirectMethod( - ProgramMethod method) { + private RewrittenPrototypeDescription computeRemovableParametersFromDirectMethod( + ProgramMethod method, DexMethodSignatureSet instanceInitializerSignatures) { assert method.getDefinition().belongsToDirectPool(); - // TODO(b/190154391): Allow parameter removal from initializers. We need to guarantee absence - // of collisions since initializers can't be renamed. - if (!isParameterRemovalAllowed(method) || method.getDefinition().isInstanceInitializer()) { - return ArgumentInfoCollection.empty(); + if (!isParameterRemovalAllowed(method)) { + return RewrittenPrototypeDescription.none(); } // TODO(b/199864962): Allow parameter removal from check-not-null classified methods. if (method .getOptimizationInfo() .getEnumUnboxerMethodClassification() .isCheckNotNullClassification()) { - return ArgumentInfoCollection.empty(); + return RewrittenPrototypeDescription.none(); } - return computeRemovableParametersFromMethod(method); + RewrittenPrototypeDescription prototypeChanges = computePrototypeChangesForMethod(method); + if (prototypeChanges.isEmpty()) { + return prototypeChanges; + } + if (method.getDefinition().isInstanceInitializer()) { + DexMethod rewrittenMethod = + prototypeChanges.getArgumentInfoCollection().rewriteMethod(method, dexItemFactory); + assert rewrittenMethod != method.getReference(); + if (!instanceInitializerSignatures.add(rewrittenMethod)) { + return RewrittenPrototypeDescription.none(); + } + } + return prototypeChanges; } - private ArgumentInfoCollection computeRemovableParametersFromVirtualMethod( + private RewrittenPrototypeDescription computeRemovableParametersFromVirtualMethod( ProgramMethod method) { IntSet removableParameterIndices = removableVirtualMethodParameters.getOrDefault( method.getMethodSignature(), IntSets.EMPTY_SET); if (removableParameterIndices.isEmpty()) { - return ArgumentInfoCollection.empty(); + return RewrittenPrototypeDescription.none(); } if (method.getAccessFlags().isAbstract()) { @@ -423,25 +442,27 @@ .setType(method.getArgumentType(removableParameterIndex)) .build()); } - return removableParametersBuilder.build(); + return RewrittenPrototypeDescription.create( + Collections.emptyList(), null, removableParametersBuilder.build()); } - ArgumentInfoCollection removableParameters = - computeRemovableParametersFromMethod(method, removableParameterIndices::contains); - assert removableParameters.size() == removableParameterIndices.size(); - return removableParameters; + RewrittenPrototypeDescription prototypeChanges = + computePrototypeChangesForMethod(method, removableParameterIndices::contains); + assert prototypeChanges.getArgumentInfoCollection().size() + == removableParameterIndices.size(); + return prototypeChanges; } - private ArgumentInfoCollection computeRemovableParametersFromMethod(ProgramMethod method) { - return computeRemovableParametersFromMethod(method, parameterIndex -> true); + private RewrittenPrototypeDescription computePrototypeChangesForMethod(ProgramMethod method) { + return computePrototypeChangesForMethod(method, parameterIndex -> true); } - private ArgumentInfoCollection computeRemovableParametersFromMethod( + private RewrittenPrototypeDescription computePrototypeChangesForMethod( ProgramMethod method, IntPredicate removableParameterIndices) { ConcreteCallSiteOptimizationInfo optimizationInfo = method.getDefinition().getCallSiteOptimizationInfo().asConcreteCallSiteOptimizationInfo(); if (optimizationInfo == null) { - return ArgumentInfoCollection.empty(); + return RewrittenPrototypeDescription.none(); } ArgumentInfoCollection.Builder removableParametersBuilder = ArgumentInfoCollection.builder(); @@ -462,7 +483,8 @@ .build()); } } - return removableParametersBuilder.build(); + return RewrittenPrototypeDescription.create( + Collections.emptyList(), null, removableParametersBuilder.build()); } } }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ArgumentPropagatorReprocessingCriteriaCollection.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ArgumentPropagatorReprocessingCriteriaCollection.java index 68191f9..90e9ead 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ArgumentPropagatorReprocessingCriteriaCollection.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ArgumentPropagatorReprocessingCriteriaCollection.java
@@ -27,6 +27,7 @@ import com.android.tools.r8.shaking.AppInfoWithLiveness; import it.unimi.dsi.fastutil.ints.Int2ReferenceMap; import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; +import java.util.IdentityHashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -35,6 +36,9 @@ private final AppView<AppInfoWithLiveness> appView; private final Map<DexMethod, MethodReprocessingCriteria> reproccessingCriteria = + new IdentityHashMap<>(); + + private final Map<DexMethod, MethodReprocessingCriteria> delayedReproccessingCriteria = new ConcurrentHashMap<>(); public ArgumentPropagatorReprocessingCriteriaCollection(AppView<AppInfoWithLiveness> appView) { @@ -43,7 +47,12 @@ public MethodReprocessingCriteria getReprocessingCriteria(ProgramMethod method) { return reproccessingCriteria.getOrDefault( - method.getReference(), MethodReprocessingCriteria.empty()); + method.getReference(), MethodReprocessingCriteria.alwaysReprocess()); + } + + public void publishDelayedReprocessingCriteria() { + reproccessingCriteria.putAll(delayedReproccessingCriteria); + delayedReproccessingCriteria.clear(); } /** @@ -69,7 +78,7 @@ // optimization info, then record this information. If the map is empty, then the method should // always be reprocessed if we find non-trivial optimization info for some of the parameters. if (!methodReprocessingCriteria.isEmpty()) { - reproccessingCriteria.put( + delayedReproccessingCriteria.put( method.getReference(), new MethodReprocessingCriteria(methodReprocessingCriteria)); } } @@ -142,4 +151,9 @@ return builder.build(); } + + public boolean verifyNoDelayedReprocessingCriteria() { + assert delayedReproccessingCriteria.isEmpty(); + return true; + } }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/MethodReprocessingCriteria.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/MethodReprocessingCriteria.java index 527ee9e..658383f 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/MethodReprocessingCriteria.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/MethodReprocessingCriteria.java
@@ -8,14 +8,19 @@ import com.android.tools.r8.graph.DexType; import com.android.tools.r8.graph.ProgramMethod; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteMonomorphicMethodState; +import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteMonomorphicMethodStateOrUnknown; +import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodState; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ParameterState; +import com.android.tools.r8.optimize.argumentpropagation.codescanner.UnknownParameterState; import com.android.tools.r8.shaking.AppInfoWithLiveness; +import com.google.common.collect.Iterables; import it.unimi.dsi.fastutil.ints.Int2ReferenceMap; import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; public class MethodReprocessingCriteria { - public static final MethodReprocessingCriteria EMPTY = new MethodReprocessingCriteria(); + public static final MethodReprocessingCriteria ALWAYS_REPROCESS = + new MethodReprocessingCriteria(); private final Int2ReferenceMap<ParameterReprocessingCriteria> reproccesingCriteria; @@ -29,8 +34,8 @@ this.reproccesingCriteria = reproccesingCriteria; } - public static MethodReprocessingCriteria empty() { - return EMPTY; + public static MethodReprocessingCriteria alwaysReprocess() { + return ALWAYS_REPROCESS; } public ParameterReprocessingCriteria getParameterReprocessingCriteria(int parameterIndex) { @@ -38,7 +43,7 @@ parameterIndex, ParameterReprocessingCriteria.alwaysReprocess()); } - public boolean shouldReprocess( + public ConcreteMonomorphicMethodStateOrUnknown widenMethodState( AppView<AppInfoWithLiveness> appView, ProgramMethod method, ConcreteMonomorphicMethodState methodState) { @@ -49,14 +54,24 @@ continue; } + if (parameterState.getAbstractValue(appView).isSingleValue()) { + // Don't widen when we have information that can be used for parameter removal. + continue; + } + ParameterReprocessingCriteria parameterReprocessingCriteria = getParameterReprocessingCriteria(parameterIndex); DexType parameterType = method.getArgumentType(parameterIndex); if (parameterReprocessingCriteria.shouldReprocess( appView, parameterState.asConcrete(), parameterType)) { - return true; + continue; } + + methodState.setParameterState(parameterIndex, UnknownParameterState.get()); } - return false; + + return Iterables.all(methodState.getParameterStates(), ParameterState::isUnknown) + ? MethodState.unknown() + : methodState; } }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ParameterReprocessingCriteria.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ParameterReprocessingCriteria.java index 9022f81..d7c8890 100644 --- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ParameterReprocessingCriteria.java +++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/reprocessingcriteria/ParameterReprocessingCriteria.java
@@ -6,6 +6,8 @@ import com.android.tools.r8.graph.AppView; import com.android.tools.r8.graph.DexType; +import com.android.tools.r8.ir.analysis.type.ClassTypeElement; +import com.android.tools.r8.ir.analysis.type.DynamicType; import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteParameterState; import com.android.tools.r8.shaking.AppInfoWithLiveness; @@ -42,6 +44,14 @@ public abstract boolean shouldReprocessDueToNullability(); + public final DynamicType widenDynamicClassType( + AppView<AppInfoWithLiveness> appView, DynamicType dynamicType, ClassTypeElement staticType) { + if (dynamicType.getNullability().isMaybeNull()) { + return DynamicType.unknown(); + } + return DynamicType.create(appView, staticType.getOrCreateVariant(dynamicType.getNullability())); + } + public static class Builder { private boolean reprocessDueToAbstractValue;
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java index 43bf109..6e61118 100644 --- a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java +++ b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
@@ -31,4 +31,6 @@ RetraceFrameResult lookupFrame(Optional<Integer> position, MethodReference methodReference); RetraceUnknownJsonMappingInformationResult getUnknownJsonMappingInformation(); + + RetraceStackTraceContext getContextWhereClassWasThrown(); }
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceElement.java index 63d40db..55de558 100644 --- a/src/main/java/com/android/tools/r8/retrace/RetraceElement.java +++ b/src/main/java/com/android/tools/r8/retrace/RetraceElement.java
@@ -16,6 +16,4 @@ R getRetraceResultContext(); boolean isCompilerSynthesized(); - - RetraceStackTraceContext getContext(); }
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java index b114240..f2ad4e7 100644 --- a/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java +++ b/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java
@@ -18,9 +18,12 @@ void visitAllFrames(BiConsumer<RetracedMethodReference, Integer> consumer); - void visitNonCompilerSynthesizedFrames(BiConsumer<RetracedMethodReference, Integer> consumer); + void visitRewrittenFrames( + RetraceStackTraceContext context, BiConsumer<RetracedMethodReference, Integer> consumer); RetracedSourceFile getSourceFile(RetracedClassMemberReference frame); List<? extends RetracedMethodReference> getOuterFrames(); + + RetraceStackTraceContext getContext(); }
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceInvalidRewriteFrameDiagnostics.java b/src/main/java/com/android/tools/r8/retrace/RetraceInvalidRewriteFrameDiagnostics.java new file mode 100644 index 0000000..ace1b86 --- /dev/null +++ b/src/main/java/com/android/tools/r8/retrace/RetraceInvalidRewriteFrameDiagnostics.java
@@ -0,0 +1,46 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.retrace; + +import com.android.tools.r8.Diagnostic; +import com.android.tools.r8.Keep; +import com.android.tools.r8.origin.Origin; +import com.android.tools.r8.position.Position; + +@Keep +public class RetraceInvalidRewriteFrameDiagnostics implements Diagnostic { + + private final int numberOfFramesToRemove; + private final String method; + + private RetraceInvalidRewriteFrameDiagnostics(int numberOfFramesToRemove, String method) { + this.numberOfFramesToRemove = numberOfFramesToRemove; + this.method = method; + } + + @Override + public Origin getOrigin() { + return Origin.unknown(); + } + + @Override + public Position getPosition() { + return Position.UNKNOWN; + } + + @Override + public String getDiagnosticMessage() { + return "Cannot remove " + + numberOfFramesToRemove + + " frames from the retraced output of " + + method + + " because it exceeds the number of retraced frames"; + } + + public static RetraceInvalidRewriteFrameDiagnostics create( + int numberOfFramesToRemove, String method) { + return new RetraceInvalidRewriteFrameDiagnostics(numberOfFramesToRemove, method); + } +}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java index 9004cc1..e87ff95 100644 --- a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java +++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java
@@ -11,6 +11,6 @@ public interface RetraceStackTraceContext { static RetraceStackTraceContext getInitialContext() { - return new RetraceStackTraceContextImpl(); + return RetraceStackTraceContextImpl.builder().build(); } }
diff --git a/src/main/java/com/android/tools/r8/retrace/Retracer.java b/src/main/java/com/android/tools/r8/retrace/Retracer.java index c609e44..bd865a8 100644 --- a/src/main/java/com/android/tools/r8/retrace/Retracer.java +++ b/src/main/java/com/android/tools/r8/retrace/Retracer.java
@@ -33,4 +33,9 @@ ProguardMapProducer proguardMapProducer, DiagnosticsHandler diagnosticsHandler) { return RetracerImpl.create(proguardMapProducer, diagnosticsHandler, false); } + + static Retracer createExperimental( + ProguardMapProducer proguardMapProducer, DiagnosticsHandler diagnosticsHandler) { + return RetracerImpl.create(proguardMapProducer, diagnosticsHandler, true); + } }
diff --git a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java index 0296d71..ff5b970 100644 --- a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java +++ b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
@@ -10,6 +10,7 @@ import com.android.tools.r8.Keep; import com.android.tools.r8.retrace.internal.StackTraceElementStringProxy; import com.android.tools.r8.utils.ListUtils; +import com.android.tools.r8.utils.StringUtils; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -78,21 +79,27 @@ List<String> retracedStrings = new ArrayList<>(); List<List<String>> retracedStackTraces = removeDuplicateStackTraces(retraceStackTrace(stackTrace)); - if (retracedStackTraces.size() > 1) { - retracedStrings.add( - "There are " - + retracedStackTraces.size() - + " ambiguous stack traces." - + (isVerbose ? "" : " Use --verbose to have all listed.")); + if (retracedStackTraces.size() > 1 && isVerbose) { + retracedStrings.add("There are " + retracedStackTraces.size() + " ambiguous stack traces."); } for (int i = 0; i < retracedStackTraces.size(); i++) { - if (i > 0) { - retracedStrings.add("< OR >"); + List<String> result = retracedStackTraces.get(i); + if (i > 0 && !result.isEmpty()) { + // We are reporting an ambiguous frame. To support retracing tools that retrace line by line + // we have to emit <OR> at the point of the first ' at ' if we can find it. + String firstLine = result.get(0); + int indexToInsertOr = firstLine.indexOf(" at "); + boolean hasSpace = indexToInsertOr >= 0; + if (indexToInsertOr < 0) { + indexToInsertOr = Math.max(StringUtils.firstNonWhitespaceCharacter(firstLine), 0); + } + result.set( + 0, + firstLine.substring(0, indexToInsertOr) + + (hasSpace ? "<OR>" : "<OR> ") + + firstLine.substring(indexToInsertOr)); } - retracedStrings.addAll(retracedStackTraces.get(i)); - if (!isVerbose) { - break; - } + retracedStrings.addAll(result); } return retracedStrings; }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java index 54c90e6..0f165cf 100644 --- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java +++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
@@ -20,7 +20,6 @@ import com.android.tools.r8.retrace.RetraceStackTraceContext; import com.android.tools.r8.retrace.RetraceUnknownJsonMappingInformationResult; import com.android.tools.r8.retrace.RetracedSourceFile; -import com.android.tools.r8.retrace.Retracer; import com.android.tools.r8.utils.ListUtils; import com.android.tools.r8.utils.Pair; import com.google.common.collect.ImmutableList; @@ -220,7 +219,7 @@ RetraceClassResultImpl classResult, List<Pair<RetraceClassElementImpl, T>> mappings, D definition, - Retracer retracer); + RetracerImpl retracer); } public static class RetraceClassElementImpl implements RetraceClassElement { @@ -273,9 +272,10 @@ } @Override - public RetraceStackTraceContext getContext() { - // TODO(b/197936862): Extend the context to enable tracking information. - return RetraceStackTraceContext.getInitialContext(); + public RetraceStackTraceContext getContextWhereClassWasThrown() { + return RetraceStackTraceContextImpl.builder() + .setSeenException(getRetracedClass().getClassReference()) + .build(); } @Override
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java index b536bea..38667c4 100644 --- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java +++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
@@ -10,7 +10,6 @@ import com.android.tools.r8.references.Reference; import com.android.tools.r8.retrace.RetraceFieldElement; import com.android.tools.r8.retrace.RetraceFieldResult; -import com.android.tools.r8.retrace.RetraceStackTraceContext; import com.android.tools.r8.retrace.RetracedSourceFile; import com.android.tools.r8.retrace.Retracer; import com.android.tools.r8.retrace.internal.RetraceClassResultImpl.RetraceClassElementImpl; @@ -114,11 +113,6 @@ } @Override - public RetraceStackTraceContext getContext() { - return RetraceStackTraceContext.getInitialContext(); - } - - @Override public boolean isUnknown() { return fieldReference.isUnknown(); }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java index 2f79d8e..9bee685 100644 --- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java +++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
@@ -6,16 +6,17 @@ import static com.android.tools.r8.retrace.internal.RetraceUtils.methodReferenceFromMappedRange; +import com.android.tools.r8.DiagnosticsHandler; import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRange; import com.android.tools.r8.naming.Range; import com.android.tools.r8.references.MethodReference; import com.android.tools.r8.retrace.RetraceFrameElement; import com.android.tools.r8.retrace.RetraceFrameResult; +import com.android.tools.r8.retrace.RetraceInvalidRewriteFrameDiagnostics; import com.android.tools.r8.retrace.RetraceStackTraceContext; import com.android.tools.r8.retrace.RetracedClassMemberReference; import com.android.tools.r8.retrace.RetracedMethodReference; import com.android.tools.r8.retrace.RetracedSourceFile; -import com.android.tools.r8.retrace.Retracer; import com.android.tools.r8.retrace.internal.RetraceClassResultImpl.RetraceClassElementImpl; import com.android.tools.r8.utils.ListUtils; import com.android.tools.r8.utils.OptionalBool; @@ -35,7 +36,7 @@ private final MethodDefinition methodDefinition; private final Optional<Integer> obfuscatedPosition; private final List<Pair<RetraceClassElementImpl, List<MappedRange>>> mappedRanges; - private final Retracer retracer; + private final RetracerImpl retracer; private OptionalBool isAmbiguousCache = OptionalBool.UNKNOWN; @@ -44,7 +45,7 @@ List<Pair<RetraceClassElementImpl, List<MappedRange>>> mappedRanges, MethodDefinition methodDefinition, Optional<Integer> obfuscatedPosition, - Retracer retracer) { + RetracerImpl retracer) { this.classResult = classResult; this.methodDefinition = methodDefinition; this.obfuscatedPosition = obfuscatedPosition; @@ -93,7 +94,8 @@ methodDefinition.substituteHolder( classElement.getRetracedClass().getClassReference())), ImmutableList.of(), - obfuscatedPosition)); + obfuscatedPosition, + retracer)); } // Iterate over mapped ranges that may have different positions than specified. List<ElementImpl> ambiguousFrames = new ArrayList<>(); @@ -125,7 +127,8 @@ classElement, getRetracedMethod(methodReference, topFrame, obfuscatedPosition), mappedRangesForElement, - obfuscatedPosition); + obfuscatedPosition, + retracer); } private RetracedMethodReferenceImpl getRetracedMethod( @@ -156,18 +159,21 @@ private final RetraceClassElementImpl classElement; private final List<MappedRange> mappedRanges; private final Optional<Integer> obfuscatedPosition; + private final RetracerImpl retracer; - private ElementImpl( + ElementImpl( RetraceFrameResultImpl retraceFrameResult, RetraceClassElementImpl classElement, RetracedMethodReferenceImpl methodReference, List<MappedRange> mappedRanges, - Optional<Integer> obfuscatedPosition) { + Optional<Integer> obfuscatedPosition, + RetracerImpl retracer) { this.methodReference = methodReference; this.retraceFrameResult = retraceFrameResult; this.classElement = classElement; this.mappedRanges = mappedRanges; this.obfuscatedPosition = obfuscatedPosition; + this.retracer = retracer; } private boolean isOuterMostFrameCompilerSynthesized() { @@ -188,11 +194,6 @@ } @Override - public RetraceStackTraceContext getContext() { - return RetraceStackTraceContext.getInitialContext(); - } - - @Override public RetraceFrameResult getRetraceResultContext() { return retraceFrameResult; } @@ -222,17 +223,32 @@ } @Override - public void visitNonCompilerSynthesizedFrames( - BiConsumer<RetracedMethodReference, Integer> consumer) { + public void visitRewrittenFrames( + RetraceStackTraceContext context, BiConsumer<RetracedMethodReference, Integer> consumer) { + RetraceStackTraceContextImpl contextImpl = (RetraceStackTraceContextImpl) context; + RetraceStackTraceCurrentEvaluationInformation currentFrameInformation = + contextImpl.computeRewritingInformation(mappedRanges); int index = 0; + int numberOfFramesToRemove = currentFrameInformation.getRemoveInnerFrames(); RetracedMethodReferenceImpl prev = getTopFrame(); - for (RetracedMethodReferenceImpl next : getOuterFrames()) { - consumer.accept(prev, index++); + List<RetracedMethodReferenceImpl> outerFrames = getOuterFrames(); + if (numberOfFramesToRemove > outerFrames.size() + 1) { + assert prev.isKnown(); + DiagnosticsHandler diagnosticsHandler = retracer.getDiagnosticsHandler(); + diagnosticsHandler.warning( + RetraceInvalidRewriteFrameDiagnostics.create( + numberOfFramesToRemove, prev.asKnown().toString())); + numberOfFramesToRemove = 0; + } + for (RetracedMethodReferenceImpl next : outerFrames) { + if (numberOfFramesToRemove-- <= 0) { + consumer.accept(prev, index++); + } prev = next; } // We expect only the last frame, i.e., the outer-most caller to potentially be synthesized. // If not include it too. - if (!isOuterMostFrameCompilerSynthesized()) { + if (numberOfFramesToRemove <= 0 && !isOuterMostFrameCompilerSynthesized()) { consumer.accept(prev, index); } } @@ -259,5 +275,11 @@ } return outerFrames; } + + @Override + public RetraceStackTraceContext getContext() { + // This will change when supporting outline frames. + return RetraceStackTraceContext.getInitialContext(); + } } }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java index 8ccdbdb..7d97ed2 100644 --- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java +++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java
@@ -10,10 +10,8 @@ import com.android.tools.r8.references.MethodReference; import com.android.tools.r8.retrace.RetraceMethodElement; import com.android.tools.r8.retrace.RetraceMethodResult; -import com.android.tools.r8.retrace.RetraceStackTraceContext; import com.android.tools.r8.retrace.RetracedMethodReference; import com.android.tools.r8.retrace.RetracedSourceFile; -import com.android.tools.r8.retrace.Retracer; import com.android.tools.r8.retrace.internal.RetraceClassResultImpl.RetraceClassElementImpl; import com.android.tools.r8.utils.Pair; import com.google.common.collect.ImmutableList; @@ -27,13 +25,13 @@ private final MethodDefinition methodDefinition; private final RetraceClassResultImpl classResult; private final List<Pair<RetraceClassElementImpl, List<MappedRange>>> mappedRanges; - private final Retracer retracer; + private final RetracerImpl retracer; RetraceMethodResultImpl( RetraceClassResultImpl classResult, List<Pair<RetraceClassElementImpl, List<MappedRange>>> mappedRanges, MethodDefinition methodDefinition, - Retracer retracer) { + RetracerImpl retracer) { this.classResult = classResult; this.mappedRanges = mappedRanges; this.methodDefinition = methodDefinition; @@ -149,11 +147,6 @@ } @Override - public RetraceStackTraceContext getContext() { - return RetraceStackTraceContext.getInitialContext(); - } - - @Override public boolean isUnknown() { return methodReference.isUnknown(); }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceStackTraceContextImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceStackTraceContextImpl.java index b33e06d..7cc4a30 100644 --- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceStackTraceContextImpl.java +++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceStackTraceContextImpl.java
@@ -4,6 +4,72 @@ package com.android.tools.r8.retrace.internal; +import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRange; +import com.android.tools.r8.naming.mappinginformation.RewriteFrameMappingInformation; +import com.android.tools.r8.naming.mappinginformation.RewriteFrameMappingInformation.Condition; +import com.android.tools.r8.naming.mappinginformation.RewriteFrameMappingInformation.RewriteAction; +import com.android.tools.r8.references.ClassReference; import com.android.tools.r8.retrace.RetraceStackTraceContext; +import com.android.tools.r8.utils.ListUtils; +import java.util.List; -public class RetraceStackTraceContextImpl implements RetraceStackTraceContext {} +public class RetraceStackTraceContextImpl implements RetraceStackTraceContext { + + private final ClassReference seenException; + + private RetraceStackTraceContextImpl(ClassReference seenException) { + this.seenException = seenException; + } + + public ClassReference getSeenException() { + return seenException; + } + + RetraceStackTraceCurrentEvaluationInformation computeRewritingInformation( + List<MappedRange> mappedRanges) { + if (mappedRanges == null || mappedRanges.isEmpty()) { + return RetraceStackTraceCurrentEvaluationInformation.empty(); + } + RetraceStackTraceCurrentEvaluationInformation.Builder builder = + RetraceStackTraceCurrentEvaluationInformation.builder(); + MappedRange last = ListUtils.last(mappedRanges); + for (RewriteFrameMappingInformation rewriteInformation : + last.getRewriteFrameMappingInformation()) { + if (evaluateConditions(rewriteInformation.getConditions())) { + for (RewriteAction action : rewriteInformation.getActions()) { + action.evaluate(builder); + } + } + } + return builder.build(); + } + + private boolean evaluateConditions(List<Condition> conditions) { + for (Condition condition : conditions) { + if (!condition.evaluate(this)) { + return false; + } + } + return true; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private ClassReference seenException; + + private Builder() {} + + public Builder setSeenException(ClassReference seenException) { + this.seenException = seenException; + return this; + } + + public RetraceStackTraceContextImpl build() { + return new RetraceStackTraceContextImpl(seenException); + } + } +}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceStackTraceCurrentEvaluationInformation.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceStackTraceCurrentEvaluationInformation.java new file mode 100644 index 0000000..b25454f --- /dev/null +++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceStackTraceCurrentEvaluationInformation.java
@@ -0,0 +1,43 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.retrace.internal; + +public class RetraceStackTraceCurrentEvaluationInformation { + + private static final RetraceStackTraceCurrentEvaluationInformation EMPTY = + new RetraceStackTraceCurrentEvaluationInformation(0); + + private final int removeInnerFrames; + + private RetraceStackTraceCurrentEvaluationInformation(int removeInnerFrames) { + this.removeInnerFrames = removeInnerFrames; + } + + public int getRemoveInnerFrames() { + return removeInnerFrames; + } + + public static RetraceStackTraceCurrentEvaluationInformation empty() { + return EMPTY; + } + + public static RetraceStackTraceCurrentEvaluationInformation.Builder builder() { + return new Builder(); + } + + public static class Builder { + + private int removeInnerFramesCount; + + public Builder incrementRemoveInnerFramesCount(int increment) { + removeInnerFramesCount += increment; + return this; + } + + RetraceStackTraceCurrentEvaluationInformation build() { + return new RetraceStackTraceCurrentEvaluationInformation(removeInnerFramesCount); + } + } +}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetracerImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetracerImpl.java index 0758be3..bad33d8 100644 --- a/src/main/java/com/android/tools/r8/retrace/internal/RetracerImpl.java +++ b/src/main/java/com/android/tools/r8/retrace/internal/RetracerImpl.java
@@ -21,9 +21,11 @@ public class RetracerImpl implements Retracer { private final ClassNameMapper classNameMapper; + private final DiagnosticsHandler diagnosticsHandler; - public RetracerImpl(ClassNameMapper classNameMapper) { + public RetracerImpl(ClassNameMapper classNameMapper, DiagnosticsHandler diagnosticsHandler) { this.classNameMapper = classNameMapper; + this.diagnosticsHandler = diagnosticsHandler; assert classNameMapper != null; } @@ -33,7 +35,8 @@ boolean allowExperimentalMapping) { if (proguardMapProducer instanceof DirectClassNameMapperProguardMapProducer) { return new RetracerImpl( - ((DirectClassNameMapperProguardMapProducer) proguardMapProducer).getClassNameMapper()); + ((DirectClassNameMapperProguardMapProducer) proguardMapProducer).getClassNameMapper(), + diagnosticsHandler); } try { ClassNameMapper classNameMapper = @@ -42,12 +45,16 @@ diagnosticsHandler, true, allowExperimentalMapping); - return new RetracerImpl(classNameMapper); + return new RetracerImpl(classNameMapper, diagnosticsHandler); } catch (Throwable throwable) { throw new InvalidMappingFileException(throwable); } } + public DiagnosticsHandler getDiagnosticsHandler() { + return diagnosticsHandler; + } + @Override public RetraceMethodResultImpl retraceMethod(MethodReference methodReference) { return retraceClass(methodReference.getHolderClass())
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java index 9fe783b..2e2c38f 100644 --- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java +++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
@@ -78,7 +78,9 @@ .setRetracedClass(classElement.getRetracedClass()) .joinAmbiguous(classResult.isAmbiguous()) .setTopFrame(true) - .setContext(classElement.getContext()) + // We assume, since no method was defined for this stack trace element, + // that this was a thrown exception. + .setContext(classElement.getContextWhereClassWasThrown()) .applyIf( element.hasSourceFile(), builder -> { @@ -110,7 +112,8 @@ frameElement -> { List<RetraceStackTraceElementProxyImpl<T, ST>> retracedProxies = new ArrayList<>(); - frameElement.visitNonCompilerSynthesizedFrames( + frameElement.visitRewrittenFrames( + proxy.getContext(), (frame, index) -> { boolean isTopFrame = index == 0; retracedProxies.add( @@ -164,7 +167,6 @@ .setRetracedField(fieldElement.getField()) .joinAmbiguous(retraceFieldResult.isAmbiguous()) .setTopFrame(true) - .setContext(fieldElement.getContext()) .applyIf( element.hasSourceFile(), builder -> {
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java index 5ef1b35..7b5eee3 100644 --- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java +++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -138,8 +138,6 @@ public final Map<DexMember<?, ?>, ProguardMemberRule> assumedValues; /** All methods that should be inlined if possible due to a configuration directive. */ private final Set<DexMethod> alwaysInline; - /** All methods that *must* be inlined due to a configuration directive (testing only). */ - private final Set<DexMethod> forceInline; /** All methods that *must* never be inlined due to a configuration directive (testing only). */ private final Set<DexMethod> neverInline; /** @@ -218,7 +216,6 @@ Map<DexMember<?, ?>, ProguardMemberRule> noSideEffects, Map<DexMember<?, ?>, ProguardMemberRule> assumedValues, Set<DexMethod> alwaysInline, - Set<DexMethod> forceInline, Set<DexMethod> neverInline, Set<DexMethod> neverInlineDueToSingleCaller, Set<DexMethod> whyAreYouNotInlining, @@ -256,7 +253,6 @@ this.assumedValues = assumedValues; this.callSites = callSites; this.alwaysInline = alwaysInline; - this.forceInline = forceInline; this.neverInline = neverInline; this.neverInlineDueToSingleCaller = neverInlineDueToSingleCaller; this.whyAreYouNotInlining = whyAreYouNotInlining; @@ -302,7 +298,6 @@ previous.noSideEffects, previous.assumedValues, previous.alwaysInline, - previous.forceInline, previous.neverInline, previous.neverInlineDueToSingleCaller, previous.whyAreYouNotInlining, @@ -349,7 +344,6 @@ previous.noSideEffects, previous.assumedValues, previous.alwaysInline, - previous.forceInline, previous.neverInline, previous.neverInlineDueToSingleCaller, previous.whyAreYouNotInlining, @@ -404,7 +398,6 @@ noSideEffects, assumedValues, alwaysInline, - forceInline, neverInline, neverInlineDueToSingleCaller, whyAreYouNotInlining, @@ -487,7 +480,6 @@ this.assumedValues = previous.assumedValues; this.callSites = previous.callSites; this.alwaysInline = previous.alwaysInline; - this.forceInline = previous.forceInline; this.neverInline = previous.neverInline; this.neverInlineDueToSingleCaller = previous.neverInlineDueToSingleCaller; this.whyAreYouNotInlining = previous.whyAreYouNotInlining; @@ -599,6 +591,10 @@ return bootstrapMethods.contains(method); } + public boolean isBootstrapMethod(ProgramMethod method) { + return isBootstrapMethod(method.getReference()); + } + public boolean isMethodTargetedByInvokeDynamic(DexMethod method) { return methodsTargetedByInvokeDynamic.contains(method); } @@ -619,14 +615,6 @@ return alwaysInline.isEmpty(); } - public boolean isForceInlineMethod(DexMethod method) { - return forceInline.contains(method); - } - - public boolean hasNoForceInlineMethods() { - return forceInline.isEmpty(); - } - public boolean isNeverInlineMethod(DexMethod method) { return neverInline.contains(method); } @@ -1108,7 +1096,6 @@ lens.rewriteReferenceKeys(noSideEffects, rules -> null), lens.rewriteReferenceKeys(assumedValues, rules -> null), lens.rewriteMethods(alwaysInline), - lens.rewriteMethods(forceInline), lens.rewriteMethods(neverInline), lens.rewriteMethods(neverInlineDueToSingleCaller), lens.rewriteMethods(whyAreYouNotInlining),
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 52d59bb..28c2602 100644 --- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java +++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -3727,7 +3727,6 @@ rootSet.noSideEffects, rootSet.assumedValues, amendWithCompanionMethods(rootSet.alwaysInline), - amendWithCompanionMethods(rootSet.forceInline), amendWithCompanionMethods(rootSet.neverInline), amendWithCompanionMethods(rootSet.neverInlineDueToSingleCaller), amendWithCompanionMethods(rootSet.whyAreYouNotInlining),
diff --git a/src/main/java/com/android/tools/r8/shaking/InlineRule.java b/src/main/java/com/android/tools/r8/shaking/InlineRule.java index 32412d7..7f77fab 100644 --- a/src/main/java/com/android/tools/r8/shaking/InlineRule.java +++ b/src/main/java/com/android/tools/r8/shaking/InlineRule.java
@@ -10,16 +10,8 @@ public class InlineRule extends ProguardConfigurationRule { - public static final Origin checkDiscardOrigin = new Origin(Origin.root()) { - @Override - public String part() { - return "<SYNTHETIC_CHECK_DISCARD_RULE>"; - } - }; - public enum Type { ALWAYS, - FORCE, NEVER, NEVER_SINGLE_CALLER } @@ -104,30 +96,11 @@ return type; } - public ProguardCheckDiscardRule asProguardCheckDiscardRule() { - assert type == Type.FORCE; - ProguardCheckDiscardRule.Builder builder = ProguardCheckDiscardRule.builder(); - builder.setOrigin(checkDiscardOrigin); - builder.setSource(null); - builder.addClassAnnotations(getClassAnnotations()); - builder.setClassAccessFlags(getClassAccessFlags()); - builder.setNegatedClassAccessFlags(getNegatedClassAccessFlags()); - builder.setClassTypeNegated(getClassTypeNegated()); - builder.setClassType(getClassType()); - builder.setClassNames(getClassNames()); - builder.addInheritanceAnnotations(getInheritanceAnnotations()); - builder.setInheritanceIsExtends(getInheritanceIsExtends()); - builder.setMemberRules(getMemberRules()); - return builder.build(); - } - @Override String typeString() { switch (type) { case ALWAYS: return "alwaysinline"; - case FORCE: - return "forceinline"; case NEVER: return "neverinline"; case NEVER_SINGLE_CALLER:
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java index 3072667..99da4fb 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -432,7 +432,7 @@ String devMessage = ""; if (Version.isDevelopmentVersion() && unknownOption != null - && (unknownOption.equals("forceinline") || unknownOption.equals("neverinline"))) { + && unknownOption.equals("neverinline")) { devMessage = ", this option needs to be turned on explicitly if used for tests."; } throw unknownOption(unknownOption, optionStart, devMessage); @@ -449,14 +449,6 @@ configurationBuilder.addRule(rule); return true; } - if (acceptString("forceinline")) { - InlineRule rule = parseInlineRule(InlineRule.Type.FORCE, optionStart); - configurationBuilder.addRule(rule); - // Insert a matching -checkdiscard rule to ensure force inlining happens. - ProguardCheckDiscardRule ruled = rule.asProguardCheckDiscardRule(); - configurationBuilder.addRule(ruled); - return true; - } if (acceptString("keepconstantarguments")) { ConstantArgumentRule rule = parseConstantArgumentRule(optionStart); configurationBuilder.addRule(rule);
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 bbe1773..c4ddd9f 100644 --- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java +++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -106,7 +106,6 @@ private final LinkedHashMap<DexReference, DexReference> reasonAsked = new LinkedHashMap<>(); private final LinkedHashMap<DexReference, DexReference> checkDiscarded = new LinkedHashMap<>(); private final Set<DexMethod> alwaysInline = Sets.newIdentityHashSet(); - private final Set<DexMethod> forceInline = Sets.newIdentityHashSet(); private final Set<DexMethod> neverInline = Sets.newIdentityHashSet(); private final Set<DexMethod> neverInlineDueToSingleCaller = Sets.newIdentityHashSet(); private final Set<DexMethod> bypassClinitforInlining = Sets.newIdentityHashSet(); @@ -368,14 +367,12 @@ bypassClinitforInlining); } assert Sets.intersection(neverInline, alwaysInline).isEmpty() - && Sets.intersection(neverInline, forceInline).isEmpty() - : "A method cannot be marked as both -neverinline and -forceinline/-alwaysinline."; + : "A method cannot be marked as both -neverinline and -alwaysinline."; return new RootSet( dependentMinimumKeepInfo, ImmutableList.copyOf(reasonAsked.values()), ImmutableList.copyOf(checkDiscarded.values()), alwaysInline, - forceInline, neverInline, neverInlineDueToSingleCaller, bypassClinitforInlining, @@ -1193,9 +1190,6 @@ case ALWAYS: alwaysInline.add(reference); break; - case FORCE: - forceInline.add(reference); - break; case NEVER: neverInline.add(reference); break; @@ -1561,7 +1555,6 @@ public final ImmutableList<DexReference> reasonAsked; public final ImmutableList<DexReference> checkDiscarded; public final Set<DexMethod> alwaysInline; - public final Set<DexMethod> forceInline; public final Set<DexMethod> bypassClinitForInlining; public final Set<DexMethod> whyAreYouNotInlining; public final Set<DexMethod> keepConstantArguments; @@ -1584,7 +1577,6 @@ ImmutableList<DexReference> reasonAsked, ImmutableList<DexReference> checkDiscarded, Set<DexMethod> alwaysInline, - Set<DexMethod> forceInline, Set<DexMethod> neverInline, Set<DexMethod> neverInlineDueToSingleCaller, Set<DexMethod> bypassClinitForInlining, @@ -1618,7 +1610,6 @@ this.reasonAsked = reasonAsked; this.checkDiscarded = checkDiscarded; this.alwaysInline = alwaysInline; - this.forceInline = forceInline; this.bypassClinitForInlining = bypassClinitForInlining; this.whyAreYouNotInlining = whyAreYouNotInlining; this.keepConstantArguments = keepConstantArguments; @@ -1995,7 +1986,6 @@ Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), - Collections.emptySet(), PredicateSet.empty(), Collections.emptySet(), Collections.emptySet(),
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java index a06fdb7..d660753 100644 --- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java +++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
@@ -109,11 +109,10 @@ private static SyntheticMarker internalStripMarkerFromClass( DexProgramClass clazz, AppView<?> appView) { - ClassAccessFlags flags = clazz.accessFlags; if (clazz.superType != appView.dexItemFactory().objectType) { return NO_MARKER; } - if (!flags.isSynthetic() || flags.isAbstract() || flags.isEnum()) { + if (isDefinitelyNotSyntheticProgramClass(clazz)) { return NO_MARKER; } SyntheticKind kind = @@ -139,6 +138,12 @@ kind, SynthesizingContext.fromSyntheticInputClass(clazz, context, appView)); } + // Filters out definitely not synthetic classes to avoid expensive computations on all classes. + public static boolean isDefinitelyNotSyntheticProgramClass(DexProgramClass clazz) { + ClassAccessFlags flags = clazz.accessFlags; + return !flags.isSynthetic() || flags.isEnum(); + } + private static DexType getSyntheticContextType( DexType type, SyntheticKind kind, DexItemFactory factory) { String prefix = SyntheticNaming.getPrefixForExternalSyntheticType(kind, type);
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java index 8c07884..fa3fc33 100644 --- a/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java +++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java
@@ -29,4 +29,11 @@ public SyntheticProgramClassBuilder self() { return this; } + + @Override + public DexProgramClass build() { + DexProgramClass clazz = super.build(); + assert !SyntheticMarker.isDefinitelyNotSyntheticProgramClass(clazz); + return clazz; + } }
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java index 3718fcf..308862a 100644 --- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java +++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -214,7 +214,6 @@ } public void disableGlobalOptimizations() { - enableArgumentRemoval = false; enableInlining = false; enableClassInlining = false; enableClassStaticizer = false; @@ -255,7 +254,6 @@ public boolean enableFieldBitAccessAnalysis = System.getProperty("com.android.tools.r8.fieldBitAccessAnalysis") != null; public boolean enableVerticalClassMerging = true; - public boolean enableArgumentRemoval = true; public boolean enableUnusedInterfaceRemoval = true; public boolean enableDevirtualization = true; public boolean enableInlining = @@ -1258,6 +1256,15 @@ return enableDynamicTypePropagation; } + public CallSiteOptimizationOptions setEnabled(boolean enabled) { + if (enabled) { + assert isEnabled(); + } else { + disableOptimization(); + } + return this; + } + public CallSiteOptimizationOptions setEnableLegacyConstantPropagation() { assert !enableLegacyConstantPropagation; enableLegacyConstantPropagation = true;
diff --git a/src/main/java/com/android/tools/r8/utils/collections/DexMethodSignatureSet.java b/src/main/java/com/android/tools/r8/utils/collections/DexMethodSignatureSet.java index b6f7c52..8ef1277 100644 --- a/src/main/java/com/android/tools/r8/utils/collections/DexMethodSignatureSet.java +++ b/src/main/java/com/android/tools/r8/utils/collections/DexMethodSignatureSet.java
@@ -94,6 +94,10 @@ return backing.contains(signature); } + public boolean contains(DexMethod method) { + return contains(method.getSignature()); + } + public boolean contains(DexEncodedMethod method) { return contains(method.getSignature()); }
diff --git a/src/test/examples/classmerging/CallGraphCycleTest.java b/src/test/examples/classmerging/CallGraphCycleTest.java index 40347d6..ea958d2 100644 --- a/src/test/examples/classmerging/CallGraphCycleTest.java +++ b/src/test/examples/classmerging/CallGraphCycleTest.java
@@ -7,14 +7,14 @@ public class CallGraphCycleTest { public static void main(String[] args) { - new B(true); + new B(args.length == 0, args.length == 1); } public static class A { - public A(boolean instantiateB) { + public A(boolean instantiateB, boolean alwaysFalse) { if (instantiateB) { - new B(false); + new B(alwaysFalse, alwaysFalse); } System.out.println("A(" + instantiateB + ")"); } @@ -22,8 +22,8 @@ public static class B extends A { - public B(boolean instantiateBinA) { - super(instantiateBinA); + public B(boolean instantiateBinA, boolean alwaysFalse) { + super(instantiateBinA, alwaysFalse); System.out.println("B(" + instantiateBinA + ")"); } }
diff --git a/src/test/examples/shaking1/Shaking.java b/src/test/examples/shaking1/Shaking.java index 8c39ab8..924ae93 100644 --- a/src/test/examples/shaking1/Shaking.java +++ b/src/test/examples/shaking1/Shaking.java
@@ -5,6 +5,7 @@ public class Shaking { public static void main(String[] args) { - System.out.println(new Used("world").method()); + String world = args.length == 0 ? "world" : null; + System.out.println(new Used(world).method()); } }
diff --git a/src/test/examples/shaking1/print-mapping-cf.ref b/src/test/examples/shaking1/print-mapping-cf.ref index a7e0b8e..8b38084 100644 --- a/src/test/examples/shaking1/print-mapping-cf.ref +++ b/src/test/examples/shaking1/print-mapping-cf.ref
@@ -1,6 +1,7 @@ shaking1.Shaking -> shaking1.Shaking: shaking1.Used -> a.a: + 1:2:void <init>(java.lang.String):12:13 -> <init> + 1:1:java.lang.String aMethodThatIsNotUsedButKept():21:21 -> aMethodThatIsNotUsedButKept + 1:2:void main(java.lang.String[]):8:9 -> main 1:1:java.lang.String method():17:17 -> a - 1:1:void main(java.lang.String[]):8:8 -> main - 1:1:void <init>(java.lang.String):12:12 -> <init> - 1:1:java.lang.String aMethodThatIsNotUsedButKept():21:21 -> aMethodThatIsNotUsedButKept \ No newline at end of file + java.lang.String name -> a \ No newline at end of file
diff --git a/src/test/examples/shaking1/print-mapping-dex.ref b/src/test/examples/shaking1/print-mapping-dex.ref index 7ba8ee8..5a9504a 100644 --- a/src/test/examples/shaking1/print-mapping-dex.ref +++ b/src/test/examples/shaking1/print-mapping-dex.ref
@@ -1,5 +1,8 @@ shaking1.Shaking -> shaking1.Shaking: shaking1.Used -> a.a: - java.lang.String method() -> a - 0:16:void main(java.lang.String[]):8:8 -> main - 0:3:void <init>(java.lang.String):12:12 -> <init> + 0:2:void <init>(java.lang.String):12:12 -> <init> + 3:5:void <init>(java.lang.String):13:13 -> <init> + 0:6:void main(java.lang.String[]):8:8 -> main + 7:21:void main(java.lang.String[]):9:9 -> main + 0:19:java.lang.String method():17:17 -> a + java.lang.String name -> a
diff --git a/src/test/examplesJava17/records/RecordLib.java b/src/test/examplesJava17/records/RecordLib.java new file mode 100644 index 0000000..7f1b149 --- /dev/null +++ b/src/test/examplesJava17/records/RecordLib.java
@@ -0,0 +1,14 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package records; + +public class RecordLib { + + record LibRecord(String data) {} + + public static Object getRecord() { + return new LibRecord("data"); + } +}
diff --git a/src/test/examplesJava17/records/RecordMain.java b/src/test/examplesJava17/records/RecordMain.java new file mode 100644 index 0000000..dcca88e --- /dev/null +++ b/src/test/examplesJava17/records/RecordMain.java
@@ -0,0 +1,16 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package records; + +public class RecordMain { + + record MainRecord(String data) {} + ; + + public static void main(String[] args) { + System.out.println(new MainRecord("main") instanceof java.lang.Record); + System.out.println(RecordLib.getRecord() instanceof java.lang.Record); + } +}
diff --git a/src/test/examplesJava17/records/RecordShrinkField.java b/src/test/examplesJava17/records/RecordShrinkField.java new file mode 100644 index 0000000..b3cd366 --- /dev/null +++ b/src/test/examplesJava17/records/RecordShrinkField.java
@@ -0,0 +1,21 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package records; + +public class RecordShrinkField { + + record Person(String name, int age, int unused) { + Person(String name, int age) { + this(name, age, -1); + } + } + + public static void main(String[] args) { + Person jane = new Person("Jane Doe", 42); + Person bob = new Person("Bob", 42); + System.out.println(jane); + System.out.println(bob); + } +}
diff --git a/src/test/java/com/android/tools/r8/ForceInline.java b/src/test/java/com/android/tools/r8/ForceInline.java deleted file mode 100644 index dfeace7..0000000 --- a/src/test/java/com/android/tools/r8/ForceInline.java +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -package com.android.tools.r8; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -@Target({ElementType.METHOD}) -public @interface ForceInline {}
diff --git a/src/test/java/com/android/tools/r8/KotlinCompilerTool.java b/src/test/java/com/android/tools/r8/KotlinCompilerTool.java index 33152f1..94ceeb4 100644 --- a/src/test/java/com/android/tools/r8/KotlinCompilerTool.java +++ b/src/test/java/com/android/tools/r8/KotlinCompilerTool.java
@@ -3,15 +3,15 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8; -import static com.android.tools.r8.ToolHelper.getKotlinC_1_4_20; +import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MAX_SUPPORTED_VERSION; import static com.android.tools.r8.ToolHelper.isWindows; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import com.android.tools.r8.TestRuntime.CfRuntime; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.ToolHelper.ProcessResult; +import com.android.tools.r8.errors.Unimplemented; import com.android.tools.r8.utils.ArrayUtils; import com.android.tools.r8.utils.FileUtils; import com.android.tools.r8.utils.structural.Ordered; @@ -30,12 +30,41 @@ public class KotlinCompilerTool { + public enum KotlinTargetVersion { + NONE(""), + JAVA_6("JAVA_6"), + JAVA_8("JAVA_8"); + + private final String folderName; + + KotlinTargetVersion(String folderName) { + this.folderName = folderName; + } + + public String getFolderName() { + return folderName; + } + + public String getJvmTargetString() { + switch (this) { + case JAVA_6: + return "1.6"; + case JAVA_8: + return "1.8"; + default: + throw new Unimplemented("JvmTarget not specified for " + this); + } + } + } + public enum KotlinCompilerVersion implements Ordered<KotlinCompilerVersion> { KOTLINC_1_3_72("kotlin-compiler-1.3.72"), KOTLINC_1_4_20("kotlin-compiler-1.4.20"), - KOTLINC_1_5_0("kotlin-compiler-1.5.0"); + KOTLINC_1_5_0("kotlin-compiler-1.5.0"), + KOTLIN_DEV("kotlin-compiler-dev"); public static final KotlinCompilerVersion MIN_SUPPORTED_VERSION = KOTLINC_1_4_20; + public static final KotlinCompilerVersion MAX_SUPPORTED_VERSION = KOTLINC_1_5_0; private final String folder; @@ -46,6 +75,10 @@ public static KotlinCompilerVersion latest() { return ArrayUtils.last(values()); } + + public KotlinCompiler getCompiler() { + return new KotlinCompiler(this); + } } public static final class KotlinCompiler { @@ -71,7 +104,7 @@ } public static KotlinCompiler latest() { - return getKotlinC_1_4_20(); + return MAX_SUPPORTED_VERSION.getCompiler(); } public Path getCompiler() { @@ -94,6 +127,30 @@ return compilerVersion; } + public Path getKotlinStdlibJar() { + Path stdLib = getFolder().resolve("kotlin-stdlib.jar"); + assert Files.exists(stdLib) : "Expected kotlin stdlib jar"; + return stdLib; + } + + public Path getKotlinReflectJar() { + Path reflectJar = getFolder().resolve("kotlin-reflect.jar"); + assert Files.exists(reflectJar) : "Expected kotlin reflect jar"; + return reflectJar; + } + + public Path getKotlinScriptRuntime() { + Path reflectJar = getFolder().resolve("kotlin-script-runtime.jar"); + assert Files.exists(reflectJar) : "Expected kotlin script runtime jar"; + return reflectJar; + } + + public Path getKotlinAnnotationJar() { + Path annotationJar = getFolder().resolve("annotations-13.0.jar"); + assert Files.exists(annotationJar) : "Expected annotation jar"; + return annotationJar; + } + @Override public String toString() { return name;
diff --git a/src/test/java/com/android/tools/r8/KotlinTestBase.java b/src/test/java/com/android/tools/r8/KotlinTestBase.java index 1696327..539fe56 100644 --- a/src/test/java/com/android/tools/r8/KotlinTestBase.java +++ b/src/test/java/com/android/tools/r8/KotlinTestBase.java
@@ -7,8 +7,8 @@ import static org.hamcrest.CoreMatchers.containsString; import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.TestRuntime.CfRuntime; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.utils.DescriptorUtils; import com.android.tools.r8.utils.FileUtils; import java.io.IOException;
diff --git a/src/test/java/com/android/tools/r8/KotlinTestParameters.java b/src/test/java/com/android/tools/r8/KotlinTestParameters.java index 4306e53..534a42c 100644 --- a/src/test/java/com/android/tools/r8/KotlinTestParameters.java +++ b/src/test/java/com/android/tools/r8/KotlinTestParameters.java
@@ -5,10 +5,13 @@ import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; import com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; +import com.google.common.collect.ImmutableList; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.function.Predicate; +import java.util.stream.Collectors; public class KotlinTestParameters { @@ -56,6 +59,8 @@ private Predicate<KotlinCompilerVersion> compilerFilter = c -> false; private Predicate<KotlinTargetVersion> targetVersionFilter = t -> false; + private boolean withDevCompiler = + System.getProperty("com.android.tools.r8.kotlincompilerdev") != null; private Builder() {} @@ -83,8 +88,13 @@ return this; } + public Builder withDevCompiler() { + this.withDevCompiler = true; + return this; + } + public Builder withAllTargetVersions() { - withTargetVersionFilter(t -> true); + withTargetVersionFilter(t -> t != KotlinTargetVersion.NONE); return this; } @@ -93,6 +103,10 @@ return this; } + public Builder withNoTargetVersion() { + return withTargetVersion(KotlinTargetVersion.NONE); + } + public Builder withCompilersStartingFromIncluding(KotlinCompilerVersion version) { withCompilerFilter(c -> c.isGreaterThanOrEqualTo(version)); return this; @@ -101,15 +115,24 @@ public KotlinTestParametersCollection build() { List<KotlinTestParameters> testParameters = new ArrayList<>(); int index = 0; - for (KotlinCompilerVersion kotlinVersion : KotlinCompilerVersion.values()) { + List<KotlinCompilerVersion> compilerVersions; + if (withDevCompiler) { + compilerVersions = ImmutableList.of(KotlinCompilerVersion.KOTLIN_DEV); + } else { + compilerVersions = + Arrays.stream(KotlinCompilerVersion.values()) + .filter(c -> c != KotlinCompilerVersion.KOTLIN_DEV && compilerFilter.test(c)) + .collect(Collectors.toList()); + } + for (KotlinCompilerVersion kotlinVersion : compilerVersions) { for (KotlinTargetVersion targetVersion : KotlinTargetVersion.values()) { // KotlinTargetVersion java 6 is deprecated from kotlinc 1.5 and forward, no need to run // tests on that target. if (targetVersion == KotlinTargetVersion.JAVA_6 - && kotlinVersion.equals(KotlinCompilerVersion.KOTLINC_1_5_0)) { + && kotlinVersion.isGreaterThanOrEqualTo(KotlinCompilerVersion.KOTLINC_1_5_0)) { continue; } - if (compilerFilter.test(kotlinVersion) && targetVersionFilter.test(targetVersion)) { + if (targetVersionFilter.test(targetVersion)) { testParameters.add( new KotlinTestParameters( new KotlinCompiler(kotlinVersion), targetVersion, index++));
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java index 188f23f..c4f152e 100644 --- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java +++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -201,6 +201,24 @@ .put( "145-alloc-tracking-stress", TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0))) + // Art in 12.0.0 beta4 will hang on this test when running on dx input. + // D8 will never generate the code introducing this (goto32 0) + // See: b/200660605 + .put( + "083-compiler-regressions", + TestCondition.match( + TestCondition.tools(DexTool.DX), + TestCondition.compilers(CompilerUnderTest.D8), + TestCondition.runtimes(DexVm.Version.V12_0_0))) + // Art in 12.0.0 beta4 will hang on this test when running on dx input. + // D8 will never generate the code introducing this (goto32 0) + // See: b/200660605 + .put( + "121-simple-suspend-check", + TestCondition.match( + TestCondition.tools(DexTool.DX), + TestCondition.compilers(CompilerUnderTest.D8), + TestCondition.runtimes(DexVm.Version.V12_0_0))) .build(); // Tests that are flaky with the Art version we currently use.
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java index d245c58..2233484 100644 --- a/src/test/java/com/android/tools/r8/R8TestBuilder.java +++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -405,16 +405,6 @@ "-neverinline class * { @" + annotationPackageName + ".NeverInline *; }"); } - public T enableForceInliningAnnotations() { - return addForceInliningAnnotations() - .enableForceInliningAnnotations(ForceInline.class.getPackage().getName()); - } - - public T enableForceInliningAnnotations(String annotationPackageName) { - return addInternalKeepRules( - "-forceinline class * { @" + annotationPackageName + ".ForceInline *; }"); - } - public T enableNeverSingleCallerInlineAnnotations() { return addNeverSingleCallerInlineAnnotations() .addInternalKeepRules(
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java index 1fda6a4..e3c86ad 100644 --- a/src/test/java/com/android/tools/r8/TestBase.java +++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -17,10 +17,10 @@ import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer; import com.android.tools.r8.DataResourceProvider.Visitor; import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.TestRuntime.CfRuntime; import com.android.tools.r8.ToolHelper.ArtCommandBuilder; import com.android.tools.r8.ToolHelper.DexVm; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.ToolHelper.ProcessResult; import com.android.tools.r8.cf.CfVersion; import com.android.tools.r8.code.Instruction; @@ -1153,9 +1153,7 @@ * specified class and add rules to inline methods with the inlining annotation. */ public static String keepMainProguardConfigurationWithInliningAnnotation(Class<?> clazz) { - return "-forceinline class * { @com.android.tools.r8.ForceInline *; }" - + System.lineSeparator() - + "-neverinline class * { @com.android.tools.r8.NeverInline *; }" + return "-neverinline class * { @com.android.tools.r8.NeverInline *; }" + System.lineSeparator() + keepMainProguardConfiguration(clazz); }
diff --git a/src/test/java/com/android/tools/r8/TestBuilder.java b/src/test/java/com/android/tools/r8/TestBuilder.java index 656955e..aec53db 100644 --- a/src/test/java/com/android/tools/r8/TestBuilder.java +++ b/src/test/java/com/android/tools/r8/TestBuilder.java
@@ -190,7 +190,6 @@ return ImmutableList.of( AlwaysInline.class, AssumeMayHaveSideEffects.class, - ForceInline.class, KeepConstantArguments.class, KeepUnusedArguments.class, NeverClassInline.class,
diff --git a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java index fe6cc31..4004a47 100644 --- a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java +++ b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
@@ -395,10 +395,6 @@ return addTestingAnnotation(KeepConstantArguments.class); } - public final T addForceInliningAnnotations() { - return addTestingAnnotation(ForceInline.class); - } - public final T addInliningAnnotations() { return addTestingAnnotation(NeverInline.class); }
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java index ec57f95..14db34c 100644 --- a/src/test/java/com/android/tools/r8/ToolHelper.java +++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -3,9 +3,6 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8; -import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_3_72; -import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_4_20; -import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_5_0; import static com.android.tools.r8.utils.FileUtils.CLASS_EXTENSION; import static com.android.tools.r8.utils.FileUtils.JAVA_EXTENSION; import static com.android.tools.r8.utils.FileUtils.isDexFile; @@ -14,12 +11,10 @@ import static org.junit.Assert.fail; import com.android.tools.r8.DeviceRunner.DeviceRunnerConfigurationException; -import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; import com.android.tools.r8.TestBase.Backend; import com.android.tools.r8.TestRuntime.CfRuntime; import com.android.tools.r8.ToolHelper.DexVm.Kind; import com.android.tools.r8.dex.ApplicationReader; -import com.android.tools.r8.errors.Unimplemented; import com.android.tools.r8.errors.Unreachable; import com.android.tools.r8.graph.AppView; import com.android.tools.r8.graph.AssemblyWriter; @@ -895,34 +890,6 @@ throw new Unreachable("Unable to find a most recent android.jar"); } - public static Path getKotlinStdlibJar(KotlinCompiler kotlinc) { - Path stdLib = kotlinc.getFolder().resolve("kotlin-stdlib.jar"); - assert Files.exists(stdLib) : "Expected kotlin stdlib jar"; - return stdLib; - } - - public static Path getKotlinReflectJar(KotlinCompiler kotlinc) { - Path reflectJar = kotlinc.getFolder().resolve("kotlin-reflect.jar"); - assert Files.exists(reflectJar) : "Expected kotlin reflect jar"; - return reflectJar; - } - - public static Path getKotlinScriptRuntime(KotlinCompiler kotlinc) { - Path reflectJar = kotlinc.getFolder().resolve("kotlin-script-runtime.jar"); - assert Files.exists(reflectJar) : "Expected kotlin script runtime jar"; - return reflectJar; - } - - public static Path getKotlinAnnotationJar(KotlinCompiler kotlinc) { - Path annotationJar = kotlinc.getFolder().resolve("annotations-13.0.jar"); - assert Files.exists(annotationJar) : "Expected annotation jar"; - return annotationJar; - } - - public static Path getMostRecentKotlinAnnotationJar() { - return getKotlinAnnotationJar(KotlinCompiler.latest()); - } - public static Path getJdwpTestsCfJarPath(AndroidApiLevel minSdk) { if (minSdk.getLevel() >= AndroidApiLevel.N.getLevel()) { return Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar"); @@ -2206,49 +2173,7 @@ options, null); } - - public enum KotlinTargetVersion { - JAVA_6("JAVA_6"), - JAVA_8("JAVA_8"); - - private final String folderName; - - KotlinTargetVersion(String folderName) { - this.folderName = folderName; - } - - public String getFolderName() { - return folderName; - } - - public String getJvmTargetString() { - switch (this) { - case JAVA_6: - return "1.6"; - case JAVA_8: - return "1.8"; - default: - throw new Unimplemented("JvmTarget not specified for " + this); - } - } - } - - public static KotlinCompiler getKotlinC_1_3_72() { - return new KotlinCompiler(KOTLINC_1_3_72); - } - - public static KotlinCompiler getKotlinC_1_4_20() { - return new KotlinCompiler(KOTLINC_1_4_20); - } - - public static KotlinCompiler getKotlinC_1_5_0() { - return new KotlinCompiler(KOTLINC_1_5_0); - } - - public static KotlinCompiler[] getKotlinCompilers() { - return new KotlinCompiler[] {getKotlinC_1_3_72(), getKotlinC_1_4_20(), getKotlinC_1_5_0()}; - } - + public static void disassemble(AndroidApp app, PrintStream ps) throws IOException { DexApplication application = new ApplicationReader(app, new InternalOptions(), Timing.empty()).read().toDirect();
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java index 19c8015..29e44c0 100644 --- a/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java +++ b/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java
@@ -113,7 +113,7 @@ MethodSignature barMethodSignatureAfterArgumentRemoval = enableUnusedArgumentRemoval - ? new MethodSignature("bara", STRING, ImmutableList.of()) + ? new MethodSignature("bar$1", STRING, ImmutableList.of()) : new MethodSignature("bar", STRING, ImmutableList.of("int")); assertPublic(inspector, A.class, new MethodSignature("baz", STRING, ImmutableList.of())); assertPublic(inspector, A.class, new MethodSignature("bar", STRING, ImmutableList.of()));
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 8540d13..14b6376 100644 --- a/src/test/java/com/android/tools/r8/annotations/SourceDebugExtensionTest.java +++ b/src/test/java/com/android/tools/r8/annotations/SourceDebugExtensionTest.java
@@ -5,20 +5,18 @@ package com.android.tools.r8.annotations; import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinCompilers; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import com.android.tools.r8.CompilationFailedException; import com.android.tools.r8.CompilationMode; import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; +import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestRuntime; import com.android.tools.r8.TestRuntime.CfRuntime; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.retrace.KotlinInlineFunctionRetraceTest; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.codeinspector.AnnotationSubject; @@ -37,25 +35,28 @@ public class SourceDebugExtensionTest extends TestBase { private final TestParameters parameters; - private final KotlinCompiler kotlinCompiler; + private final KotlinTestParameters kotlinTestParameters; @Parameters(name = "{0}, kotlinc: {1}") public static List<Object[]> data() { return buildParameters( - getTestParameters().withAllRuntimesAndApiLevels().build(), getKotlinCompilers()); + getTestParameters().withAllRuntimesAndApiLevels().build(), + getKotlinTestParameters().withAllCompilersAndTargetVersions().build()); } - public SourceDebugExtensionTest(TestParameters parameters, KotlinCompiler kotlinCompiler) { + public SourceDebugExtensionTest( + TestParameters parameters, KotlinTestParameters kotlinTestParameters) { this.parameters = parameters; - this.kotlinCompiler = kotlinCompiler; + this.kotlinTestParameters = kotlinTestParameters; } @Test public void testR8() throws IOException, CompilationFailedException, ExecutionException { CfRuntime cfRuntime = parameters.isCfRuntime() ? parameters.getRuntime().asCf() : TestRuntime.getCheckedInJdk9(); + KotlinCompiler kotlinc = kotlinTestParameters.getCompiler(); Path kotlinSources = - kotlinc(cfRuntime, getStaticTemp(), kotlinCompiler, KotlinTargetVersion.JAVA_8) + kotlinc(cfRuntime, getStaticTemp(), kotlinc, KotlinTargetVersion.JAVA_8) .addSourceFiles( getFilesInTestFolderRelativeToClass( KotlinInlineFunctionRetraceTest.class, "kt", ".kt")) @@ -63,8 +64,7 @@ CodeInspector kotlinInspector = new CodeInspector(kotlinSources); inspectSourceDebugExtension(kotlinInspector); testForR8(parameters.getBackend()) - .addClasspathFiles( - getKotlinStdlibJar(kotlinCompiler), getKotlinAnnotationJar(kotlinCompiler)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(kotlinSources) .addKeepAttributes(ProguardKeepAttributes.SOURCE_DEBUG_EXTENSION) .addKeepAllClassesRule()
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 3dd6878..d5e17f4 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
@@ -3,14 +3,14 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.cf.bootstrap; -import static com.android.tools.r8.ToolHelper.getKotlinCompilers; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static org.junit.Assert.assertTrue; import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; +import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; import com.android.tools.r8.ToolHelper; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.internal.CompilationTestBase; import com.android.tools.r8.utils.AndroidApp; import com.android.tools.r8.utils.DescriptorUtils; @@ -38,28 +38,34 @@ private static final int MAX_SIZE = (int) (31361268 * 0.4); private final TestParameters parameters; - private final KotlinCompiler kotlinCompiler; + private final KotlinTestParameters kotlinTestParameters; @Parameters(name = "{0}, kotlinc: {1}") public static List<Object[]> data() { - return buildParameters(getTestParameters().withCfRuntimes().build(), getKotlinCompilers()); + return buildParameters( + getTestParameters().withCfRuntimes().build(), + getKotlinTestParameters().withAllCompilersAndTargetVersions().build()); } - public KotlinCompilerTreeShakingTest(TestParameters parameters, KotlinCompiler kotlinCompiler) { + public KotlinCompilerTreeShakingTest( + TestParameters parameters, KotlinTestParameters kotlinTestParameters) { this.parameters = parameters; - this.kotlinCompiler = kotlinCompiler; + this.kotlinTestParameters = kotlinTestParameters; } @Test public void testForRuntime() throws Exception { // Compile Hello.kt and make sure it works as expected. Path classPathBefore = - kotlinc(parameters.getRuntime().asCf(), kotlinCompiler, KotlinTargetVersion.JAVA_8) + kotlinc( + parameters.getRuntime().asCf(), + kotlinTestParameters.getCompiler(), + kotlinTestParameters.getTargetVersion()) .addSourceFiles(HELLO_KT) .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinCompiler)) + .addRunClasspathFiles(kotlinTestParameters.getCompiler().getKotlinStdlibJar()) .addClasspath(classPathBefore) .run(parameters.getRuntime(), PKG_NAME + ".HelloKt") .assertSuccessWithOutputLines("I'm Woody. Howdy, howdy, howdy."); @@ -73,17 +79,18 @@ @Test public void test() throws Exception { + KotlinCompiler kotlinc = kotlinTestParameters.getCompiler(); List<Path> libs = ImmutableList.of( - ToolHelper.getKotlinStdlibJar(kotlinCompiler), - ToolHelper.getKotlinReflectJar(kotlinCompiler), - ToolHelper.getKotlinScriptRuntime(kotlinCompiler)); + kotlinc.getKotlinStdlibJar(), + kotlinc.getKotlinReflectJar(), + kotlinc.getKotlinScriptRuntime()); // Process kotlin-compiler.jar. Path r8ProcessedKotlinc = testForR8(parameters.getBackend()) .addLibraryFiles(libs) .addLibraryFiles(ToolHelper.getJava8RuntimeJar()) - .addProgramFiles(kotlinCompiler.getCompiler()) + .addProgramFiles(kotlinc.getCompiler()) .addKeepAttributes("*Annotation*") .addKeepClassAndMembersRules(ToolHelper.K2JVMCompiler) .addKeepClassAndMembersRules("**.K2JVMCompilerArguments") @@ -120,13 +127,13 @@ kotlinc( parameters.getRuntime().asCf(), new KotlinCompiler( - "r8ProcessedKotlinc", r8ProcessedKotlinc, kotlinCompiler.getCompilerVersion()), + "r8ProcessedKotlinc", r8ProcessedKotlinc, kotlinc.getCompilerVersion()), KotlinTargetVersion.JAVA_8) .addSourceFiles(HELLO_KT) .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinCompiler)) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar()) .addClasspath(classPathAfter) .run(parameters.getRuntime(), PKG_NAME + ".HelloKt") .assertSuccessWithOutputLines("I'm Woody. Howdy, howdy, howdy.");
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java index e0c6c9e..06bfb5b 100644 --- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java +++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
@@ -38,8 +38,7 @@ .enableNoHorizontalClassMergingAnnotations() .setMinApi(parameters.getApiLevel()) .run(parameters.getRuntime(), Main.class) - .assertSuccessWithOutputLines( - "changed", "13", "42", "foo", "7", "foo", "print a", "print b") + .assertSuccessWithOutputLines("changed", "0", "42", "foo", "7", "foo", "print a", "print b") .inspect( codeInspector -> { ClassSubject changedClassSubject = codeInspector.clazz(Changed.class); @@ -118,7 +117,7 @@ public static class Main { public static void main(String[] args) { Parent p = new Changed(); - A a = new A(13); + A a = new A(args.length); a = new A(p); B b = new B(p); a.print();
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentConstructorsWithClassIdAndExtraNullsMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentConstructorsWithClassIdAndExtraNullsMergingTest.java index 3917d56..6094157 100644 --- a/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentConstructorsWithClassIdAndExtraNullsMergingTest.java +++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentConstructorsWithClassIdAndExtraNullsMergingTest.java
@@ -75,14 +75,14 @@ isPresent()); }) .run(parameters.getRuntime(), Main.class) - .assertSuccessWithOutputLines("C", "42", "C", "D"); + .assertSuccessWithOutputLines("C", "0", "C", "D"); } static class Main { public static void main(String[] args) { System.out.println(new A(new C())); - System.out.println(new A(new C(), 42)); + System.out.println(new A(new C(), args.length)); System.out.println(new B(new D())); } }
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java index dd9ab2a..9b45774 100644 --- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java +++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java
@@ -30,7 +30,7 @@ .enableNeverClassInliningAnnotations() .setMinApi(parameters.getApiLevel()) .run(parameters.getRuntime(), Main.class) - .assertSuccessWithOutputLines("foo", "B", "bar", "5", "foobar") + .assertSuccessWithOutputLines("foo", "B", "bar", "0", "foobar") .inspect( codeInspector -> { assertThat(codeInspector.clazz(A.class), isAbsent()); @@ -56,7 +56,7 @@ a.foo(); B b = a.get("B"); b.bar(); - C c = new C(5); + C c = new C(args.length); c.foobar(); } }
diff --git a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java index 3b35a12..8f4273f 100644 --- a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java +++ b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java
@@ -635,13 +635,14 @@ .addKeepRules( getProguardConfig( EXAMPLE_KEEP, - "-forceinline class classmerging.ProguardMethodMapTest$A { public void" + "-alwaysinline class classmerging.ProguardMethodMapTest$A { public void" + " method(); }")) .addOptionsModification(this::configure) .addOptionsModification( options -> { options.enableVerticalClassMerging = false; - options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE); + options.testing.validInliningReasons = + ImmutableSet.of(Reason.ALWAYS, Reason.FORCE); }) .allowUnusedProguardConfigurationRules(), main, @@ -675,12 +676,13 @@ .addKeepRules( getProguardConfig( EXAMPLE_KEEP, - "-forceinline class classmerging.ProguardMethodMapTest$A { public void" + "-alwaysinline class classmerging.ProguardMethodMapTest$A { public void" + " method(); }")) .addOptionsModification(this::configure) .addOptionsModification( options -> { - options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE); + options.testing.validInliningReasons = + ImmutableSet.of(Reason.ALWAYS, Reason.FORCE); }) .allowUnusedProguardConfigurationRules(), main,
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinStdLibCompilationTest.java b/src/test/java/com/android/tools/r8/debug/KotlinStdLibCompilationTest.java index eebed6b..f93bfb4 100644 --- a/src/test/java/com/android/tools/r8/debug/KotlinStdLibCompilationTest.java +++ b/src/test/java/com/android/tools/r8/debug/KotlinStdLibCompilationTest.java
@@ -3,15 +3,13 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.debug; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinCompilers; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assume.assumeTrue; import com.android.tools.r8.CompilationFailedException; import com.android.tools.r8.CompilationMode; import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestDiagnosticMessages; import com.android.tools.r8.TestParameters; @@ -26,33 +24,35 @@ public class KotlinStdLibCompilationTest extends TestBase { private final TestParameters parameters; - private final KotlinCompiler kotlinc; + private final KotlinTestParameters kotlinTestParameters; @Parameters(name = "{0}, kotlinc: {1}") public static List<Object[]> setup() { return buildParameters( TestParametersBuilder.builder().withAllRuntimesAndApiLevels().build(), - getKotlinCompilers()); + getKotlinTestParameters().withAllCompilers().withNoTargetVersion().build()); } - public KotlinStdLibCompilationTest(TestParameters parameters, KotlinCompiler kotlinc) { + public KotlinStdLibCompilationTest( + TestParameters parameters, KotlinTestParameters kotlinTestParameters) { this.parameters = parameters; - this.kotlinc = kotlinc; + this.kotlinTestParameters = kotlinTestParameters; } @Test public void testD8() throws CompilationFailedException { assumeTrue(parameters.isDexRuntime()); testForD8() - .addProgramFiles(getKotlinStdlibJar(kotlinc)) + .addProgramFiles(kotlinTestParameters.getCompiler().getKotlinStdlibJar()) .setMinApi(parameters.getApiLevel()) .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages); } @Test public void testR8() throws CompilationFailedException { + KotlinCompiler compiler = kotlinTestParameters.getCompiler(); testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(compiler.getKotlinStdlibJar(), compiler.getKotlinAnnotationJar()) .addKeepAllAttributes() .allowDiagnosticWarningMessages() .noMinification()
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 c10af51..b0c3032 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
@@ -15,6 +15,7 @@ import com.android.tools.r8.D8TestRunResult; import com.android.tools.r8.DexIndexedConsumer.ArchiveConsumer; +import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; import com.android.tools.r8.KotlinTestBase.KotlinCompileMemoizer; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.R8FullTestBuilder; @@ -51,6 +52,7 @@ private final TestParameters parameters; private final KotlinTestParameters kotlinParameters; + private final KotlinCompiler kotlinc; private final boolean shrinkDesugaredLibrary; @Parameters(name = "{0}, {1}, shrinkDesugaredLibrary: {2}") @@ -67,6 +69,7 @@ boolean shrinkDesugaredLibrary) { this.parameters = parameters; this.kotlinParameters = kotlinParameters; + this.kotlinc = kotlinParameters.getCompiler(); this.shrinkDesugaredLibrary = shrinkDesugaredLibrary; } @@ -83,8 +86,8 @@ assumeTrue(parameters.getRuntime().isCf()); testForRuntime(parameters) .addProgramFiles(compiledJars.getForConfiguration(kotlinParameters)) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinParameters.getCompiler())) - .addProgramFiles(ToolHelper.getKotlinReflectJar(kotlinParameters.getCompiler())) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) + .addProgramFiles(kotlinc.getKotlinReflectJar()) .run(parameters.getRuntime(), PKG + ".MainKt") .assertSuccessWithOutputLines(EXPECTED_OUTPUT); } @@ -98,8 +101,8 @@ testForD8() .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P)) .addProgramFiles(compiledJars.getForConfiguration(kotlinParameters)) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinParameters.getCompiler())) - .addProgramFiles(ToolHelper.getKotlinReflectJar(kotlinParameters.getCompiler())) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) + .addProgramFiles(kotlinc.getKotlinReflectJar()) .setProgramConsumer(new ArchiveConsumer(output.toPath(), true)) .setMinApi(parameters.getApiLevel()) .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer) @@ -128,9 +131,9 @@ testForR8(parameters.getBackend()) .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P)) .addProgramFiles(compiledJars.getForConfiguration(kotlinParameters)) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinParameters.getCompiler())) - .addProgramFiles(ToolHelper.getKotlinReflectJar(kotlinParameters.getCompiler())) - .addProgramFiles(ToolHelper.getKotlinAnnotationJar(kotlinParameters.getCompiler())) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) + .addProgramFiles(kotlinc.getKotlinReflectJar()) + .addProgramFiles(kotlinc.getKotlinAnnotationJar()) .addKeepMainRule(PKG + ".MainKt") .addKeepAllClassesRule() .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
diff --git a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaPrivateInstanceInterfaceMethodWithNonLambdaCallSiteTest.java b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaPrivateInstanceInterfaceMethodWithNonLambdaCallSiteTest.java index 7d0b2fa..6961fe9 100644 --- a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaPrivateInstanceInterfaceMethodWithNonLambdaCallSiteTest.java +++ b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaPrivateInstanceInterfaceMethodWithNonLambdaCallSiteTest.java
@@ -4,6 +4,8 @@ package com.android.tools.r8.desugar.lambdas; +import static org.junit.Assert.assertFalse; + import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestParametersCollection; @@ -41,7 +43,21 @@ .addProgramClasses(Main.class, A.class, FunctionalInterface.class) .addProgramClassFileData(getProgramClassFileData()) .run(parameters.getRuntime(), Main.class) - .assertSuccessWithOutputLines("Hello world!", "Hello world!"); + .assertSuccessWithOutputLines("Hello world!", "Hello world!") + .inspect( + inspector -> { + if (parameters.isDexRuntime() + && !parameters.canUseDefaultAndStaticInterfaceMethods()) { + inspector + .clazz(I.class) + .toCompanionClass() + .forAllMethods( + m -> + // We don't expect any synthetic accessors to be needed for the private + // interface method. + assertFalse("Unexpected synthetic method: " + m, m.isSynthetic())); + } + }); } @Test
diff --git a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaWithPrivateInterfaceInvokeTest.java b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaWithPrivateInterfaceInvokeTest.java new file mode 100644 index 0000000..d66b1d2 --- /dev/null +++ b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaWithPrivateInterfaceInvokeTest.java
@@ -0,0 +1,114 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +package com.android.tools.r8.desugar.lambdas; + +import static org.junit.Assert.assertEquals; + +import com.android.tools.r8.TestBase; +import com.android.tools.r8.TestParameters; +import com.android.tools.r8.TestRuntime.CfVm; +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.objectweb.asm.Opcodes; + +@RunWith(Parameterized.class) +public class LambdaWithPrivateInterfaceInvokeTest extends TestBase { + + static final String EXPECTED = StringUtils.lines("Hello world"); + + private final TestParameters parameters; + private final boolean useInvokeSpecial; + + @Parameterized.Parameters(name = "{0}, invokespecial:{1}") + public static List<Object[]> data() { + return buildParameters( + getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values()); + } + + public LambdaWithPrivateInterfaceInvokeTest(TestParameters parameters, boolean useInvokeSpecial) { + this.parameters = parameters; + this.useInvokeSpecial = useInvokeSpecial; + } + + @Test + public void testReference() throws Exception { + testForRuntime(parameters) + .addProgramClasses(TestClass.class, MyFun.class, A.class) + .addProgramClassFileData(getTransformForI()) + .run(parameters.getRuntime(), TestClass.class) + // On JDK 8 and 9 the VM will fail if not targeting with invoke special. + .applyIf( + !useInvokeSpecial + && parameters.isCfRuntime() + && parameters.asCfRuntime().isOlderThan(CfVm.JDK11), + r -> r.assertFailureWithErrorThatThrows(IncompatibleClassChangeError.class), + r -> r.assertSuccessWithOutput(EXPECTED)); + } + + @Test + public void testR8() throws Exception { + testForR8(parameters.getBackend()) + .addProgramClasses(TestClass.class, MyFun.class, A.class) + .addProgramClassFileData(getTransformForI()) + .addKeepMainRule(TestClass.class) + .setMinApi(parameters.getApiLevel()) + .run(parameters.getRuntime(), TestClass.class) + .assertSuccessWithOutput(EXPECTED); + } + + private byte[] getTransformForI() throws Exception { + return transformer(I.class) + .setPrivate(I.class.getDeclaredMethod("bar")) + .transformMethodInsnInMethod( + "lambda$foo$0", + (opcode, owner, name, descriptor, isInterface, visitor) -> { + if (name.equals("bar")) { + assertEquals(Opcodes.INVOKEINTERFACE, opcode); + visitor.visitMethodInsn( + useInvokeSpecial ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEINTERFACE, + owner, + name, + descriptor, + isInterface); + } else { + visitor.visitMethodInsn(opcode, owner, name, descriptor, isInterface); + } + }) + .transform(); + } + + interface I { + /* private */ default String bar() { + return "Hello world"; + } + + default void foo() { + TestClass.run( + () -> { + System.out.println(bar()); + }); + } + } + + interface MyFun { + void run(); + } + + static class A implements I {} + + static class TestClass { + + public static void run(MyFun fn) { + fn.run(); + } + + public static void main(String[] args) { + new A().foo(); + } + } +}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java index 4ea7cd7..2446b14 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.desugar.records; -import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF; import static com.android.tools.r8.utils.InternalOptions.TestingOptions; import com.android.tools.r8.R8FullTestBuilder; @@ -70,11 +69,12 @@ .addProgramClassFileData(PROGRAM_DATA) .setMinApi(parameters.getApiLevel()) .addKeepRules("-keep class records.EmptyRecordAnnotation { *; }") + .addKeepRules("-keepattributes *Annotation*") + .addKeepRules("-keep class records.EmptyRecordAnnotation$Empty") .addKeepMainRule(MAIN_TYPE) .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); if (parameters.isCfRuntime()) { builder - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .compile() .inspect(RecordTestUtils::assertRecordsAreRecords) @@ -84,8 +84,6 @@ return; } builder - .addKeepRules("-keepattributes *Annotation*") - .addKeepRules("-keep class records.EmptyRecordAnnotation$Empty") .addKeepRules("-keep class java.lang.Record") .run(parameters.getRuntime(), MAIN_TYPE) .assertSuccessWithOutput(EXPECTED_RESULT_DEX);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java index effcba3..7a64c3c 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.desugar.records; -import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF; import static com.android.tools.r8.utils.InternalOptions.TestingOptions; import com.android.tools.r8.R8FullTestBuilder; @@ -23,7 +22,8 @@ private static final String RECORD_NAME = "EmptyRecord"; private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME); private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME); - private static final String EXPECTED_RESULT = StringUtils.lines("Empty[]"); + private static final String EXPECTED_RESULT_D8 = StringUtils.lines("Empty[]"); + private static final String EXPECTED_RESULT_R8 = StringUtils.lines("a[]"); private final TestParameters parameters; @@ -48,7 +48,7 @@ testForJvm() .addProgramClassFileData(PROGRAM_DATA) .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_D8); } testForD8(parameters.getBackend()) .addProgramClassFileData(PROGRAM_DATA) @@ -56,7 +56,7 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) .compile() .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_D8); } @Test @@ -69,14 +69,13 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); if (parameters.isCfRuntime()) { builder - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .compile() .inspect(RecordTestUtils::assertRecordsAreRecords) .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_R8); return; } - builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT); + builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT_R8); } }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java index d4da59e..1c32b27 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.desugar.records; -import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF; - import com.android.tools.r8.R8FullTestBuilder; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; @@ -69,7 +67,6 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); if (parameters.isCfRuntime()) { builder - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .compile() .inspect(RecordTestUtils::assertRecordsAreRecords)
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java index 2d771cc..9ee21d2 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
@@ -22,7 +22,7 @@ private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME); private static final String EXPECTED_RESULT = StringUtils.lines( - "Empty[]", + "%s[]", "true", "true", "true", @@ -33,7 +33,10 @@ "true", "false", "false", - "Person[name=Jane Doe, age=42]"); + "%s[name=Jane Doe, age=42]"); + private static final String EXPECTED_RESULT_D8 = + String.format(EXPECTED_RESULT, "Empty", "Person"); + private static final String EXPECTED_RESULT_R8 = String.format(EXPECTED_RESULT, "a", "b"); private final TestParameters parameters; @@ -62,7 +65,7 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) .compile() .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_D8); } @Test @@ -81,6 +84,6 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) .compile() .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_R8); } }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java index 1fc2f3e..228275b 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.desugar.records; -import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF; - import com.android.tools.r8.R8FullTestBuilder; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; @@ -25,7 +23,7 @@ private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME); private static final String EXPECTED_RESULT = StringUtils.lines( - "Empty[]", + "%s[]", "true", "true", "true", @@ -36,7 +34,10 @@ "true", "false", "false", - "Person[name=Jane Doe, age=42]"); + "%s[name=Jane Doe, age=42]"); + private static final String EXPECTED_RESULT_D8 = + String.format(EXPECTED_RESULT, "Empty", "Person"); + private static final String EXPECTED_RESULT_R8 = String.format(EXPECTED_RESULT, "a", "b"); private final TestParameters parameters; @@ -61,7 +62,7 @@ testForJvm() .addProgramClassFileData(PROGRAM_DATA) .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_D8); } testForD8(parameters.getBackend()) .addProgramClassFileData(PROGRAM_DATA) @@ -69,7 +70,7 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) .compile() .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_D8); } @Test @@ -82,14 +83,13 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); if (parameters.isCfRuntime()) { builder - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .compile() .inspect(RecordTestUtils::assertRecordsAreRecords) .run(parameters.getRuntime(), MAIN_TYPE) - .assertSuccessWithOutput(EXPECTED_RESULT); + .assertSuccessWithOutput(EXPECTED_RESULT_R8); return; } - builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT); + builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT_R8); } }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordLibMergeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordLibMergeTest.java new file mode 100644 index 0000000..7c32b98 --- /dev/null +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordLibMergeTest.java
@@ -0,0 +1,79 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.desugar.records; + +import com.android.tools.r8.R8FullTestBuilder; +import com.android.tools.r8.TestBase; +import com.android.tools.r8.TestParameters; +import com.android.tools.r8.TestRuntime.CfRuntime; +import com.android.tools.r8.utils.InternalOptions.TestingOptions; +import com.android.tools.r8.utils.StringUtils; +import java.nio.file.Path; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class RecordLibMergeTest extends TestBase { + + private static final String RECORD_LIB = "RecordLib"; + private static final String RECORD_MAIN = "RecordMain"; + private static final byte[][] PROGRAM_DATA_LIB = RecordTestUtils.getProgramData(RECORD_LIB); + private static final byte[][] PROGRAM_DATA_MAIN = RecordTestUtils.getProgramData(RECORD_MAIN); + private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_MAIN); + private static final String EXPECTED_RESULT = StringUtils.lines("true", "true"); + + private final TestParameters parameters; + + public RecordLibMergeTest(TestParameters parameters) { + this.parameters = parameters; + } + + @Parameterized.Parameters(name = "{0}") + public static List<Object[]> data() { + // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk17). + return buildParameters( + getTestParameters() + .withCustomRuntime(CfRuntime.getCheckedInJdk17()) + .withDexRuntimes() + .withAllApiLevelsAlsoForCf() + .build()); + } + + @Test + public void testR8Merge() throws Exception { + Path lib = + testForR8(Backend.CF) + .addProgramClassFileData(PROGRAM_DATA_LIB) + .setMinApi(parameters.getApiLevel()) + .addKeepRules( + "-keep class records.RecordLib { public static java.lang.Object getRecord(); }") + .addKeepRules("-keep class records.RecordLib$LibRecord") + .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) + .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .compile() + .writeToZip(); + R8FullTestBuilder builder = + testForR8(parameters.getBackend()) + .addProgramFiles(lib) + .addProgramClassFileData(PROGRAM_DATA_MAIN) + .setMinApi(parameters.getApiLevel()) + .addKeepMainRule(MAIN_TYPE) + .addKeepRules("-keep class records.RecordLib$LibRecord") + .addKeepRules("-keep class records.RecordMain$MainRecord") + .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); + if (parameters.isCfRuntime()) { + builder + .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) + .compile() + .inspect(RecordTestUtils::assertRecordsAreRecords) + .run(parameters.getRuntime(), MAIN_TYPE) + .assertSuccessWithOutput(EXPECTED_RESULT); + return; + } + builder.run(parameters.getRuntime(), MAIN_TYPE).assertSuccessWithOutput(EXPECTED_RESULT); + } +}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java index 7af5f41..8401196 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
@@ -8,6 +8,7 @@ import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestRuntime.CfRuntime; +import com.android.tools.r8.utils.BooleanUtils; import com.android.tools.r8.utils.InternalOptions.TestingOptions; import com.android.tools.r8.utils.StringUtils; import java.nio.file.Path; @@ -33,12 +34,14 @@ StringUtils.lines("Jane Doe", "42", "Jane Doe", "42"); private final TestParameters parameters; + private final boolean intermediate; - public RecordMergeTest(TestParameters parameters) { + public RecordMergeTest(TestParameters parameters, boolean intermediate) { this.parameters = parameters; + this.intermediate = intermediate; } - @Parameterized.Parameters(name = "{0}") + @Parameterized.Parameters(name = "{0}, intermediate: {1}") public static List<Object[]> data() { // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk17). return buildParameters( @@ -46,7 +49,8 @@ .withCustomRuntime(CfRuntime.getCheckedInJdk17()) .withDexRuntimes() .withAllApiLevelsAlsoForCf() - .build()); + .build(), + BooleanUtils.values()); } @Test @@ -56,6 +60,7 @@ .addProgramClassFileData(PROGRAM_DATA_1) .setMinApi(parameters.getApiLevel()) .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .setIntermediate(intermediate) .compile() .writeToZip(); Path output2 = @@ -63,6 +68,7 @@ .addProgramClassFileData(PROGRAM_DATA_2) .setMinApi(parameters.getApiLevel()) .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .setIntermediate(intermediate) .compile() .writeToZip(); D8TestCompileResult result = @@ -82,6 +88,7 @@ .addProgramClassFileData(PROGRAM_DATA_1) .setMinApi(parameters.getApiLevel()) .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .setIntermediate(intermediate) .compile() .writeToZip(); D8TestCompileResult result =
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java index a1fc48e..a3df3b5 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMethods.java
@@ -11,13 +11,13 @@ public class RecordMethods { public static String toString( - Object[] recordFieldsAsObjects, String simpleName, String fieldNames) { + Object[] recordFieldsValues, Class<?> recordClass, String fieldNames) { // Example: "Person[name=Jane Doe, age=42]" String[] fieldNamesSplit = fieldNames.isEmpty() ? new String[0] : fieldNames.split(";"); StringBuilder builder = new StringBuilder(); - builder.append(simpleName).append("["); + builder.append(recordClass.getSimpleName()).append("["); for (int i = 0; i < fieldNamesSplit.length; i++) { - builder.append(fieldNamesSplit[i]).append("=").append(recordFieldsAsObjects[i]); + builder.append(fieldNamesSplit[i]).append("=").append(recordFieldsValues[i]); if (i != fieldNamesSplit.length - 1) { builder.append(", "); }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java index 26d259a..82891db 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.desugar.records; -import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF; - import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestRuntime.CfRuntime; @@ -61,7 +59,8 @@ .addProgramClassFileData(PROGRAM_DATA) .setMinApi(parameters.getApiLevel()) .addKeepMainRule(MAIN_TYPE) - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) + .addKeepRules("-keepattributes *") + .addKeepRules("-keep class * extends java.lang.Record { private final <fields>; }") .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) .compile()
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java new file mode 100644 index 0000000..d46e947 --- /dev/null +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
@@ -0,0 +1,97 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.desugar.records; + +import static org.junit.Assert.assertEquals; + +import com.android.tools.r8.TestBase; +import com.android.tools.r8.TestParameters; +import com.android.tools.r8.utils.InternalOptions.TestingOptions; +import com.android.tools.r8.utils.StringUtils; +import com.android.tools.r8.utils.codeinspector.ClassSubject; +import com.android.tools.r8.utils.codeinspector.CodeInspector; +import java.nio.file.Path; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class RecordShrinkFieldTest extends TestBase { + + private static final String RECORD_NAME = "RecordShrinkField"; + private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME); + private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME); + private static final String EXPECTED_RESULT = + StringUtils.lines("%s[name=Jane Doe, age=42, unused=-1]", "%s[name=Bob, age=42, unused=-1]"); + private static final String EXPECTED_RESULT_D8 = + String.format(EXPECTED_RESULT, "Person", "Person"); + private static final String EXPECTED_RESULT_R8 = String.format(EXPECTED_RESULT, "a", "a"); + + private final TestParameters parameters; + + public RecordShrinkFieldTest(TestParameters parameters) { + this.parameters = parameters; + } + + @Parameterized.Parameters(name = "{0}") + public static List<Object[]> data() { + return buildParameters( + getTestParameters().withDexRuntimes().withAllApiLevelsAlsoForCf().build()); + } + + @Test + public void testD8() throws Exception { + testForD8(parameters.getBackend()) + .addProgramClassFileData(PROGRAM_DATA) + .setMinApi(parameters.getApiLevel()) + .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .compile() + .run(parameters.getRuntime(), MAIN_TYPE) + .assertSuccessWithOutput(EXPECTED_RESULT_D8); + } + + @Test + public void testR8() throws Exception { + testForR8(parameters.getBackend()) + .addProgramClassFileData(PROGRAM_DATA) + .setMinApi(parameters.getApiLevel()) + .addKeepMainRule(MAIN_TYPE) + .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .compile() + .inspect(this::assertSingleField) + .run(parameters.getRuntime(), MAIN_TYPE) + .assertSuccessWithOutput(EXPECTED_RESULT_R8); + } + + @Test + public void testR8CfThenDex() throws Exception { + Path desugared = + testForR8(Backend.CF) + .addProgramClassFileData(PROGRAM_DATA) + .setMinApi(parameters.getApiLevel()) + .addKeepMainRule(MAIN_TYPE) + .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) + .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .compile() + .writeToZip(); + testForR8(parameters.getBackend()) + .addProgramFiles(desugared) + .setMinApi(parameters.getApiLevel()) + .addKeepMainRule(MAIN_TYPE) + .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .compile() + .inspect(this::assertSingleField) + .run(parameters.getRuntime(), MAIN_TYPE) + .assertSuccessWithOutput(EXPECTED_RESULT_R8); + } + + private void assertSingleField(CodeInspector inspector) { + ClassSubject recordClass = inspector.clazz("records.a"); + assertEquals(1, recordClass.allInstanceFields().size()); + assertEquals( + "java.lang.String", recordClass.allInstanceFields().get(0).getField().type().toString()); + } +}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java index 3f8adcc..7008bfe 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
@@ -40,12 +40,6 @@ return Paths.get(ToolHelper.TESTS_BUILD_DIR, EXAMPLE_FOLDER, RECORD_FOLDER + ".jar"); } - // TODO(b/197081367): Rediscuss if we want to maintain the toString() method. - // In R8 Cf to Cf we need to maintain the record component attributes, the class name and fields - // so the mapping between the record components and fields is valid and the toString() prints - // the record as specified (including the class name). - public static final String RECORD_KEEP_RULE_R8_CF_TO_CF = - "-keepattributes *\n" + "-keep class * extends java.lang.Record { private final <fields>; }"; public static Path[] getJdk15LibraryFiles(TemporaryFolder temp) throws IOException { Assume.assumeFalse(ToolHelper.isWindows());
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java index f1fc5ae..f22f8cd 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.desugar.records; -import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF; - import com.android.tools.r8.R8FullTestBuilder; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; @@ -71,7 +69,6 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); if (parameters.isCfRuntime()) { builder - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .compile() .inspect(RecordTestUtils::assertRecordsAreRecords)
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java index 68ad95e..5e7aa9a 100644 --- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java +++ b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.desugar.records; -import static com.android.tools.r8.desugar.records.RecordTestUtils.RECORD_KEEP_RULE_R8_CF_TO_CF; import com.android.tools.r8.R8FullTestBuilder; import com.android.tools.r8.TestBase; @@ -12,7 +11,9 @@ import com.android.tools.r8.TestRuntime.CfRuntime; import com.android.tools.r8.utils.InternalOptions.TestingOptions; import com.android.tools.r8.utils.StringUtils; +import java.nio.file.Path; import java.util.List; +import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -64,6 +65,25 @@ } @Test + public void testD8Intermediate() throws Exception { + Assume.assumeTrue(parameters.isDexRuntime()); + Path path = + testForD8(Backend.DEX) + .addProgramClassFileData(PROGRAM_DATA) + .setMinApi(parameters.getApiLevel()) + .addOptionsModification(TestingOptions::allowExperimentClassFileVersion) + .setIntermediate(true) + .compile() + .writeToZip(); + testForD8() + .addProgramFiles(path) + .setMinApi(parameters.getApiLevel()) + .compile() + .run(parameters.getRuntime(), MAIN_TYPE) + .assertSuccessWithOutput(EXPECTED_RESULT); + } + + @Test public void testR8() throws Exception { R8FullTestBuilder builder = testForR8(parameters.getBackend()) @@ -73,7 +93,6 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); if (parameters.isCfRuntime()) { builder - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .compile() .inspect(RecordTestUtils::assertRecordsAreRecords) @@ -101,7 +120,6 @@ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion); if (parameters.isCfRuntime()) { builder - .addKeepRules(RECORD_KEEP_RULE_R8_CF_TO_CF) .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)) .compile() .inspect(RecordTestUtils::assertRecordsAreRecords)
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 2d89396..de13512 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
@@ -66,7 +66,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( jars.getForConfiguration(kotlinParameters), - ToolHelper.getKotlinStdlibJar(kotlinParameters.getCompiler())) + kotlinParameters.getCompiler().getKotlinStdlibJar()) .addKeepMainRule(PKG + ".MainKt") .addKeepRules(enumKeepRules.getKeepRules()) .addKeepRuntimeVisibleAnnotations()
diff --git a/src/test/java/com/android/tools/r8/graph/DexTypeTest.java b/src/test/java/com/android/tools/r8/graph/DexTypeTest.java index 83164c5..ab7fea5 100644 --- a/src/test/java/com/android/tools/r8/graph/DexTypeTest.java +++ b/src/test/java/com/android/tools/r8/graph/DexTypeTest.java
@@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.graph; +import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_3_72; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; @@ -30,7 +31,7 @@ new ApplicationReader( AndroidApp.builder() .addLibraryFiles(ToolHelper.getDefaultAndroidJar()) - .addLibraryFiles(ToolHelper.getKotlinStdlibJar(ToolHelper.getKotlinC_1_3_72())) + .addLibraryFiles(KOTLINC_1_3_72.getCompiler().getKotlinStdlibJar()) .build(), options, Timing.empty())
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureKeepAttributesTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureKeepAttributesTest.java index fe4a189..48877b9 100644 --- a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureKeepAttributesTest.java +++ b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureKeepAttributesTest.java
@@ -8,6 +8,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; +import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.graph.genericsignature.GenericSignatureKeepAttributesTest.Outer.Middle; @@ -72,6 +73,7 @@ .addKeepAttributeInnerClassesAndEnclosingMethod() .addKeepMainRule(Main.class) .addKeepClassAndMembersRules(Outer.Middle.Inner.class, Supplier.class, Predicate.class) + .enableInliningAnnotations() .run(parameters.getRuntime(), Main.class) .assertSuccessWithOutputLines(parameters.isCfRuntime() ? EXPECTED_JVM : EXPECTED_DEX) .inspect(this::inspectSignatures); @@ -146,6 +148,7 @@ return new Outer<O>.Middle<>(); } + @NeverInline public static Outer<?>.Middle<?>.Inner<Object> create() { return new Outer<>().createMiddle().createInner(); }
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureReflectiveInnerTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureReflectiveInnerTest.java index e34a36c..3c32c7b 100644 --- a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureReflectiveInnerTest.java +++ b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureReflectiveInnerTest.java
@@ -7,6 +7,7 @@ import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; +import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestParametersCollection; @@ -48,6 +49,7 @@ .addKeepAttributeInnerClassesAndEnclosingMethod() .addKeepAttributeSignature() .addKeepClassRules(Foo.Bar.class) + .enableInliningAnnotations() .setMinApi(parameters.getApiLevel()) .run(parameters.getRuntime(), Main.class) .assertSuccessWithOutputLines(EXPECTED) @@ -71,6 +73,7 @@ } } + @NeverInline public Bar<String> foo() { return new Bar<>(); }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/SubsumedCatchHandlerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/SubsumedCatchHandlerTest.java index 19d7226..3d3db4a 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/SubsumedCatchHandlerTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/SubsumedCatchHandlerTest.java
@@ -3,12 +3,12 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.ir.optimize; +import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertEquals; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.ToolHelper; @@ -42,7 +42,6 @@ System.out.print(" -> " + exitCode); } - @ForceInline private static int foo() { try { bar(); @@ -86,7 +85,6 @@ testForR8(backend) .addInnerClasses(SubsumedCatchHandlerTest.class) .addKeepMainRule(TestClass.class) - .enableForceInliningAnnotations() .enableInliningAnnotations() .run(TestClass.class) .assertSuccessWithOutput(expected) @@ -118,5 +116,7 @@ DexType guard = handler.guards.get(0); assertEquals("java.lang.Exception", guard.toSourceString()); } + + assertThat(classSubject.uniqueMethodWithName("foo"), isAbsent()); } }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/nonpublicsubtype/ClassInlineNonPublicSubtypeTest.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/nonpublicsubtype/ClassInlineNonPublicSubtypeTest.java new file mode 100644 index 0000000..4292720 --- /dev/null +++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/nonpublicsubtype/ClassInlineNonPublicSubtypeTest.java
@@ -0,0 +1,75 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +package com.android.tools.r8.ir.optimize.classinliner.nonpublicsubtype; + +import com.android.tools.r8.NeverInline; +import com.android.tools.r8.TestBase; +import com.android.tools.r8.TestParameters; +import com.android.tools.r8.TestParametersCollection; +import com.android.tools.r8.ir.optimize.classinliner.nonpublicsubtype.subpkg.Utils; +import com.android.tools.r8.utils.StringUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class ClassInlineNonPublicSubtypeTest extends TestBase { + + static final String EXPECTED = StringUtils.lines("Hello world"); + + private final TestParameters parameters; + + @Parameterized.Parameters(name = "{0}") + public static TestParametersCollection data() { + return getTestParameters().withAllRuntimesAndApiLevels().build(); + } + + public ClassInlineNonPublicSubtypeTest(TestParameters parameters) { + this.parameters = parameters; + } + + @Test + public void testReference() throws Exception { + testForRuntime(parameters) + .addInnerClasses(getClass()) + .addProgramClassesAndInnerClasses(Utils.class) + .run(parameters.getRuntime(), TestClass.class) + .assertSuccessWithOutput(EXPECTED); + } + + @Test + public void testR8() throws Exception { + testForR8(parameters.getBackend()) + .enableInliningAnnotations() + .addInnerClasses(getClass()) + .addProgramClassesAndInnerClasses(Utils.class) + .addKeepMainRule(TestClass.class) + .setMinApi(parameters.getApiLevel()) + .run(parameters.getRuntime(), TestClass.class) + .assertSuccessWithOutput(EXPECTED); + } + + public interface I { + @NeverInline + void method(); + } + + static class Accessor { + @NeverInline + static void access(I i) { + i.method(); + } + } + + static class TestClass { + + static void run() { + Accessor.access(Utils.INSTANCE); + } + + public static void main(String[] args) { + run(); + } + } +}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/nonpublicsubtype/subpkg/Utils.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/nonpublicsubtype/subpkg/Utils.java new file mode 100644 index 0000000..18c9946 --- /dev/null +++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/nonpublicsubtype/subpkg/Utils.java
@@ -0,0 +1,20 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +package com.android.tools.r8.ir.optimize.classinliner.nonpublicsubtype.subpkg; + +import com.android.tools.r8.ir.optimize.classinliner.nonpublicsubtype.ClassInlineNonPublicSubtypeTest.I; + +public class Utils { + + // Non-public class can't be accessed by the context calling 'method'. + // TODO(b/120061431): Class inlining should be able to inline this as the instance itself will be + // eliminated, but until then, it must consistently refuse to inline in case of invalid access. + public static final I INSTANCE = + new I() { + @Override + public void method() { + System.out.println("Hello world"); + } + }; +}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineLibraryInterfaceMethodTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineLibraryInterfaceMethodTest.java index 48d3203..3c76052 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineLibraryInterfaceMethodTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineLibraryInterfaceMethodTest.java
@@ -58,11 +58,9 @@ counts.println = countInvokesWithName(methodSubject, "println"); }); - // TODO(b/129044633) We expect 0 x run and 2 x println after we can inline those methods. - assertEquals(2, counts.run); - assertEquals(0, counts.println); - // TODO(b/126323172) After this issue has been fixed, add test here to check the same with - // desugared lambdas. + // TODO(b/126323172) Add test here to check the same with desugared lambdas. + assertEquals(0, counts.run); + assertEquals(2, counts.println); } private static long countInvokesWithName(MethodSubject methodSubject, String name) {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlinerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlinerTest.java index 74b2a56..db81629 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlinerTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlinerTest.java
@@ -4,11 +4,13 @@ package com.android.tools.r8.ir.optimize.inliner; +import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent; +import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; -import com.android.tools.r8.R8Command; import com.android.tools.r8.TestBase; import com.android.tools.r8.ToolHelper; import com.android.tools.r8.ToolHelper.ProcessResult; @@ -20,16 +22,12 @@ import com.android.tools.r8.ir.optimize.inliner.interfaces.InterfaceTargetsTestClass.IfaceD; import com.android.tools.r8.ir.optimize.inliner.interfaces.InterfaceTargetsTestClass.IfaceNoImpl; import com.android.tools.r8.naming.MemberNaming.MethodSignature; -import com.android.tools.r8.origin.Origin; import com.android.tools.r8.utils.AndroidApp; import com.android.tools.r8.utils.InternalOptions; 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 com.google.common.collect.ImmutableList; import java.nio.file.Path; -import java.util.Collections; -import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.Test; @@ -52,31 +50,33 @@ @Test public void testExceptionHandling() throws Exception { - String className = ExceptionHandlingTestClass.class.getName(); - AndroidApp inputApp = readClasses(ExceptionHandlingTestClass.class); - List<String> proguardConfig = - ImmutableList.of( - "-keep public class " + className + "{", - " public static void main(...);", - "}", - "-forceinline public class " + className + "{", - " private static void inlinee*(...);", - "}", - "-neverinline public class " + className + "{", - " private static void *Test(...);", - "}"); - R8Command.Builder commandBuilder = - ToolHelper.prepareR8CommandBuilder(inputApp, emptyConsumer(backend)) - .addProguardConfiguration(proguardConfig, Origin.unknown()) - .addLibraryFiles(runtimeJar(backend)); - ToolHelper.allowTestProguardOptions(commandBuilder); - AndroidApp outputApp = ToolHelper.runR8(commandBuilder.build(), this::configure); - assert backend == Backend.DEX || backend == Backend.CF; - assertEquals( - runOnJava(ExceptionHandlingTestClass.class), - backend == Backend.DEX - ? runOnArt(outputApp, className) - : runOnJava(outputApp, className, Collections.emptyList())); + testForR8(backend) + .addProgramClasses(ExceptionHandlingTestClass.class) + .addKeepMainRule(ExceptionHandlingTestClass.class) + .addOptionsModification(this::configure) + .enableInliningAnnotations() + .compile() + .inspect( + inspector -> { + ClassSubject mainClassSubject = inspector.clazz(ExceptionHandlingTestClass.class); + assertThat(mainClassSubject, isPresent()); + assertThat( + mainClassSubject.uniqueMethodWithName("inlineeWithNormalExitThatDoesNotThrow"), + isAbsent()); + assertThat( + mainClassSubject.uniqueMethodWithName("inlineeWithNormalExitThatThrows"), + isAbsent()); + assertThat( + mainClassSubject.uniqueMethodWithName("inlineeWithoutNormalExit"), isAbsent()); + }) + .run(ExceptionHandlingTestClass.class) + .assertSuccessWithOutputLines( + "Test succeeded: methodWithoutCatchHandlersTest(1)", + "Test succeeded: methodWithoutCatchHandlersTest(2)", + "Test succeeded: methodWithoutCatchHandlersTest(3)", + "Test succeeded: methodWithCatchHandlersTest(1)", + "Test succeeded: methodWithCatchHandlersTest(2)", + "Test succeeded: methodWithCatchHandlersTest(3)"); } @Test
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java index f9081c2..59e5118 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java
@@ -10,6 +10,7 @@ import static org.hamcrest.core.IsNot.not; import com.android.tools.r8.KeepConstantArguments; +import com.android.tools.r8.KeepUnusedArguments; import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; @@ -224,6 +225,7 @@ .addOptionsModification( options -> options.enableInliningOfInvokesWithClassInitializationSideEffects = false) .enableConstantArgumentAnnotations() + .enableUnusedArgumentAnnotations() .enableInliningAnnotations() .setMinApi(parameters.getApiLevel()) .run(parameters.getRuntime(), mainClass) @@ -322,6 +324,7 @@ } @KeepConstantArguments + @KeepUnusedArguments @NeverInline private static void test(A obj) { try {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java index 75679e5..dc74e0f 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java
@@ -54,10 +54,8 @@ .addInnerClasses(InliningIntoVisibilityBridgeTest.class) .addInnerClasses(InliningIntoVisibilityBridgeTestClasses.class) .addKeepMainRule(TestClass.class) - .addForceInliningAnnotations() .addInliningAnnotations() .applyIf(neverInline, R8TestBuilder::enableInliningAnnotations) - .applyIf(!neverInline, R8TestBuilder::enableForceInliningAnnotations) .enableNoVerticalClassMergingAnnotations() .enableProguardTestOptions() .setMinApi(parameters.getApiLevel()) @@ -93,13 +91,11 @@ static class TestClass { public static void main(String[] args) { - InliningIntoVisibilityBridgeTestClassC obj = new InliningIntoVisibilityBridgeTestClassC(); - // Invoke method three times to prevent the synthetic bridge on InliningIntoVisibilityBridge- // TestClassB from being inlined. - obj.method(); - obj.method(); - obj.method(); + InliningIntoVisibilityBridgeTestClassC.method(); + InliningIntoVisibilityBridgeTestClassC.method(); + InliningIntoVisibilityBridgeTestClassC.method(); } }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/exceptionhandling/ExceptionHandlingTestClass.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/exceptionhandling/ExceptionHandlingTestClass.java index cda0856..a23b775 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/exceptionhandling/ExceptionHandlingTestClass.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/exceptionhandling/ExceptionHandlingTestClass.java
@@ -4,11 +4,12 @@ package com.android.tools.r8.ir.optimize.inliner.exceptionhandling; +import com.android.tools.r8.NeverInline; + public class ExceptionHandlingTestClass { private static boolean FALSE; - // -keep public static void main(String[] args) { FALSE = args == null; try { @@ -33,7 +34,7 @@ methodWithCatchHandlersTest(); } - // -neverinline + @NeverInline private static void methodWithoutCatchHandlersTest(int i) { switch (i) { case 1: @@ -50,7 +51,7 @@ } } - // -neverinline + @NeverInline private static void methodWithCatchHandlersTest() { try { inlineeWithNormalExitThatDoesNotThrow(); @@ -70,21 +71,18 @@ } } - // -forceinline private static void inlineeWithNormalExitThatDoesNotThrow() { if (FALSE) { throw new RuntimeException(); } } - // -forceinline private static void inlineeWithNormalExitThatThrows() { if (!FALSE) { throw new RuntimeException(); } } - // -forceinline private static void inlineeWithoutNormalExit() { throw new RuntimeException(); }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/testclasses/InliningIntoVisibilityBridgeTestClasses.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/testclasses/InliningIntoVisibilityBridgeTestClasses.java index 54018ee..e856133 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/testclasses/InliningIntoVisibilityBridgeTestClasses.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/testclasses/InliningIntoVisibilityBridgeTestClasses.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.ir.optimize.inliner.testclasses; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.NoVerticalClassMerging; @@ -17,7 +16,6 @@ @NoVerticalClassMerging static class InliningIntoVisibilityBridgeTestClassA { - @ForceInline @NeverInline public static void method() { System.out.println("Hello world");
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetClassTest.java b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetClassTest.java index 000f5d4..3f0c8d6 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetClassTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetClassTest.java
@@ -4,16 +4,15 @@ package com.android.tools.r8.ir.optimize.reflection; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static com.android.tools.r8.utils.codeinspector.Matchers.onlyIf; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; import com.android.tools.r8.CompilationMode; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.NoHorizontalClassMerging; -import com.android.tools.r8.R8TestBuilder; import com.android.tools.r8.TestParameters; import com.android.tools.r8.utils.InternalOptions; import com.android.tools.r8.utils.ListUtils; @@ -23,7 +22,6 @@ import com.android.tools.r8.utils.codeinspector.MethodSubject; import com.google.common.collect.ImmutableList; import java.util.List; -import java.util.concurrent.Callable; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -39,17 +37,15 @@ static class EffectivelyFinal {} @NoHorizontalClassMerging - static class Reflection implements Callable<Class<?>> { + static class Reflection { - @ForceInline - @Override public Class<?> call() { return getClass(); } } @NoHorizontalClassMerging - static class GetClassTestMain implements Callable<Class<?>> { + static class GetClassTestMain { @NeverInline static Class<?> getMainClass(GetClassTestMain instance) { @@ -58,7 +54,6 @@ } @NeverInline - @Override public Class<?> call() { // Non-null `this` pointer. return getClass(); @@ -180,6 +175,11 @@ assertEquals(expectedGetClassCount, countGetClass(mainMethod)); assertEquals(expectedConstClassCount, countConstClass(mainMethod)); + ClassSubject reflectionClass = codeInspector.clazz(Reflection.class); + assertThat(reflectionClass, isPresent()); + assertThat( + reflectionClass.uniqueMethodWithName("call"), onlyIf(expectCallPresent, isPresent())); + ClassSubject getterClass = codeInspector.clazz(GetClassTestMain.class); MethodSubject getMainClass = getterClass.uniqueMethodWithName("getMainClass"); assertThat(getMainClass, isPresent()); @@ -219,8 +219,6 @@ testForR8(parameters.getBackend()) .setMode(mode) .addInnerClasses(GetClassTest.class) - .addForceInliningAnnotations() - .applyIf(mode == CompilationMode.RELEASE, R8TestBuilder::enableForceInliningAnnotations) .enableInliningAnnotations() .enableNoHorizontalClassMergingAnnotations() .addKeepMainRule(MAIN)
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java index f5d0eb9..9b3b394 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java
@@ -4,12 +4,14 @@ package com.android.tools.r8.ir.optimize.reflection; 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; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; import com.android.tools.r8.D8TestRunResult; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.R8TestRunResult; import com.android.tools.r8.SingleTestRunResult; import com.android.tools.r8.TestParameters; @@ -17,11 +19,11 @@ 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.FoundMethodSubject; import com.android.tools.r8.utils.codeinspector.MethodSubject; import com.google.common.collect.ImmutableList; import java.nio.file.Path; import java.util.Collection; -import org.junit.Ignore; import org.junit.Test; class GetName0Class { @@ -32,7 +34,6 @@ void foo(); } - @ForceInline static Itf createRunnable() { return new Itf() { @Override @@ -42,7 +43,6 @@ }; } - @ForceInline static GetName0Class factory() { return new GetName0Class() { @Override @@ -212,7 +212,6 @@ builder.addAll(ToolHelper.getClassFilesForTestDirectory( ToolHelper.getPackageDirectoryForTestPackage(MAIN.getPackage()), path -> path.getFileName().toString().startsWith("GetName0"))); - builder.add(ToolHelper.getClassFileForTestClass(ForceInline.class)); classPaths = builder.build(); } @@ -263,7 +262,6 @@ } @Test - @Ignore("b/154813140: Invalidly assumes that getClass on kept classes can be optimized") public void testR8_pinning() throws Exception { // Pinning the test class. R8TestRunResult result = @@ -276,13 +274,21 @@ .minification(enableMinification) .setMinApi(parameters.getApiLevel()) .addOptionsModification(this::configure) + .compile() + .inspect( + inspector -> { + ClassSubject getName0ClassSubject = inspector.clazz(GetName0Class.class); + assertThat(getName0ClassSubject, isPresent()); + assertTrue( + getName0ClassSubject.allMethods(FoundMethodSubject::isStatic).isEmpty()); + }) .run(parameters.getRuntime(), MAIN) - .assertSuccessWithOutput(JAVA_OUTPUT); - test(result, 2); + // TODO(b/154813140): Invalidly assumes that getClass on kept classes can be optimized. + .assertSuccessWithOutputThatMatches(not(equalTo(JAVA_OUTPUT))); + test(result, 8); } @Test - @Ignore("b/154813140: Invalidly assumes that getClass on kept classes can be optimized") public void testR8_shallow_pinning() throws Exception { // Shallow pinning the test class. R8TestRunResult result = @@ -295,13 +301,21 @@ .minification(enableMinification) .setMinApi(parameters.getApiLevel()) .addOptionsModification(this::configure) + .compile() + .inspect( + inspector -> { + ClassSubject getName0ClassSubject = inspector.clazz(GetName0Class.class); + assertThat(getName0ClassSubject, isPresent()); + assertTrue( + getName0ClassSubject.allMethods(FoundMethodSubject::isStatic).isEmpty()); + }) .run(parameters.getRuntime(), MAIN); + // TODO(b/154813140): Invalidly assumes that getClass on kept classes can be optimized. if (enableMinification) { - result.assertSuccessWithOutput(RENAMED_OUTPUT); + result.assertSuccessWithOutputThatMatches(not(equalTo(RENAMED_OUTPUT))); } else { - result.assertSuccessWithOutput(JAVA_OUTPUT); + result.assertSuccessWithOutputThatMatches(not(equalTo(JAVA_OUTPUT))); } - test(result, 2); + test(result, 8); } - }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java index 102d5c7..a6d3931 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java
@@ -3,17 +3,18 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.ir.optimize.reflection; +import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; import com.android.tools.r8.D8TestRunResult; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.SingleTestRunResult; import com.android.tools.r8.TestParameters; import com.android.tools.r8.ToolHelper; +import com.android.tools.r8.ir.optimize.reflection.Outer.TestHelper; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; import com.android.tools.r8.utils.codeinspector.CodeInspector; @@ -100,7 +101,6 @@ this.inner = inner; } - @ForceInline String getClassName() { return inner.getClass().getSimpleName(); } @@ -159,12 +159,18 @@ .assertSuccessWithOutput(JVM_OUTPUT); } - private void test(SingleTestRunResult<?> result) throws Exception { + private void test(SingleTestRunResult<?> result, boolean isOptimizing) throws Exception { CodeInspector codeInspector = result.inspector(); ClassSubject mainClass = codeInspector.clazz(MAIN); MethodSubject mainMethod = mainClass.mainMethod(); assertThat(mainMethod, isPresent()); assertEquals(0, countGetName(mainMethod)); + + if (isOptimizing) { + ClassSubject testHelperClassSubject = codeInspector.clazz(TestHelper.class); + assertThat(testHelperClassSubject, isPresent()); + assertThat(testHelperClassSubject.uniqueMethodWithName("getClassName"), isAbsent()); + } } @Test @@ -179,7 +185,7 @@ .addOptionsModification(this::configure) .run(parameters.getRuntime(), MAIN) .assertSuccessWithOutput(JVM_OUTPUT); - test(result); + test(result, false); result = testForD8() @@ -189,7 +195,7 @@ .addOptionsModification(this::configure) .run(parameters.getRuntime(), MAIN) .assertSuccessWithOutput(JVM_OUTPUT); - test(result); + test(result, false); } @Test @@ -197,7 +203,6 @@ // Pinning the test class. testForR8(parameters.getBackend()) .addProgramFiles(classPaths) - .addForceInliningAnnotations() .enableInliningAnnotations() .addKeepAllClassesRule() .addKeepAttributeInnerClassesAndEnclosingMethod() @@ -206,7 +211,7 @@ .addOptionsModification(this::configure) .run(parameters.getRuntime(), MAIN) .assertSuccessWithOutput(JVM_OUTPUT) - .apply(this::test); + .apply(result -> test(result, false)); } @Test @@ -214,7 +219,6 @@ // Pinning the test class. testForR8(parameters.getBackend()) .addProgramFiles(classPaths) - .enableForceInliningAnnotations() .enableInliningAnnotations() .addKeepMainRule(MAIN) .addKeepRules("-keep class **.ClassGetSimpleName*") @@ -225,7 +229,7 @@ .addOptionsModification(this::configure) .run(parameters.getRuntime(), MAIN) .assertSuccessWithOutput(OUTPUT_NO_ATTRIBUTES) - .apply(this::test); + .apply(result -> test(result, true)); } @Test @@ -233,7 +237,6 @@ // Shallow pinning the test class. testForR8(parameters.getBackend()) .addProgramFiles(classPaths) - .enableForceInliningAnnotations() .enableInliningAnnotations() .addKeepMainRule(MAIN) .addKeepRules("-keep,allowobfuscation class **.ClassGetSimpleName*") @@ -249,6 +252,6 @@ .applyIf(enableMinification, result -> result.assertSuccessWithOutput(RENAMED_OUTPUT)) .applyIf( !enableMinification, result -> result.assertSuccessWithOutput(OUTPUT_NO_ATTRIBUTES)) - .apply(this::test); + .apply(result -> test(result, true)); } }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java index a1b6f08..c3f71e3 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
@@ -164,16 +164,19 @@ assertTrue(instanceMethods(simpleWithPhi).isEmpty()); assertThat(simpleWithPhi.clinit(), not(isPresent())); + // TODO(b/200498092): SimpleWithParams should be staticized, but due to reprocessing the + // instantiation of SimpleWithParams, it is marked as ineligible for staticizing. assertEquals( Lists.newArrayList( - "STATIC: String SimpleWithParams.bar(String)", - "STATIC: String SimpleWithParams.foo()", - "STATIC: String TrivialTestClass.next()"), + "STATIC: String TrivialTestClass.next()", + "SimpleWithParams SimpleWithParams.INSTANCE", + "VIRTUAL: String SimpleWithParams.bar(String)", + "VIRTUAL: String SimpleWithParams.foo()"), references(clazz, "testSimpleWithParams", "void")); ClassSubject simpleWithParams = inspector.clazz(SimpleWithParams.class); - assertTrue(instanceMethods(simpleWithParams).isEmpty()); - assertThat(simpleWithParams.clinit(), not(isPresent())); + assertFalse(instanceMethods(simpleWithParams).isEmpty()); + assertThat(simpleWithParams.clinit(), isPresent()); assertEquals( Lists.newArrayList(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java index 38ddc76..65d51c3 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java
@@ -6,7 +6,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestParametersCollection; @@ -39,20 +38,21 @@ testForR8(parameters.getBackend()) .addProgramClasses(MAIN) - .enableForceInliningAnnotations() .addKeepMainRule(MAIN) .setMinApi(parameters.getApiLevel()) .run(parameters.getRuntime(), MAIN.getTypeName(), "$") .assertSuccessWithOutput(EXPECTED) - .inspect(codeInspector -> { - ClassSubject mainClass = codeInspector.clazz(MAIN); - MethodSubject main = mainClass.mainMethod(); - assertEquals( - // TODO(b/113859361): should be 1 after merging StringBuilder's - 2, - main.streamInstructions().filter( - i -> i.isNewInstance(StringBuilder.class.getTypeName())).count()); - }); + .inspect( + codeInspector -> { + ClassSubject mainClass = codeInspector.clazz(MAIN); + MethodSubject main = mainClass.uniqueMethod(); + assertEquals( + // TODO(b/113859361): should be 1 after merging StringBuilder's + 2, + main.streamInstructions() + .filter(i -> i.isNewInstance(StringBuilder.class.getTypeName())) + .count()); + }); } static class NestedStringBuilders { @@ -61,7 +61,6 @@ System.out.println(concat("one", args[0]) + "two"); } - @ForceInline public static String concat(String one, String two) { return one + two; }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/StringLengthTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/StringLengthTest.java index 7924a77..b2927fb 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/string/StringLengthTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/string/StringLengthTest.java
@@ -9,7 +9,6 @@ import static org.junit.Assume.assumeTrue; import com.android.tools.r8.D8TestRunResult; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.R8TestRunResult; import com.android.tools.r8.SingleTestRunResult; @@ -96,7 +95,6 @@ R8TestRunResult result = testForR8(parameters.getBackend()) .addProgramClasses(MAIN) - .enableForceInliningAnnotations() .enableInliningAnnotations() .addKeepMainRule(MAIN) .setMinApi(parameters.getApiLevel()) @@ -107,7 +105,6 @@ public static class TestClass { - @ForceInline static String simpleInlineable() { return "Shared"; }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/StringValueOfTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/StringValueOfTest.java index 01ac9dc..3861a06 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/string/StringValueOfTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/string/StringValueOfTest.java
@@ -3,12 +3,12 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.ir.optimize.string; +import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.NeverPropagateValue; import com.android.tools.r8.SingleTestRunResult; @@ -45,7 +45,7 @@ @Parameterized.Parameters(name = "{0}") public static TestParametersCollection data() { - return getTestParameters().withAllRuntimes().build(); + return getTestParameters().withAllRuntimesAndApiLevels().build(); } private final TestParameters parameters; @@ -111,13 +111,19 @@ SingleTestRunResult<?> result = testForR8(parameters.getBackend()) .addProgramClassesAndInnerClasses(MAIN) - .enableForceInliningAnnotations() .enableInliningAnnotations() .enableMemberValuePropagationAnnotations() .addKeepMainRule(MAIN) - .setMinApi(parameters.getRuntime()) + .setMinApi(parameters.getApiLevel()) .noMinification() .addOptionsModification(this::configure) + .compile() + .inspect( + inspector -> { + ClassSubject fooClassSubject = inspector.clazz(Foo.class); + assertThat(fooClassSubject, isPresent()); + assertThat(fooClassSubject.uniqueMethodWithName("getter"), isAbsent()); + }) .run(parameters.getRuntime(), MAIN) .assertSuccessWithOutput(JAVA_OUTPUT); test(result, true, true); @@ -155,7 +161,6 @@ } static class Foo implements Itf { - @ForceInline @Override public String getter() { return String.valueOf(getClass().getName());
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/InvokeMethodWithReceiverOptimizationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/InvokeMethodWithReceiverOptimizationTest.java index e7e09dd..06aae25 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/InvokeMethodWithReceiverOptimizationTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/InvokeMethodWithReceiverOptimizationTest.java
@@ -12,7 +12,7 @@ import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; -import com.android.tools.r8.ToolHelper; +import com.android.tools.r8.TestParameters; import com.android.tools.r8.utils.BooleanUtils; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -33,17 +33,19 @@ @RunWith(Parameterized.class) public class InvokeMethodWithReceiverOptimizationTest extends TestBase { - private final Backend backend; - private final boolean enableArgumentRemoval; + private final TestParameters parameters; + private final boolean enableArgumentPropagation; - @Parameters(name = "Backend: {0}, enable argument removal: {1}") + @Parameters(name = "{0}, argument propagation: {1}") public static List<Object[]> data() { - return buildParameters(ToolHelper.getBackends(), BooleanUtils.values()); + return buildParameters( + getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values()); } - public InvokeMethodWithReceiverOptimizationTest(Backend backend, boolean enableArgumentRemoval) { - this.backend = backend; - this.enableArgumentRemoval = enableArgumentRemoval; + public InvokeMethodWithReceiverOptimizationTest( + TestParameters parameters, boolean enableArgumentPropagation) { + this.parameters = parameters; + this.enableArgumentPropagation = enableArgumentPropagation; } @Test @@ -57,15 +59,20 @@ testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expected); CodeInspector inspector = - testForR8(backend) + testForR8(parameters.getBackend()) .addInnerClasses(InvokeMethodWithReceiverOptimizationTest.class) .addKeepMainRule(TestClass.class) .enableInliningAnnotations() - .addOptionsModification(o -> o.enableArgumentRemoval = enableArgumentRemoval) + .addOptionsModification( + options -> { + options.enableUninstantiatedTypeOptimization = enableArgumentPropagation; + options.callSiteOptimizationOptions().setEnabled(enableArgumentPropagation); + }) // TODO(b/120764902): The calls to getOriginalName() below does not work in presence of - // argument removal. - .addKeepRules("-dontobfuscate") - .run(TestClass.class) + // argument removal. + .noMinification() + .setMinApi(parameters.getApiLevel()) + .run(parameters.getRuntime(), TestClass.class) .assertSuccessWithOutput(expected) .inspector(); @@ -73,7 +80,7 @@ assertThat(testClassSubject, isPresent()); ClassSubject otherClassSubject = inspector.clazz(A.class); - assertNotEquals(enableArgumentRemoval, otherClassSubject.isPresent()); + assertNotEquals(enableArgumentPropagation, otherClassSubject.isPresent()); // Check that A.method() has been removed. assertThat(otherClassSubject.uniqueMethodWithName("method"), not(isPresent()));
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/PrivateInstanceMethodCollisionTest.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/PrivateInstanceMethodCollisionTest.java index 8dc29fb..58dc4e5 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/PrivateInstanceMethodCollisionTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/PrivateInstanceMethodCollisionTest.java
@@ -35,7 +35,7 @@ @Parameters(name = "{0}, minification: {1}, allowaccessmodification: {2}") public static List<Object[]> data() { return buildParameters( - getTestParameters().withAllRuntimes().build(), + getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values(), BooleanUtils.values()); } @@ -66,7 +66,7 @@ .enableNoHorizontalClassMergingAnnotations() .minification(minification) .allowAccessModification(allowAccessModification) - .setMinApi(parameters.getRuntime()) + .setMinApi(parameters.getApiLevel()) .compile() .inspect(this::verifyUninstantiatedArgumentsRemovedAndNoCollisions) .run(parameters.getRuntime(), TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java index 663bcf6..0e4a3a2 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java
@@ -100,10 +100,7 @@ for (MethodSubject methodSubject : methodSubjects) { assertThat(methodSubject, isPresent()); - // TODO(b/131735725): Should also remove arguments from the virtual methods. - boolean shouldHaveArgumentRemoval = - keepUninstantiatedArguments || methodSubject.getOriginalName().contains("Virtual"); - if (shouldHaveArgumentRemoval) { + if (keepUninstantiatedArguments) { assertEquals(3, methodSubject.getMethod().getParameters().size()); // In non-compat mode, R8 removes annotations from non-pinned items. @@ -122,7 +119,7 @@ assertEquals(1, annotationSet.size()); DexAnnotation annotation = annotationSet.getFirst(); - if (shouldHaveArgumentRemoval && i == getPositionOfUnusedArgument(methodSubject)) { + if (keepUninstantiatedArguments && i == getPositionOfUnusedArgument(methodSubject)) { assertEquals( uninstantiatedClassSubject.getFinalName(), annotation.getAnnotationType().getTypeName());
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithLibraryMethodsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithLibraryMethodsTest.java index 14efc77..612a0b5 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithLibraryMethodsTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithLibraryMethodsTest.java
@@ -67,7 +67,7 @@ assertEquals("a", methodSubject.getFinalName()); assertEquals(0, methodSubject.getMethod().getReference().proto.parameters.size()); } else { - assertEquals("toString1", methodSubject.getFinalName()); + assertEquals("toString$1", methodSubject.getFinalName()); assertEquals(0, methodSubject.getMethod().getReference().proto.parameters.size()); } }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAndUninstantiatedTypesTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAndUninstantiatedTypesTest.java index 138f0a9..7ca05fb 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAndUninstantiatedTypesTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAndUninstantiatedTypesTest.java
@@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals; +import com.android.tools.r8.NeverClassInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; @@ -39,6 +40,7 @@ .addKeepMainRule(Main.class) .noMinification() .enableInliningAnnotations() + .enableNeverClassInliningAnnotations() .setMinApi(parameters.getApiLevel()) .compile() .inspect(this::assertMethodsAreThere) @@ -168,5 +170,6 @@ private static class UnInstantiated {} + @NeverClassInline private static class Unused {} }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsWithMissingAnnotationsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsWithMissingAnnotationsTest.java index c008972..c074ee1 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsWithMissingAnnotationsTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsWithMissingAnnotationsTest.java
@@ -82,7 +82,9 @@ .addKeepRules( "-keep @interface Annotation?", "-neverclassinline class *", - "-nohorizontalclassmerging class Test$Inner?") + "-nohorizontalclassmerging class Test$Inner?", + "-keepclassmembers class Test$Inner? { synthetic <fields>; }", + "-keepconstantarguments class Test$Inner? { void <init>(...); }") .addKeepRuntimeVisibleParameterAnnotations() .enableProguardTestOptions() .setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentRemovalWithOverridingTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentRemovalWithOverridingTest.java index 281db3e..58b052c 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentRemovalWithOverridingTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentRemovalWithOverridingTest.java
@@ -32,7 +32,8 @@ @Parameters(name = "{1}, minification: {0}") public static List<Object[]> params() { - return buildParameters(BooleanUtils.values(), getTestParameters().withAllRuntimes().build()); + return buildParameters( + BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build()); } public UnusedArgumentRemovalWithOverridingTest(boolean minification, TestParameters parameters) { @@ -50,7 +51,7 @@ .enableInliningAnnotations() .enableNoVerticalClassMergingAnnotations() .minification(minification) - .setMinApi(parameters.getRuntime()) + .setMinApi(parameters.getApiLevel()) .compile() .inspect(this::verify) .run(parameters.getRuntime(), TestClass.class) @@ -70,8 +71,9 @@ static class TestClass { public static void main(String[] args) { - System.out.println(new A().greeting("Hello world!")); - System.out.println(new B().greeting("Hello world!")); + String greeting = System.currentTimeMillis() > 0 ? "Hello world!" : null; + System.out.println(new A().greeting(greeting)); + System.out.println(new B().greeting(greeting)); } }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java index 7d9a941..8ccee13 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java
@@ -9,12 +9,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import com.android.tools.r8.CompilationMode; import com.android.tools.r8.KeepConstantArguments; import com.android.tools.r8.NeverInline; import com.android.tools.r8.R8TestRunResult; 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; @@ -29,25 +29,20 @@ public class UnusedArgumentsCollisionMappingTest extends TestBase { private final TestParameters parameters; - private final CompilationMode compilationMode; - @Parameters(name = "{0}, compilation mode: {1}") - public static List<Object[]> data() { - return buildParameters( - getTestParameters().withAllRuntimesAndApiLevels().build(), CompilationMode.values()); + @Parameters(name = "{0}") + public static TestParametersCollection data() { + return getTestParameters().withAllRuntimesAndApiLevels().build(); } - public UnusedArgumentsCollisionMappingTest( - TestParameters parameters, CompilationMode compilationMode) { + public UnusedArgumentsCollisionMappingTest(TestParameters parameters) { this.parameters = parameters; - this.compilationMode = compilationMode; } @Test public void testR8() throws Exception { R8TestRunResult runResult = testForR8(parameters.getBackend()) - .setMode(compilationMode) .addProgramClasses(Main.class) .setMinApi(parameters.getApiLevel()) .addKeepMainRule(Main.class)
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionTest.java index 1137a01..c59eb85 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionTest.java
@@ -34,7 +34,8 @@ @Parameters(name = "{1}, minification: {0}") public static List<Object[]> data() { - return buildParameters(BooleanUtils.values(), getTestParameters().withAllRuntimes().build()); + return buildParameters( + BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build()); } public UnusedArgumentsCollisionTest(boolean minification, TestParameters parameters) { @@ -60,7 +61,7 @@ .enableNeverClassInliningAnnotations() .enableNoVerticalClassMergingAnnotations() .minification(minification) - .setMinApi(parameters.getRuntime()) + .setMinApi(parameters.getApiLevel()) .compile() .inspect(this::verifyUnusedArgumentsRemovedAndNoCollisions) .run(parameters.getRuntime(), TestClass.class) @@ -85,11 +86,10 @@ MethodSubject methodB1Subject = bClassSubject.allMethods().stream().filter(FoundMethodSubject::isStatic).findFirst().get(); assertThat(methodB1Subject, isPresent()); - assertEquals(0, methodB1Subject.getMethod().getReference().proto.parameters.size()); + assertEquals(0, methodB1Subject.getMethod().getParameters().size()); - // TODO(b/129933280): Determine if we should use member pool collection for unused argument - // removal for private and static methods. - assertEquals(methodB1Subject.getFinalName(), methodA1Subject.getFinalName()); + // Verify that the static method B.method1() does not collide with a method in A. + assertNotEquals(methodB1Subject.getFinalName(), methodA1Subject.getFinalName()); assertNotEquals(methodB1Subject.getFinalName(), methodA2Subject.getFinalName()); // Verify that the unused argument has been removed from B.method2(). @@ -97,7 +97,7 @@ MethodSubject methodB2Subject = bClassSubject.allMethods().stream().filter(FoundMethodSubject::isVirtual).findFirst().get(); assertThat(methodB2Subject, isPresent()); - assertEquals(0, methodB2Subject.getMethod().getReference().proto.parameters.size()); + assertEquals(0, methodB2Subject.getMethod().getParameters().size()); // Verify that the virtual method B.method2() does not collide with a method in A. assertNotEquals(methodB2Subject.getFinalName(), methodA1Subject.getFinalName());
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsInstanceConstructorTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsInstanceConstructorTest.java index c890e97..a4622bc 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsInstanceConstructorTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsInstanceConstructorTest.java
@@ -11,11 +11,14 @@ import com.android.tools.r8.NeverClassInline; import com.android.tools.r8.NeverInline; +import com.android.tools.r8.NoHorizontalClassMerging; import com.android.tools.r8.TestBase; -import com.android.tools.r8.ToolHelper; +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.HorizontallyMergedClassesInspector; import com.android.tools.r8.utils.codeinspector.MethodSubject; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,32 +28,39 @@ @RunWith(Parameterized.class) public class UnusedArgumentsInstanceConstructorTest extends TestBase { - private final Backend backend; + private final TestParameters parameters; - @Parameters(name = "Backend: {0}") - public static Backend[] data() { - return ToolHelper.getBackends(); + @Parameters(name = "{0}") + public static TestParametersCollection data() { + return getTestParameters().withAllRuntimesAndApiLevels().build(); } - public UnusedArgumentsInstanceConstructorTest(Backend backend) { - this.backend = backend; + public UnusedArgumentsInstanceConstructorTest(TestParameters parameters) { + this.parameters = parameters; } @Test public void test() throws Exception { String expectedOutput = StringUtils.lines("Hello world"); - if (backend == Backend.CF) { - testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expectedOutput); + if (parameters.isCfRuntime()) { + testForJvm() + .addTestClasspath() + .run(parameters.getRuntime(), TestClass.class) + .assertSuccessWithOutput(expectedOutput); } CodeInspector inspector = - testForR8(backend) + testForR8(parameters.getBackend()) .addInnerClasses(UnusedArgumentsInstanceConstructorTest.class) .addKeepMainRule(TestClass.class) + .addHorizontallyMergedClassesInspector( + HorizontallyMergedClassesInspector::assertNoClassesMerged) .enableInliningAnnotations() .enableNeverClassInliningAnnotations() - .run(TestClass.class) + .enableNoHorizontalClassMergingAnnotations() + .setMinApi(parameters.getApiLevel()) + .run(parameters.getRuntime(), TestClass.class) .assertSuccessWithOutput(expectedOutput) .inspector(); @@ -73,6 +83,7 @@ } @NeverClassInline + @NoHorizontalClassMerging static class A { public A(B uninstantiated, C unused) { @@ -90,7 +101,9 @@ } } + @NoHorizontalClassMerging static class B {} + @NoHorizontalClassMerging static class C {} }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java index 794d588..3a4eeda 100644 --- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java +++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java
@@ -29,6 +29,7 @@ return UnusedArgumentsTestBase.data(); } + @NeverClassInline static class TestObject { public final String s;
diff --git a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java index cdc4346..5c45b49 100644 --- a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java +++ b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.jsr45; import static com.android.tools.r8.ToolHelper.getDefaultAndroidJar; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import com.android.tools.r8.CompilationFailedException; import com.android.tools.r8.D8; @@ -66,12 +64,11 @@ private AndroidApp compileWithR8(Path inputPath, Path outputPath, Path keepRulesPath) throws CompilationFailedException { + KotlinCompiler kotlinc = KotlinCompiler.latest(); return ToolHelper.runR8( R8Command.builder() .addProgramFiles(inputPath) - .addProgramFiles( - getKotlinStdlibJar(KotlinCompiler.latest()), - getKotlinAnnotationJar(KotlinCompiler.latest())) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addLibraryFiles(getDefaultAndroidJar()) .setOutput(outputPath, OutputMode.DexIndexed) .addProguardConfigurationFiles(keepRulesPath)
diff --git a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java index 2516b74..79880c8 100644 --- a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java +++ b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.kotlin; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.not; @@ -228,7 +227,7 @@ classpath.clear(); classpath.add(kotlinJarFile); classpath.add(getJavaJarFile(folder)); - classpath.add(getKotlinAnnotationJar(kotlinc)); + classpath.add(kotlinc.getKotlinAnnotationJar()); classpath.addAll(extraClasspath); // Compare with Java.
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 f6cc385..6ec949a 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.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_3_72; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -59,7 +58,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addKeepRules( StringUtils.lines( "-keepclasseswithmembers class " + MAIN + "{", " public static *** *(...);", "}")) @@ -110,7 +109,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addKeepRules( StringUtils.lines( "-keepclasseswithmembers class " + MAIN + "{",
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 baf1308..50e9c6e 100644 --- a/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinReflectionLibTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinReflectionLibTest.java
@@ -48,9 +48,9 @@ testForR8(parameters.getBackend()) .addLibraryFiles( ToolHelper.getMostRecentAndroidJar(), - ToolHelper.getKotlinStdlibJar(kotlinc), - ToolHelper.getKotlinAnnotationJar(kotlinc)) - .addProgramFiles(ToolHelper.getKotlinReflectJar(kotlinc)) + kotlinc.getKotlinStdlibJar(), + kotlinc.getKotlinAnnotationJar()) + .addProgramFiles(kotlinc.getKotlinReflectJar()) .addKeepAttributes(ProguardKeepAttributes.SIGNATURE) .addKeepAttributes(ProguardKeepAttributes.INNER_CLASSES) .addKeepAttributes(ProguardKeepAttributes.ENCLOSING_METHOD)
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 68614ad..db73684 100644 --- a/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinStdlibTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/ProcessKotlinStdlibTest.java
@@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.kotlin; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import com.android.tools.r8.KotlinTestBase; @@ -35,7 +33,7 @@ private void test(Collection<String> rules) throws Exception { testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepRules(rules) .addKeepAttributes(ProguardKeepAttributes.SIGNATURE) .addKeepAttributes(ProguardKeepAttributes.INNER_CLASSES)
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 46adea0..0f534e0 100644 --- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
@@ -10,11 +10,11 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.R8TestBuilder; import com.android.tools.r8.TestParameters; import com.android.tools.r8.ToolHelper; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.ToolHelper.ProcessResult; import com.android.tools.r8.jasmin.JasminBuilder; import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder; @@ -327,7 +327,7 @@ "accessors", mainClass, builder -> { - builder.addClasspathFiles(ToolHelper.getKotlinAnnotationJar(kotlinc)); + builder.addClasspathFiles(kotlinc.getKotlinAnnotationJar()); builder.noClassStaticizing(); }) .inspect(
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 aebbbb2..2cb21d4 100644 --- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
@@ -6,10 +6,8 @@ import static org.junit.Assume.assumeTrue; -import com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.graph.DexCode; import com.android.tools.r8.kotlin.TestKotlinClass.Visibility; import com.android.tools.r8.naming.MemberNaming.MethodSignature; @@ -78,9 +76,7 @@ .addOptionsModification(disableClassInliner)) .inspect( inspector -> { - if (allowAccessModification - && kotlinParameters.is( - KotlinCompilerVersion.KOTLINC_1_5_0, KotlinTargetVersion.JAVA_8)) { + if (allowAccessModification) { checkClassIsRemoved(inspector, TEST_DATA_CLASS.getClassName()); } else { ClassSubject dataClass = @@ -129,9 +125,7 @@ .addOptionsModification(disableClassInliner)) .inspect( inspector -> { - if (allowAccessModification - && kotlinParameters.is( - KotlinCompilerVersion.KOTLINC_1_5_0, KotlinTargetVersion.JAVA_8)) { + if (allowAccessModification) { checkClassIsRemoved(inspector, TEST_DATA_CLASS.getClassName()); } else { ClassSubject dataClass = @@ -181,21 +175,26 @@ .addOptionsModification(disableClassInliner)) .inspect( inspector -> { - ClassSubject dataClass = checkClassIsKept(inspector, TEST_DATA_CLASS.getClassName()); + if (allowAccessModification) { + checkClassIsRemoved(inspector, TEST_DATA_CLASS.getClassName()); + } else { + ClassSubject dataClass = + checkClassIsKept(inspector, TEST_DATA_CLASS.getClassName()); - boolean component2IsPresent = !allowAccessModification; - checkMethodIsKeptOrRemoved(dataClass, COMPONENT2_METHOD, component2IsPresent); + boolean component2IsPresent = !allowAccessModification; + checkMethodIsKeptOrRemoved(dataClass, COMPONENT2_METHOD, component2IsPresent); - // Function component1 is not used. - checkMethodIsRemoved(dataClass, COMPONENT1_METHOD); + // Function component1 is not used. + checkMethodIsRemoved(dataClass, COMPONENT1_METHOD); - // No use of getter. - checkMethodIsRemoved(dataClass, NAME_GETTER_METHOD); - checkMethodIsRemoved(dataClass, AGE_GETTER_METHOD); + // No use of getter. + checkMethodIsRemoved(dataClass, NAME_GETTER_METHOD); + checkMethodIsRemoved(dataClass, AGE_GETTER_METHOD); - // No use of copy functions. - checkMethodIsRemoved(dataClass, COPY_METHOD); - checkMethodIsRemoved(dataClass, COPY_DEFAULT_METHOD); + // No use of copy functions. + checkMethodIsRemoved(dataClass, COPY_METHOD); + checkMethodIsRemoved(dataClass, COPY_DEFAULT_METHOD); + } ClassSubject classSubject = checkClassIsKept(inspector, mainClassName); MethodSubject testMethod = checkMethodIsKept(classSubject, testMethodSignature); @@ -222,9 +221,7 @@ .addOptionsModification(disableClassInliner)) .inspect( inspector -> { - if (testParameters.isDexRuntime() - && allowAccessModification - && kotlinParameters.is(KotlinCompilerVersion.KOTLINC_1_3_72)) { + if (allowAccessModification) { checkClassIsRemoved(inspector, TEST_DATA_CLASS.getClassName()); } else { ClassSubject dataClass =
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/JStyleKotlinLambdaMergingWithEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/JStyleKotlinLambdaMergingWithEnumUnboxingTest.java index 787ae1f..c6885f3 100644 --- a/src/test/java/com/android/tools/r8/kotlin/lambda/JStyleKotlinLambdaMergingWithEnumUnboxingTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/lambda/JStyleKotlinLambdaMergingWithEnumUnboxingTest.java
@@ -4,14 +4,11 @@ package com.android.tools.r8.kotlin.lambda; -import static com.android.tools.r8.ToolHelper.getKotlinCompilers; - -import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.NeverClassInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.kotlin.lambda.JStyleKotlinLambdaMergingWithEnumUnboxingTest.Main.EnumUnboxingCandidate; import java.util.List; import org.junit.Test; @@ -23,19 +20,19 @@ public class JStyleKotlinLambdaMergingWithEnumUnboxingTest extends TestBase { private final TestParameters parameters; - private final KotlinCompiler kotlinc; + private final KotlinTestParameters kotlinTestParameters; @Parameters(name = "{0}, kotlinc: {1}") public static List<Object[]> data() { return buildParameters( - TestBase.getTestParameters().withDexRuntimes().withAllApiLevels().build(), - getKotlinCompilers()); + getTestParameters().withDexRuntimes().withAllApiLevels().build(), + getKotlinTestParameters().withAllCompilers().withNoTargetVersion().build()); } public JStyleKotlinLambdaMergingWithEnumUnboxingTest( - TestParameters parameters, KotlinCompiler kotlinc) { + TestParameters parameters, KotlinTestParameters kotlinTestParameters) { this.parameters = parameters; - this.kotlinc = kotlinc; + this.kotlinTestParameters = kotlinTestParameters; } @Test @@ -43,7 +40,7 @@ testForR8(parameters.getBackend()) .addInnerClasses(getClass()) .addDefaultRuntimeLibrary(parameters) - .addLibraryFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addLibraryFiles(kotlinTestParameters.getCompiler().getKotlinStdlibJar()) .addKeepMainRule(Main.class) .addHorizontallyMergedClassesInspector( inspector -> inspector.assertMergedInto(Lambda2.class, Lambda1.class))
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KStyleKotlinLambdaMergingWithEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KStyleKotlinLambdaMergingWithEnumUnboxingTest.java index 5b22795..b4abfb6 100644 --- a/src/test/java/com/android/tools/r8/kotlin/lambda/KStyleKotlinLambdaMergingWithEnumUnboxingTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KStyleKotlinLambdaMergingWithEnumUnboxingTest.java
@@ -4,12 +4,9 @@ package com.android.tools.r8.kotlin.lambda; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinCompilers; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; -import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.NeverClassInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.TestBase; @@ -25,26 +22,28 @@ public class KStyleKotlinLambdaMergingWithEnumUnboxingTest extends TestBase { private final TestParameters parameters; - private final KotlinCompiler kotlinc; + private final KotlinTestParameters kotlinTestParameters; @Parameters(name = "{0}, kotlinc: {1}") public static List<Object[]> data() { return buildParameters( - TestBase.getTestParameters().withDexRuntimes().withAllApiLevels().build(), - getKotlinCompilers()); + getTestParameters().withDexRuntimes().withAllApiLevels().build(), + getKotlinTestParameters().withAllCompilers().withNoTargetVersion().build()); } public KStyleKotlinLambdaMergingWithEnumUnboxingTest( - TestParameters parameters, KotlinCompiler kotlinc) { + TestParameters parameters, KotlinTestParameters kotlinTestParameters) { this.parameters = parameters; - this.kotlinc = kotlinc; + this.kotlinTestParameters = kotlinTestParameters; } @Test public void test() throws Exception { testForR8(parameters.getBackend()) .addInnerClasses(getClass()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles( + kotlinTestParameters.getCompiler().getKotlinStdlibJar(), + kotlinTestParameters.getCompiler().getKotlinAnnotationJar()) .addKeepMainRule(Main.class) .addHorizontallyMergedClassesInspector( inspector -> inspector.assertMergedInto(Lambda2.class, Lambda1.class))
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 7966656..35087f5 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,8 +4,6 @@ package com.android.tools.r8.kotlin.lambda; import static com.android.tools.r8.ToolHelper.getJava8RuntimeJar; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assume.assumeTrue; @@ -52,14 +50,14 @@ .compile(); testForR8(parameters.getBackend()) .addLibraryFiles(getJava8RuntimeJar()) - .addLibraryFiles(getKotlinStdlibJar(kotlinc)) - .addProgramFiles(ktClasses, getKotlinAnnotationJar(kotlinc)) + .addLibraryFiles(kotlinc.getKotlinStdlibJar()) + .addProgramFiles(ktClasses, kotlinc.getKotlinAnnotationJar()) .addKeepMainRule("**.B143165163Kt") .allowDiagnosticWarningMessages() .setMinApi(parameters.getApiLevel()) .compile() .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists.")) - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc)) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar()) .run(parameters.getRuntime(), pkg + ".B143165163Kt") .assertSuccessWithOutputLines("outer foo bar", "outer foo default"); } @@ -77,7 +75,7 @@ .addSourceFiles(getKotlinFileInTest(folder, "b143165163")) .compile(); testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(ktClasses) .addKeepMainRule("**.B143165163Kt") .allowDiagnosticWarningMessages()
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingCapturesKotlinStyleTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingCapturesKotlinStyleTest.java index 1e8065c..a1adb7a 100644 --- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingCapturesKotlinStyleTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingCapturesKotlinStyleTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.kotlin.lambda; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.PredicateUtils.not; import static junit.framework.TestCase.assertEquals; import static org.hamcrest.CoreMatchers.containsString; @@ -152,7 +151,7 @@ getCompileMemoizer(getKotlinFilesInResource(getTestName()), getTestName()) .configure(kotlinCompilerTool -> kotlinCompilerTool.includeRuntime().noReflect()) .getForConfiguration(kotlinc, targetVersion); - return ImmutableList.of(kotlinJarFile, getJavaJarFile(), getKotlinAnnotationJar(kotlinc)); + return ImmutableList.of(kotlinJarFile, getJavaJarFile(), kotlinc.getKotlinAnnotationJar()); } private String getTestName() {
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 de923a9..03d1aa2 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
@@ -3,14 +3,13 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.kotlin.lambda; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static org.hamcrest.CoreMatchers.equalTo; import com.android.tools.r8.CompilationMode; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestBase; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,7 +49,7 @@ .setMode(CompilationMode.DEBUG) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, KotlinTargetVersion.JAVA_6), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .setMinApi(parameters.getApiLevel()) .addKeepMainRule(MAIN_CLASS)
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 a2127ef..2ac2b7b 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
@@ -4,7 +4,6 @@ package com.android.tools.r8.kotlin.lambda; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.shaking.ProguardKeepAttributes.ENCLOSING_METHOD; import static com.android.tools.r8.shaking.ProguardKeepAttributes.INNER_CLASSES; import static com.android.tools.r8.shaking.ProguardKeepAttributes.SIGNATURE; @@ -146,7 +145,7 @@ getCompileMemoizer(getKotlinFilesInResource(getTestName()), getTestName()) .configure(kotlinCompilerTool -> kotlinCompilerTool.includeRuntime().noReflect()) .getForConfiguration(kotlinc, targetVersion); - return ImmutableList.of(kotlinJarFile, getJavaJarFile(), getKotlinAnnotationJar(kotlinc)); + return ImmutableList.of(kotlinJarFile, getJavaJarFile(), kotlinc.getKotlinAnnotationJar()); } private String getTestName() {
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 500f7c1..33e5cff 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
@@ -4,7 +4,6 @@ package com.android.tools.r8.kotlin.lambda; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.PredicateUtils.not; import static junit.framework.TestCase.assertEquals; import static org.hamcrest.CoreMatchers.containsString; @@ -146,7 +145,7 @@ getCompileMemoizer(getKotlinFilesInResource(getTestName()), getTestName()) .configure(kotlinCompilerTool -> kotlinCompilerTool.includeRuntime().noReflect()) .getForConfiguration(kotlinc, targetVersion); - return ImmutableList.of(kotlinJarFile, getJavaJarFile(), getKotlinAnnotationJar(kotlinc)); + return ImmutableList.of(kotlinJarFile, getJavaJarFile(), kotlinc.getKotlinAnnotationJar()); } private String getTestName() {
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialJavaStyleTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialJavaStyleTest.java index 7b02bdb..41552ac 100644 --- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialJavaStyleTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialJavaStyleTest.java
@@ -5,7 +5,6 @@ package com.android.tools.r8.kotlin.lambda; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_5_0; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.PredicateUtils.not; import static junit.framework.TestCase.assertEquals; import static org.hamcrest.CoreMatchers.containsString; @@ -204,7 +203,7 @@ getCompileMemoizer(getKotlinFilesInResource(getTestName()), getTestName()) .configure(kotlinCompilerTool -> kotlinCompilerTool.includeRuntime().noReflect()) .getForConfiguration(kotlinc, targetVersion); - return ImmutableList.of(kotlinJarFile, getJavaJarFile(), getKotlinAnnotationJar(kotlinc)); + return ImmutableList.of(kotlinJarFile, getJavaJarFile(), kotlinc.getKotlinAnnotationJar()); } private String getTestName() {
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialKotlinStyleTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialKotlinStyleTest.java index cb79d89..b7cc148 100644 --- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialKotlinStyleTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTrivialKotlinStyleTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.kotlin.lambda; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.PredicateUtils.not; import static junit.framework.TestCase.assertEquals; import static org.hamcrest.CoreMatchers.containsString; @@ -162,7 +161,7 @@ getCompileMemoizer(getKotlinFilesInResource(getTestName()), getTestName()) .configure(kotlinCompilerTool -> kotlinCompilerTool.includeRuntime().noReflect()) .getForConfiguration(kotlinc, targetVersion); - return ImmutableList.of(kotlinJarFile, getJavaJarFile(), getKotlinAnnotationJar(kotlinc)); + return ImmutableList.of(kotlinJarFile, getJavaJarFile(), kotlinc.getKotlinAnnotationJar()); } private String getTestName() {
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 23b51d7..06915ec 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
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.lambda.b148525512; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import com.android.tools.r8.DexIndexedConsumer.ArchiveConsumer; @@ -76,7 +74,7 @@ Path featureCode = temp.newFile("feature.zip").toPath(); R8TestCompileResult compileResult = testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(kotlinBaseClasses.getForConfiguration(kotlinc, targetVersion)) .addProgramClasses(FeatureAPI.class) .addKeepMainRule(baseKtClassName)
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java index 0a80034..c1da822 100644 --- a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java
@@ -4,9 +4,7 @@ package com.android.tools.r8.kotlin.lambda.b159688129; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinC_1_3_72; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; +import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_3_72; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; @@ -105,7 +103,7 @@ writeClassFileDataToJar(classFiles, classFileData); return ImmutableList.of( classFiles, - getKotlinStdlibJar(getKotlinC_1_3_72()), - getKotlinAnnotationJar(getKotlinC_1_3_72())); + KOTLINC_1_3_72.getCompiler().getKotlinStdlibJar(), + KOTLINC_1_3_72.getCompiler().getKotlinAnnotationJar()); } }
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 3ce8beb..7bd2b8c 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
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.lambda.b159688129; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.equalTo; @@ -61,7 +59,7 @@ .addSourceFiles(getKotlinFileInTest(folder, "Simple")) .compile(); testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(ktClasses) .setMinApi(parameters.getApiLevel()) .addKeepMainRule(PKG_NAME + ".SimpleKt")
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataFirstToLatestTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataFirstToLatestTest.java index c030f80..de3e23d 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataFirstToLatestTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataFirstToLatestTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -15,7 +13,6 @@ import com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.utils.DescriptorUtils; import com.android.tools.r8.utils.StringUtils; import java.nio.file.Path; @@ -64,7 +61,7 @@ runTest( KotlinCompilerVersion.KOTLINC_1_5_0, libJars.getForConfiguration(kotlinc, targetVersion), - getKotlinStdlibJar(kotlinc)); + kotlinc.getKotlinStdlibJar()); } @Test @@ -72,7 +69,7 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAllClassesRule() .addKeepAllAttributes() .addOptionsModification( @@ -84,8 +81,7 @@ .writeToZip(); Path stdLibJar = testForR8(parameters.getBackend()) - .addProgramFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAllClassesRule() .addKeepAllAttributes() .allowDiagnosticWarningMessages() @@ -109,15 +105,14 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAllClassesRule() .addKeepAllAttributes() .compile() .writeToZip(); Path stdLibJar = testForR8(parameters.getBackend()) - .addProgramFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAllClassesRule() .addKeepAllAttributes() .allowDiagnosticWarningMessages()
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrimitiveTypeRewriteTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrimitiveTypeRewriteTest.java index a9732a4..1dae299 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrimitiveTypeRewriteTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrimitiveTypeRewriteTest.java
@@ -5,8 +5,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; @@ -63,7 +61,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutputLines(EXPECTED); @@ -83,8 +81,8 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles( - getKotlinStdlibJar(kotlinc), - getKotlinAnnotationJar(kotlinc), + kotlinc.getKotlinStdlibJar(), + kotlinc.getKotlinAnnotationJar(), libJars.getForConfiguration(kotlinc, targetVersion)) .addKeepAllClassesRuleWithAllowObfuscation() .addKeepRules("-keep class " + PKG_LIB + ".LibKt { *; }") @@ -110,7 +108,7 @@ .compile(); final JvmTestRunResult runResult = testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt"); if (keepUnit) {
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 505169e..2f27ec3 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
@@ -11,7 +11,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.kotlin.metadata.metadata_pruned_fields.Main; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -45,7 +44,7 @@ @Test public void testR8() throws Exception { testForR8(parameters.getBackend()) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) .addProgramClassFileData(Main.dump()) .addKeepRules("-keep class " + PKG + ".metadata_pruned_fields.MethodsKt { *; }")
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAllowAccessModificationTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAllowAccessModificationTest.java index a02d225..21c1cce 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAllowAccessModificationTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAllowAccessModificationTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static junit.framework.TestCase.assertEquals; import static org.hamcrest.MatcherAssert.assertThat; @@ -83,7 +81,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -97,7 +95,7 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepRules("-keepclassmembers,allowaccessmodification class **.Lib { *; }") .addKeepRules("-keep,allowaccessmodification,allowobfuscation class **.Lib { *; }") .addKeepRules("-keepclassmembers,allowaccessmodification class **.Lib$Comp { *; }")
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java index 5c9a639..440a8d5 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java
@@ -5,7 +5,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; 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; @@ -15,7 +14,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.DescriptorUtils; import com.android.tools.r8.utils.StringUtils; @@ -91,8 +89,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -104,8 +101,8 @@ testForR8(parameters.getBackend()) .addProgramFiles( libJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) - .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) + .addClasspathFiles(kotlinc.getKotlinStdlibJar()) /// Keep the annotations .addKeepClassAndMembersRules(PKG_LIB + ".AnnoWithClassAndEnum") .addKeepClassAndMembersRules(PKG_LIB + ".AnnoWithClassArr") @@ -140,8 +137,7 @@ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main")) .compile(); testForJvm() - .addRunClasspathFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addProgramFiles(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED.replace(FOO_ORIGINAL_NAME, FOO_FINAL_NAME));
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java index 03c8d5a..5437d0d 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java
@@ -5,8 +5,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed; import static org.hamcrest.MatcherAssert.assertThat; @@ -58,7 +56,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".anonymous_app.MainKt") .assertSuccessWithOutputLines(EXPECTED); @@ -68,7 +66,7 @@ public void testMetadataForLib() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) .addKeepAllClassesRuleWithAllowObfuscation() .addKeepRules("-keep class " + PKG + ".anonymous_lib.Test$A { *; }") @@ -88,7 +86,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(main) .run(parameters.getRuntime(), PKG + ".anonymous_app.MainKt") .assertSuccessWithOutputLines(EXPECTED);
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 1cd0805..5e5fc28 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
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertNotNull; @@ -14,7 +12,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.kotlin.KotlinMetadataWriter; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; @@ -64,7 +61,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".box_primitives_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -81,8 +78,7 @@ .compile(); testForJvm() .addVmArguments("-ea") - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".box_primitives_app.Main_reflectKt") .assertSuccessWithOutput(EXPECTED); @@ -92,7 +88,7 @@ public void testMetadataForLib() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) .addKeepAllClassesRule() .addKeepAttributes( @@ -110,8 +106,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(main) .run(parameters.getRuntime(), PKG + ".box_primitives_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -148,7 +143,7 @@ public void testMetadataForReflect() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) .addKeepAllClassesRule() .addKeepAttributes( @@ -166,8 +161,7 @@ .compile(); testForJvm() .addVmArguments("-ea") - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(main) .run(parameters.getRuntime(), PKG + ".box_primitives_app.Main_reflectKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineAnonFunctionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineAnonFunctionTest.java index 5e64b54..cf5d1eb 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineAnonFunctionTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineAnonFunctionTest.java
@@ -4,9 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; - import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; import com.android.tools.r8.utils.DescriptorUtils; @@ -53,7 +50,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -64,7 +61,7 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAllClassesRule() .addKeepAllAttributes() .compile() @@ -76,7 +73,7 @@ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main")) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addProgramFiles(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineConcreteFunctionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineConcreteFunctionTest.java index 8ca888c..52bdbb6 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineConcreteFunctionTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineConcreteFunctionTest.java
@@ -4,9 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; - import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; import com.android.tools.r8.utils.DescriptorUtils; @@ -53,7 +50,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -64,7 +61,7 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAllClassesRule() .addKeepAllAttributes() .compile() @@ -77,7 +74,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDelegatedPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDelegatedPropertyTest.java index ffe8b3a..994a011 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDelegatedPropertyTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDelegatedPropertyTest.java
@@ -4,10 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinReflectJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; - import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; import com.android.tools.r8.shaking.ProguardKeepAttributes; @@ -54,7 +50,7 @@ @Test public void smokeTest() throws Exception { testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinReflectJar(kotlinc)) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar()) .addClasspath(jars.getForConfiguration(kotlinc, targetVersion)) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED_MAIN); @@ -65,9 +61,9 @@ Path outputJar = testForR8(parameters.getBackend()) .addClasspathFiles( - getKotlinStdlibJar(kotlinc), - getKotlinReflectJar(kotlinc), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinStdlibJar(), + kotlinc.getKotlinReflectJar(), + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(jars.getForConfiguration(kotlinc, targetVersion)) .addKeepAllClassesRule() .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS) @@ -80,7 +76,7 @@ (addedStrings, addedNonInitStrings) -> {})) .writeToZip(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinReflectJar(kotlinc)) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar()) .addClasspath(outputJar) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED_MAIN);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeep.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeep.java index ef9c705..8230cef 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeep.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDependentKeep.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -45,7 +43,7 @@ @Test public void testR8() throws CompilationFailedException, IOException, ExecutionException { testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepKotlinMetadata() .addKeepRules(StringUtils.joinLines("-if class *.Metadata", "-keep class <1>.io.** { *; }"))
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmpty.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmpty.java index 08de164..1acdcf2 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmpty.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteDoNotEmitValuesIfEmpty.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -47,7 +45,7 @@ @Test public void testKotlinStdLib() throws Exception { testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepAllClassesRuleWithAllowObfuscation() .addKeepKotlinMetadata()
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java index e37b5fd..15a3391 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java
@@ -5,8 +5,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; 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; @@ -16,7 +14,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -70,7 +67,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".flexible_upper_bound_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -80,7 +77,7 @@ public void testMetadataForLib() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) // Allow renaming A to ensure that we rename in the flexible upper bound type. .addKeepRules("-keep,allowobfuscation class " + PKG_LIB + ".A { *; }") @@ -101,8 +98,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(main) .run(parameters.getRuntime(), PKG + ".flexible_upper_bound_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java index 0785411..8b9e4c1 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -75,7 +73,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), baseLibJar, extLibJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), baseLibJar, extLibJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".classpath_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -87,7 +85,7 @@ Path libJar = testForR8(parameters.getBackend()) .addClasspathFiles( - baseLibJar, getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + baseLibJar, kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(extLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the Extra class and its interface (which has the method). .addKeepRules("-keep class **.Extra") @@ -109,7 +107,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), baseLibJar, libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), baseLibJar, libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".classpath_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java index 6e754e1..dc4535c 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; 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; @@ -75,7 +73,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".companion_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -85,7 +83,7 @@ public void testMetadataInCompanion_kept() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(companionLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep everything .addKeepRules("-keep class **.companion_lib.** { *; }") @@ -107,7 +105,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".companion_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -117,7 +115,7 @@ public void testMetadataInCompanion_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(companionLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the B class and its interface (which has the doStuff method). .addKeepRules("-keep class **.B") @@ -149,7 +147,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".companion_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java index a95ed25..b1001e1 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -16,7 +15,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -72,7 +70,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".extension_function_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -85,7 +83,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( extLibJarMap.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) // Keep the B class and its interface (which has the doStuff method). .addKeepRules("-keep class **.B") .addKeepRules("-keep class **.I { <methods>; }") @@ -108,7 +106,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".extension_function_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -136,8 +134,7 @@ public void testMetadataInExtensionFunction_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(extLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the B class and its interface (which has the doStuff method). .addKeepRules("-keep class **.B") @@ -163,7 +160,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".extension_function_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java index c418067..7f0fc70 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionProperty; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; @@ -71,7 +69,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".extension_property_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -84,7 +82,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( extLibJarMap.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) // Keep the B class and its interface (which has the doStuff method). .addKeepRules("-keep class **.B") .addKeepRules("-keep class **.I { <methods>; }") @@ -104,7 +102,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".extension_property_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -144,7 +142,7 @@ public void testMetadataInExtensionProperty_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(extLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the B class and its interface (which has the doStuff method). .addKeepRules("-keep class **.B") @@ -167,7 +165,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".extension_property_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java index 14d1497..001f000 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -70,7 +68,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".function_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -83,7 +81,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( funLibJarMap.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) // Keep the B class and its interface (which has the doStuff method). .addKeepRules("-keep class **.B") .addKeepRules("-keep class **.I { <methods>; }") @@ -102,7 +100,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".function_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -141,7 +139,7 @@ public void testMetadataInFunction_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(funLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the B class and its interface (which has the doStuff method). .addKeepRules("-keep class **.B") @@ -163,7 +161,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".function_app.MainKt") .assertSuccessWithOutput(EXPECTED);
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 dc2ddce..a4cc7fa 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
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.ToolHelper.getJava8RuntimeJar; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -67,7 +65,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".default_value_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -78,7 +76,9 @@ Path libJar = testForR8(parameters.getBackend()) .addLibraryFiles( - getJava8RuntimeJar(), getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + getJava8RuntimeJar(), + kotlinc.getKotlinStdlibJar(), + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(defaultValueLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep LibKt and applyMap function, along with applyMap$default .addKeepRules("-keep class **.LibKt { *** applyMap*(...); }") @@ -98,7 +98,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".default_value_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java index c2c61a6..2707bc2 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -71,7 +69,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".vararg_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -81,7 +79,7 @@ public void testMetadataInFunctionWithVararg() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(varargLibJarMap.getForConfiguration(kotlinc, targetVersion)) // keep SomeClass#foo, since there is a method reference in the app. .addKeepRules("-keep class **.SomeClass { *** foo(...); }") @@ -103,7 +101,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".vararg_app.MainKt") .assertSuccessWithOutput(EXPECTED);
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 c990029..d8d7e4e 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
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; 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.anyOf; @@ -13,7 +12,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -70,8 +68,7 @@ public void smokeTest() throws Exception { testForJvm() .addRunClasspathFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), - baseLibJarMap.getForConfiguration(kotlinc, targetVersion)) + kotlinc.getKotlinStdlibJar(), baseLibJarMap.getForConfiguration(kotlinc, targetVersion)) .addClasspath( extLibJarMap.getForConfiguration(kotlinc, targetVersion), appJarMap.getForConfiguration(kotlinc, targetVersion)) @@ -88,7 +85,7 @@ .addProgramFiles( extLibJarMap.getForConfiguration(kotlinc, targetVersion), appJarMap.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) // Keep Ext extension method which requires metadata to be called with Kotlin syntax // from other kotlin code. .addKeepRules("-keep class **.ExtKt { <methods>; }") @@ -109,8 +106,7 @@ testForJvm() .addRunClasspathFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), - baseLibJarMap.getForConfiguration(kotlinc, targetVersion)) + kotlinc.getKotlinStdlibJar(), baseLibJarMap.getForConfiguration(kotlinc, targetVersion)) .addClasspath(out) .run(parameters.getRuntime(), main) .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java index 593b124..dfc31a7 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java
@@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -73,7 +71,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".multifileclass_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -83,7 +81,7 @@ public void testMetadataInMultifileClass_merged() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(multifileLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep UtilKt#comma*Join*(). Let R8 optimize (inline) others, such as joinOf*(String). .addKeepRules("-keep class **.UtilKt") @@ -124,7 +122,7 @@ public void testMetadataInMultifileClass_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(multifileLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep UtilKt#comma*Join*(). .addKeepRules("-keep class **.UtilKt")
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java index 24e7a56..97ec9f0 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java
@@ -14,7 +14,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -64,7 +63,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".nested_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -74,7 +73,7 @@ public void testMetadataInNestedClass() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar()) .addProgramFiles(nestedLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the Outer class and delegations. .addKeepRules("-keep class **.Outer { <init>(...); *** delegate*(...); }") @@ -97,7 +96,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".nested_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java index 59d3258..6d69d26 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; 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; @@ -63,7 +61,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".parametertype_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -73,7 +71,7 @@ public void testMetadataInParameterType_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(parameterTypeLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep non-private members of Impl .addKeepRules("-keep public class **.Impl { !private *; }") @@ -92,7 +90,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".parametertype_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java index ebafde8..11e391d 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java
@@ -5,8 +5,6 @@ import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_5_0; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionProperty; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -71,7 +69,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".fragile_property_only_getter.Getter_userKt") .assertSuccessWithOutput(EXPECTED_GETTER); @@ -81,7 +79,7 @@ public void testMetadataInProperty_getterOnly() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(propertyTypeLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep property getters .addKeepRules("-keep class **.Person { <init>(...); }") @@ -100,7 +98,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".fragile_property_only_getter.Getter_userKt") .assertSuccessWithOutput(EXPECTED_GETTER); @@ -162,7 +160,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".fragile_property_only_setter.Setter_userKt") .assertSuccessWithOutputLines(); @@ -172,7 +170,7 @@ public void testMetadataInProperty_setterOnly() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(propertyTypeLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep property setters (and users) .addKeepRules("-keep class **.Person { <init>(...); }") @@ -195,7 +193,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".fragile_property_only_setter.Setter_userKt") .assertSuccessWithOutputLines();
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java index e0233d9..06ed6a6 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; 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; @@ -63,7 +61,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".propertytype_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -73,7 +71,7 @@ public void testMetadataInProperty_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(propertyTypeLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep non-private members of Impl .addKeepRules("-keep public class **.Impl { !private *; }") @@ -90,7 +88,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".propertytype_app.MainKt") .assertSuccessWithOutput(EXPECTED);
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 7badf74..8bcbc9e 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
@@ -61,7 +61,7 @@ .addLibraryFiles( annoJarMap.getForConfiguration(kotlinc, targetVersion), ToolHelper.getJava8RuntimeJar(), - ToolHelper.getKotlinStdlibJar(kotlinc)) + kotlinc.getKotlinStdlibJar()) .addProgramFiles(inputJarMap.getForConfiguration(kotlinc, targetVersion)) .addKeepRules(OBFUSCATE_RENAMED, KEEP_KEPT) .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS) @@ -73,8 +73,7 @@ public void testR8_kotlinStdlibAsClassPath() throws Exception { testForR8(parameters.getBackend()) .addClasspathFiles( - annoJarMap.getForConfiguration(kotlinc, targetVersion), - ToolHelper.getKotlinStdlibJar(kotlinc)) + annoJarMap.getForConfiguration(kotlinc, targetVersion), kotlinc.getKotlinStdlibJar()) .addProgramFiles(inputJarMap.getForConfiguration(kotlinc, targetVersion)) .addKeepRules(OBFUSCATE_RENAMED, KEEP_KEPT) .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS) @@ -86,8 +85,7 @@ public void testR8_kotlinStdlibAsProgramFile() throws Exception { testForR8(parameters.getBackend()) .addProgramFiles( - annoJarMap.getForConfiguration(kotlinc, targetVersion), - ToolHelper.getKotlinStdlibJar(kotlinc)) + annoJarMap.getForConfiguration(kotlinc, targetVersion), kotlinc.getKotlinStdlibJar()) .addProgramFiles(inputJarMap.getForConfiguration(kotlinc, targetVersion)) .addKeepRules(OBFUSCATE_RENAMED, KEEP_KEPT) .addKeepRules("-keep class **.Anno")
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java index ac35453..59d626b 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; 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; @@ -63,7 +61,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".returntype_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -73,7 +71,7 @@ public void testMetadataInReturnType_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(returnTypeLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep non-private members of Impl .addKeepRules("-keep public class **.Impl { !private *; }") @@ -92,7 +90,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".returntype_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassNestedTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassNestedTest.java index defd730..eacdadb 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassNestedTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassNestedTest.java
@@ -3,12 +3,8 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; - import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.DescriptorUtils; import com.android.tools.r8.utils.StringUtils; @@ -59,8 +55,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -70,7 +65,7 @@ public void testMetadataInSealedClass_nested() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(sealedLibJarMap.getForConfiguration(kotlinc, targetVersion)) .addKeepAllClassesRule() .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS) @@ -86,8 +81,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED);
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 d3380e6..833ba26 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
@@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; @@ -67,7 +65,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".sealed_app.ValidKt") .assertSuccessWithOutput(EXPECTED); @@ -77,7 +75,7 @@ public void testMetadataInSealedClass_valid() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(sealedLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the Expr class .addKeepRules("-keep class **.Expr") @@ -98,7 +96,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".sealed_app.ValidKt") .assertSuccessWithOutput(EXPECTED); @@ -144,7 +142,7 @@ public void testMetadataInSealedClass_invalid() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(sealedLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep the Expr class .addKeepRules("-keep class **.Expr")
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java index ffa0888..7aa3952 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java
@@ -13,7 +13,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -65,7 +64,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".supertype_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -75,7 +74,7 @@ public void testMetadataInSupertype_merged() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar()) .addProgramFiles(superTypeLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep non-private members except for ones in `internal` definitions. .addKeepRules("-keep public class !**.internal.**, * { !private *; }") @@ -92,7 +91,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".supertype_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -120,7 +119,7 @@ public void testMetadataInSupertype_renamed() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar()) .addProgramFiles(superTypeLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep non-private members except for ones in `internal` definitions. .addKeepRules("-keep public class !**.internal.**, * { !private *; }") @@ -139,7 +138,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".supertype_app.MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java index 32be357..8482191 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java
@@ -4,9 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinReflectJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isDexClass; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed; @@ -95,7 +92,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".typealias_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -108,9 +105,9 @@ Path libJar = testForR8(parameters.getBackend()) .addClasspathFiles( - getKotlinStdlibJar(kotlinc), - getKotlinReflectJar(kotlinc), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinStdlibJar(), + kotlinc.getKotlinReflectJar(), + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(typeAliasLibJarMap.getForConfiguration(kotlinc, targetVersion)) // Keep non-private members of Impl .addKeepRules("-keep class **.Impl { !private *; }") @@ -144,7 +141,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(appJar) .run(parameters.getRuntime(), PKG + ".typealias_app.MainKt") .assertSuccessWithOutput(EXPECTED.replace(superTypeName, renamedSuperTypeName));
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java index d5342de..18fce95 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isDexClass; import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; @@ -108,7 +106,7 @@ .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".typeargument_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -118,7 +116,7 @@ public void testMetadataInTypeAliasWithR8() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(jarMap.getForConfiguration(kotlinc, targetVersion)) // Keep ClassThatWillBeObfuscated, but allow minification. .addKeepRules("-keep,allowobfuscation class **ClassThatWillBeObfuscated") @@ -144,7 +142,7 @@ .addSourceFiles(getKotlinFileInTest(PKG_PREFIX + "/typeargument_app", "main")) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(mainJar) .run(parameters.getRuntime(), PKG + ".typeargument_app.MainKt") .assertSuccessWithOutput(EXPECTED);
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 ab449b7..94b410e 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
@@ -4,15 +4,12 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertNull; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.kotlin.KotlinMetadataWriter; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; @@ -61,7 +58,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG + ".inline_property_app.MainKt") .assertSuccessWithOutput(EXPECTED); @@ -71,7 +68,7 @@ public void testMetadataForLib() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) // Allow renaming A to ensure that we rename in the flexible upper bound type. .addKeepAllClassesRule() @@ -90,8 +87,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(main) .run(parameters.getRuntime(), PKG + ".inline_property_app.MainKt") .assertSuccessWithOutput(EXPECTED);
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 48007f1..5cc9de6 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
@@ -13,7 +13,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.ProgramConsumer; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.CodeInspector; @@ -63,8 +62,7 @@ assumeTrue(parameters.isCfRuntime()); Path libJar = jarMap.getForConfiguration(kotlinc, targetVersion); testForRuntime(parameters) - .addProgramFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .run(parameters.getRuntime(), PKG_NESTED_REFLECT + ".MainKt") .assertSuccessWithOutput(EXPECTED); } @@ -73,9 +71,9 @@ public void testMetadataOuterRenamed() throws Exception { Path mainJar = testForR8(parameters.getBackend()) - .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) - .addClasspathFiles(ToolHelper.getKotlinReflectJar(kotlinc)) - .addClasspathFiles(ToolHelper.getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar()) + .addClasspathFiles(kotlinc.getKotlinReflectJar()) + .addClasspathFiles(kotlinc.getKotlinAnnotationJar()) .addProgramFiles(jarMap.getForConfiguration(kotlinc, targetVersion)) .addKeepRules("-keep public class " + PKG_NESTED_REFLECT + ".Outer$Nested { *; }") .addKeepRules("-keep public class " + PKG_NESTED_REFLECT + ".Outer$Inner { *; }") @@ -93,9 +91,9 @@ public void testMetadataOuterNotRenamed() throws Exception { Path mainJar = testForR8(parameters.getBackend()) - .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) - .addClasspathFiles(ToolHelper.getKotlinReflectJar(kotlinc)) - .addClasspathFiles(ToolHelper.getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar()) + .addClasspathFiles(kotlinc.getKotlinReflectJar()) + .addClasspathFiles(kotlinc.getKotlinAnnotationJar()) .addProgramFiles(jarMap.getForConfiguration(kotlinc, targetVersion)) .addKeepAttributeInnerClassesAndEnclosingMethod() .addKeepRules("-keep public class " + PKG_NESTED_REFLECT + ".Outer { *; }") @@ -118,8 +116,7 @@ ? new ClassFileConsumer.ArchiveConsumer(output, true) : new ArchiveConsumer(output, true); testForD8(parameters.getBackend()) - .addProgramFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), jar) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), jar) .setMinApi(parameters.getApiLevel()) .setProgramConsumer(programConsumer) .addOptionsModification(
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteJvmStaticTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteJvmStaticTest.java index 2c378c6..cd667d3 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteJvmStaticTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteJvmStaticTest.java
@@ -3,15 +3,13 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.kotlin.metadata.jvmstatic_app.MainJava; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.DescriptorUtils; @@ -70,7 +68,7 @@ .compile(); testForJvm() .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) + kotlinc.getKotlinStdlibJar(), kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -80,7 +78,7 @@ public void smokeTestJava() throws Exception { testForJvm() .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) + kotlinc.getKotlinStdlibJar(), kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) .addProgramClassFileData(MainJava.dump()) .run(parameters.getRuntime(), MainJava.class) .assertSuccessWithOutput(EXPECTED); @@ -91,7 +89,7 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles(kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAllClassesRule() .addKeepAttributes( ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS, @@ -113,7 +111,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -121,7 +119,7 @@ private void testJava(Path libJar) throws Exception { testForJvm() - .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addProgramClassFileData(MainJava.dump()) .run(parameters.getRuntime(), MainJava.class) .assertSuccessWithOutput(EXPECTED);
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 8d01e2e..07faab6 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
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -51,7 +49,7 @@ public void testProgramPath() throws Exception { testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepRules("-keep class " + LIB_CLASS_NAME) .applyIf(keepMetadata, TestShrinkerBuilder::addKeepKotlinMetadata) .addKeepRuntimeVisibleAnnotations() @@ -65,7 +63,7 @@ public void testClassPathPath() throws Exception { testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepRules("-keep class " + LIB_CLASS_NAME) .addKeepRuntimeVisibleAnnotations() .compile() @@ -76,7 +74,7 @@ public void testLibraryPath() throws Exception { testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addLibraryFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addLibraryFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addLibraryFiles(ToolHelper.getJava8RuntimeJar()) .addKeepRules("-keep class " + LIB_CLASS_NAME) .addKeepRuntimeVisibleAnnotations() @@ -88,7 +86,7 @@ public void testMissing() throws Exception { testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepRules("-keep class " + LIB_CLASS_NAME) .addKeepRuntimeVisibleAnnotations() .compile()
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 b49f740..68731b5 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,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -40,7 +38,7 @@ @Test public void testR8() throws Exception { testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepKotlinMetadata() .addKeepRules("-keep class kotlin.io.** { *; }") @@ -54,7 +52,7 @@ @Test public void testR8KeepIf() throws Exception { testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepRules("-keep class kotlin.io.** { *; }") .addKeepRules("-if class *", "-keep class kotlin.Metadata { *; }")
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java index b175132..64e7bd8 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java
@@ -4,16 +4,14 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.AndroidApiLevel; import com.android.tools.r8.utils.codeinspector.CodeInspector; @@ -47,7 +45,7 @@ public void testKotlinStdLib() throws Exception { assumeFalse(parameters.isNoneRuntime()); testForR8(parameters.getBackend()) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepAllClassesRule() .addKeepKotlinMetadata() @@ -61,7 +59,7 @@ .inspect( inspector -> assertEqualMetadata( - new CodeInspector(getKotlinStdlibJar(kotlinc)), + new CodeInspector(kotlinc.getKotlinStdlibJar()), inspector, (addedStrings, addedNonInitStrings) -> { assertEquals(0, addedStrings.intValue()); @@ -73,13 +71,13 @@ public void testKotlinStdLibD8() throws Exception { assumeTrue(parameters.isNoneRuntime()); testForD8(Backend.DEX) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .setMinApi(AndroidApiLevel.B) .compile() .inspect( inspector -> assertEqualMetadata( - new CodeInspector(getKotlinStdlibJar(kotlinc)), + new CodeInspector(kotlinc.getKotlinStdlibJar()), inspector, (addedStrings, addedNonInitStrings) -> { assertEquals(0, addedStrings.intValue());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java index 9b8a8e7..0cf8903 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java
@@ -12,7 +12,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.utils.DescriptorUtils; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -63,7 +62,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -74,8 +73,7 @@ Path libJar = testForR8(parameters.getBackend()) .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion)) - .addClasspathFiles( - ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepRules( "-keep class " + PKG_LIB + ".Sub { <init>(); *** kept(); *** keptProperty; }") .addKeepRules("-neverinline class * { @" + PKG_LIB + ".NeverInline *; }") @@ -93,7 +91,7 @@ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main")) .compile(); testForJvm() - .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), libJar) .addProgramFiles(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java index fafb083..07e22c5 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java
@@ -5,10 +5,7 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION; -import static com.android.tools.r8.ToolHelper.KotlinTargetVersion.JAVA_8; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinReflectJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; +import static com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion.JAVA_8; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -16,7 +13,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.kotlin.KotlinMetadataWriter; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.DescriptorUtils; @@ -87,8 +83,8 @@ .compile(); testForJvm() .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), - getKotlinReflectJar(kotlinc), + kotlinc.getKotlinStdlibJar(), + kotlinc.getKotlinReflectJar(), kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") @@ -99,10 +95,10 @@ public void testMetadataForLib() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinAnnotationJar()) .addProgramFiles( kotlincLibJar.getForConfiguration(kotlinc, targetVersion), - getKotlinStdlibJar(kotlinc)) + kotlinc.getKotlinStdlibJar()) .addKeepClassAndMembersRules(PKG_LIB + ".*") .addKeepAttributes( ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS, @@ -124,8 +120,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(main) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteValueClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteValueClassTest.java index cc26b5c..29fa8ec 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteValueClassTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteValueClassTest.java
@@ -5,9 +5,7 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_5_0; -import static com.android.tools.r8.ToolHelper.KotlinTargetVersion.JAVA_8; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; +import static com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion.JAVA_8; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.StringContains.containsString; @@ -15,7 +13,6 @@ import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import com.android.tools.r8.kotlin.KotlinMetadataWriter; import com.android.tools.r8.shaking.ProguardKeepAttributes; import com.android.tools.r8.utils.DescriptorUtils; @@ -72,7 +69,7 @@ .compile(); testForJvm() .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) + kotlinc.getKotlinStdlibJar(), kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) .addClasspath(output) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED); @@ -82,7 +79,7 @@ public void testMetadataForLib() throws Exception { Path libJar = testForR8(parameters.getBackend()) - .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(kotlincLibJar.getForConfiguration(kotlinc, targetVersion)) .addKeepAllClassesRule() .addKeepAttributes( @@ -105,8 +102,7 @@ .setOutputPath(temp.newFolder().toPath()) .compile(); testForJvm() - .addRunClasspathFiles( - getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar) + .addRunClasspathFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinReflectJar(), libJar) .addClasspath(main) .run(parameters.getRuntime(), PKG_APP + ".MainKt") .assertSuccessWithOutput(EXPECTED);
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 9490133..5d715f1 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
@@ -4,8 +4,6 @@ package com.android.tools.r8.kotlin.metadata; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_3_72; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinReflectJar; 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; @@ -54,7 +52,7 @@ testForR8(parameters.getBackend()) .addProgramFiles(compiledJars.getForConfiguration(kotlinc, targetVersion)) .addProgramFiles(getJavaJarFile(FOLDER)) - .addProgramFiles(getKotlinReflectJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinReflectJar(), kotlinc.getKotlinAnnotationJar()) .addKeepMainRule(mainClassName) .addKeepKotlinMetadata() .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataVersionNumberBumpTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataVersionNumberBumpTest.java index b0ea3d9..84139d9 100644 --- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataVersionNumberBumpTest.java +++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataVersionNumberBumpTest.java
@@ -4,17 +4,15 @@ package com.android.tools.r8.kotlin.metadata; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.objectweb.asm.Opcodes.ASM7; import com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.R8FullTestBuilder; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.graph.DexAnnotationElement; import com.android.tools.r8.references.Reference; import com.android.tools.r8.shaking.ProguardKeepAttributes; @@ -61,7 +59,7 @@ final R8FullTestBuilder testBuilder = testForR8(parameters.getBackend()); rewriteMetadataVersion(testBuilder::addProgramClassFileData, new int[] {1, 1, 16}); testBuilder - .addProgramFiles(getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addOptionsModification(options -> options.testing.keepMetadataInR8IfNotRewritten = false) .addKeepAllClassesRuleWithAllowObfuscation() @@ -75,7 +73,7 @@ final R8FullTestBuilder testBuilder = testForR8(parameters.getBackend()); rewriteMetadataVersion(testBuilder::addProgramClassFileData, new int[] {1, 4, 0}); testBuilder - .addProgramFiles(getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepAllClassesRuleWithAllowObfuscation() .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS) @@ -88,7 +86,7 @@ final R8FullTestBuilder testBuilder = testForR8(parameters.getBackend()); rewriteMetadataVersion(testBuilder::addProgramClassFileData, new int[] {1, 4, 2}); testBuilder - .addProgramFiles(getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepAllClassesRuleWithAllowObfuscation() .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS) @@ -99,7 +97,7 @@ private void rewriteMetadataVersion(Consumer<byte[]> rewrittenBytesConsumer, int[] newVersion) throws IOException { ZipUtils.iter( - ToolHelper.getKotlinStdlibJar(kotlinc).toString(), + kotlinc.getKotlinStdlibJar().toString(), ((entry, input) -> { if (!entry.getName().endsWith(".class")) { return;
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 ca9fbd2..b14aeb4 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
@@ -4,7 +4,6 @@ package com.android.tools.r8.kotlin.optimize.switches; -import static com.android.tools.r8.ToolHelper.getMostRecentKotlinAnnotationJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -53,7 +52,7 @@ public void test() throws Exception { testForR8(parameters.getBackend()) .addProgramFiles( - kotlinJars.getForConfiguration(kotlinParameters), getMostRecentKotlinAnnotationJar()) + kotlinJars.getForConfiguration(kotlinParameters), kotlinc.getKotlinAnnotationJar()) .addKeepMainRule("enumswitch.EnumSwitchKt") .addOptionsModification( options -> {
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 d448e96..1ad87d5 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
@@ -57,8 +57,8 @@ assumeTrue(parameters.isCfRuntime()); testForJvm() .addProgramFiles(compiledJars.getForConfiguration(kotlinc, targetVersion)) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) - .addProgramFiles(ToolHelper.getKotlinReflectJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) + .addProgramFiles(kotlinc.getKotlinReflectJar()) .run(parameters.getRuntime(), PKG + ".SimpleReflectKt") .assertSuccessWithOutputLines(EXPECTED_OUTPUT); } @@ -69,8 +69,8 @@ final File output = temp.newFile("output.zip"); testForD8(parameters.getBackend()) .addProgramFiles(compiledJars.getForConfiguration(kotlinc, targetVersion)) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) - .addProgramFiles(ToolHelper.getKotlinReflectJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) + .addProgramFiles(kotlinc.getKotlinReflectJar()) .setProgramConsumer(new ArchiveConsumer(output.toPath(), true)) .setMinApi(parameters.getApiLevel()) .addOptionsModification( @@ -87,9 +87,9 @@ final File foo = temp.newFile("foo"); testForR8(parameters.getBackend()) .addProgramFiles(compiledJars.getForConfiguration(kotlinc, targetVersion)) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) - .addProgramFiles(ToolHelper.getKotlinReflectJar(kotlinc)) - .addProgramFiles(ToolHelper.getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) + .addProgramFiles(kotlinc.getKotlinReflectJar()) + .addProgramFiles(kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .addKeepAllClassesRule() .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
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 3422030..5bbd532 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,8 +5,6 @@ package com.android.tools.r8.kotlin.sealed; import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static org.hamcrest.CoreMatchers.equalTo; import com.android.tools.r8.CompilationFailedException; @@ -58,7 +56,7 @@ public void testRuntime() throws ExecutionException, CompilationFailedException, IOException { testForRuntime(parameters) .addProgramFiles(compilationResults.getForConfiguration(kotlinc, targetVersion)) - .addRunClasspathFiles(buildOnDexRuntime(parameters, getKotlinStdlibJar(kotlinc))) + .addRunClasspathFiles(buildOnDexRuntime(parameters, kotlinc.getKotlinStdlibJar())) .run(parameters.getRuntime(), MAIN) .assertSuccessWithOutputLines(EXPECTED); } @@ -67,8 +65,8 @@ public void testR8() throws ExecutionException, CompilationFailedException, IOException { testForR8(parameters.getBackend()) .addProgramFiles(compilationResults.getForConfiguration(kotlinc, targetVersion)) - .addProgramFiles(buildOnDexRuntime(parameters, getKotlinStdlibJar(kotlinc))) - .addProgramFiles(getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(buildOnDexRuntime(parameters, kotlinc.getKotlinStdlibJar())) + .addProgramFiles(kotlinc.getKotlinAnnotationJar()) .setMinApi(parameters.getApiLevel()) .allowAccessModification() .allowDiagnosticWarningMessages()
diff --git a/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java b/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java index 19e75b3..76e19f6 100644 --- a/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java +++ b/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java
@@ -4,11 +4,10 @@ package com.android.tools.r8.maindexlist.warnings; -import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestParametersCollection; @@ -16,7 +15,6 @@ import com.android.tools.r8.utils.codeinspector.CodeInspector; import com.google.common.collect.ImmutableList; import java.util.List; -import org.hamcrest.CoreMatchers; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -45,8 +43,8 @@ } private void classStaticGone(CodeInspector inspector) { - assertThat(inspector.clazz(Static.class), CoreMatchers.not(isPresent())); - assertThat(inspector.clazz(Static2.class), CoreMatchers.not(isPresent())); + assertThat(inspector.clazz(Static.class), isAbsent()); + assertThat(inspector.clazz(Static2.class), isAbsent()); } @Test @@ -57,7 +55,6 @@ .addKeepMainRule(mainClass) // Include main dex rule for class Static. .addMainDexKeepClassRules(Main.class, Static.class) - .enableForceInliningAnnotations() .setMinApi(parameters.getApiLevel()) .compile() .inspect(this::classStaticGone) @@ -74,7 +71,6 @@ // Include explicit main dex entry for class Static. .addMainDexListClasses(Static.class) .allowDiagnosticWarningMessages() - .enableForceInliningAnnotations() .setMinApi(parameters.getApiLevel()) .compile() .inspect(this::classStaticGone) @@ -96,7 +92,6 @@ .addMainDexKeepClassRules(Static2.class) .addDontWarn(Static.class) .allowDiagnosticWarningMessages() - .enableForceInliningAnnotations() .setMinApi(parameters.getApiLevel()) .compile() .inspect(this::classStaticGone) @@ -116,14 +111,12 @@ } class Static { - @ForceInline public static int m() { return 1; } } class Static2 { - @ForceInline public static int m() { return 1; }
diff --git a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java index 61387ea..eaac9ca 100644 --- a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java +++ b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
@@ -4,11 +4,14 @@ package com.android.tools.r8.movestringconstants; +import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static junit.framework.TestCase.assertEquals; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; +import com.android.tools.r8.AlwaysInline; import com.android.tools.r8.CompilationMode; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.NeverInline; import com.android.tools.r8.R8Command; import com.android.tools.r8.TestBase; @@ -41,21 +44,20 @@ private void runTest(Consumer<CodeInspector> inspection) throws Exception { R8Command.Builder builder = R8Command.builder(); - builder.addProgramFiles(ToolHelper.getClassFileForTestClass(ForceInline.class)); builder.addProgramFiles(ToolHelper.getClassFileForTestClass(NeverInline.class)); builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestClass.class)); builder.addProgramFiles(ToolHelper.getClassFileForTestClass(Utils.class)); + builder.addProgramFiles(ToolHelper.getClassFileForTestClass(AlwaysInline.class)); builder.addLibraryFiles(runtimeJar(backend)); builder.setProgramConsumer(emptyConsumer(backend)); builder.setMode(CompilationMode.RELEASE); builder.addProguardConfiguration( ImmutableList.of( - "-forceinline class * { @com.android.tools.r8.ForceInline *; }", + "-alwaysinline class * { @com.android.tools.r8.AlwaysInline *; }", "-neverinline class * { @com.android.tools.r8.NeverInline *; }", "-keep class " + TestClass.class.getCanonicalName() + "{ *; }", "-dontobfuscate", - "-allowaccessmodification" - ), + "-allowaccessmodification"), Origin.unknown()); ToolHelper.allowTestProguardOptions(builder); AndroidApp app = ToolHelper.runR8(builder.build()); @@ -125,6 +127,11 @@ insn -> insn.isConstString("StringConstants::foo#1", JumboStringMode.DISALLOW), InstructionSubject::isInvokeStatic, InstructionSubject::isThrow); + + ClassSubject utilsClassSubject = inspector.clazz(Utils.class); + assertThat(utilsClassSubject, isPresent()); + assertThat(utilsClassSubject.uniqueMethodWithName("throwException"), isPresent()); + assertEquals(1, utilsClassSubject.allMethods().size()); } @SafeVarargs
diff --git a/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java b/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java index 2af704d..7df59d9 100644 --- a/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java +++ b/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java
@@ -4,7 +4,7 @@ package com.android.tools.r8.movestringconstants; -import com.android.tools.r8.ForceInline; +import com.android.tools.r8.AlwaysInline; import com.android.tools.r8.NeverInline; public class TestClass { @@ -30,7 +30,7 @@ } class Utils { - @ForceInline + @AlwaysInline static void check(Object value, String message) { if (value == null) { throwException(message);
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 80d865e..1652222 100644 --- a/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java +++ b/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.naming; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; 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; @@ -56,7 +55,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .addKeepMainRule(MAIN_CLASS_NAME) .addKeepClassRulesWithAllowObfuscation(ENUM_CLASS_NAME)
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 c129553..e6f1c6d 100644 --- a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java +++ b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.naming; import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_3_72; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -94,7 +93,7 @@ testForR8(Backend.DEX) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .addKeepMainRule(mainClassName) .addKeepRules( @@ -154,7 +153,7 @@ testForR8(Backend.DEX) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .enableProguardTestOptions() .addKeepMainRule(mainClassName)
diff --git a/src/test/java/com/android/tools/r8/naming/b139991218/TestRunner.java b/src/test/java/com/android/tools/r8/naming/b139991218/TestRunner.java index 22a3470..559f6a0 100644 --- a/src/test/java/com/android/tools/r8/naming/b139991218/TestRunner.java +++ b/src/test/java/com/android/tools/r8/naming/b139991218/TestRunner.java
@@ -4,16 +4,15 @@ package com.android.tools.r8.naming.b139991218; -import static com.android.tools.r8.ToolHelper.getMostRecentKotlinAnnotationJar; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; import com.android.tools.r8.CompilationFailedException; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestBase; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.ir.optimize.Inliner.Reason; import com.google.common.collect.ImmutableSet; import java.io.IOException; @@ -62,7 +61,7 @@ testForR8(parameters.getBackend()) .addProgramClassFileData(Lambda1.dump(), Lambda2.dump(), Main.dump(), Alpha.dump()) .addProgramFiles( - kotlinJars.getForConfiguration(kotlinParameters), getMostRecentKotlinAnnotationJar()) + kotlinJars.getForConfiguration(kotlinParameters), kotlinc.getKotlinAnnotationJar()) .addKeepMainRule(Main.class) .addKeepAllAttributes() .addOptionsModification(
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java index 344a716..be514ec 100644 --- a/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java +++ b/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java
@@ -12,8 +12,6 @@ import static org.junit.Assume.assumeTrue; import com.android.tools.r8.CompilationMode; -import com.android.tools.r8.ForceInline; -import com.android.tools.r8.R8TestBuilder; import com.android.tools.r8.TestParameters; import com.android.tools.r8.utils.BooleanUtils; import com.android.tools.r8.utils.codeinspector.CodeInspector; @@ -83,13 +81,6 @@ } @Override - public void configure(R8TestBuilder<?> builder) { - builder - .addForceInliningAnnotations() - .applyIf(mode == CompilationMode.RELEASE, R8TestBuilder::enableForceInliningAnnotations); - } - - @Override public void inspect(CodeInspector inspector) { if (mode == CompilationMode.RELEASE) { assertEquals(compat ? 2 : 1, inspector.clazz(Main.class).allMethods().size()); @@ -99,13 +90,11 @@ class Main { - @ForceInline public static void method3(long j) { System.out.println("In method3"); throw null; } - @ForceInline public static void method2(int j) { System.out.println("In method2"); for (int i = 0; i < 10; i++) { @@ -113,7 +102,6 @@ } } - @ForceInline public static void method1(String s) { System.out.println("In method1"); for (int i = 0; i < 10; i++) {
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java b/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java index 2583b6e..d91a506 100644 --- a/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java +++ b/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java
@@ -6,49 +6,60 @@ import static org.junit.Assert.assertEquals; -import com.android.tools.r8.ForceInline; 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 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 LineDeltaTest extends TestBase { - public String runTest(Backend backend) throws Exception { - return testForR8(backend) - .enableForceInliningAnnotations() - .addProgramClasses(LineDeltaTestClass.class) - .addKeepMainRule(LineDeltaTestClass.class) - .addKeepRules("-keepattributes LineNumberTable") - .run(LineDeltaTestClass.class) - .assertSuccessWithOutput( - StringUtils.lines( - "In test1() - 1", - "In test1() - 2", - "In test1() - 3", - "In test1() - 4", - "In test2() - 1", - "In test2() - 2", - "In test2() - 3", - "In test2() - 4")) - .proguardMap(); + + @Parameter(0) + public TestParameters parameters; + + @Parameters(name = "{0}") + public static TestParametersCollection parameters() { + return getTestParameters().withAllRuntimesAndApiLevels().build(); + } + + @Test + public void test() throws Exception { + String proguardMap = + testForR8(parameters.getBackend()) + .addProgramClasses(LineDeltaTestClass.class) + .addKeepMainRule(LineDeltaTestClass.class) + .addKeepRules("-keepattributes LineNumberTable") + .setMinApi(parameters.getApiLevel()) + .compile() + .inspect( + inspector -> + assertEquals(1, inspector.clazz(LineDeltaTestClass.class).allMethods().size())) + .run(parameters.getRuntime(), LineDeltaTestClass.class) + .assertSuccessWithOutput( + StringUtils.lines( + "In test1() - 1", + "In test1() - 2", + "In test1() - 3", + "In test1() - 4", + "In test2() - 1", + "In test2() - 2", + "In test2() - 3", + "In test2() - 4")) + .proguardMap(); + assertEquals(parameters.isCfRuntime() ? 5 : 17, mapLines(proguardMap)); } private long mapLines(String map) { return StringUtils.splitLines(map).stream().filter(line -> !line.startsWith("#")).count(); } - - @Test - public void testDex() throws Exception { - assertEquals(17, mapLines(runTest(Backend.DEX))); - } - - @Test - public void testCf() throws Exception { - assertEquals(5, mapLines(runTest(Backend.CF))); - } } class LineDeltaTestClass { - @ForceInline static void test1() { System.out.println("In test1() - 1"); // One line comment. @@ -63,7 +74,6 @@ System.out.println("In test1() - 4"); } - @ForceInline static void test2() { System.out.println("In test2() - 1"); // Seven line comments.
diff --git a/src/test/java/com/android/tools/r8/naming/retraceproguard/InliningRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retraceproguard/InliningRetraceTest.java index 8d94fc8..ae6a985 100644 --- a/src/test/java/com/android/tools/r8/naming/retraceproguard/InliningRetraceTest.java +++ b/src/test/java/com/android/tools/r8/naming/retraceproguard/InliningRetraceTest.java
@@ -11,7 +11,6 @@ import static org.junit.Assume.assumeTrue; import com.android.tools.r8.CompilationMode; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.ToolHelper; import com.android.tools.r8.ToolHelper.DexVm.Version; import com.android.tools.r8.utils.BooleanUtils; @@ -85,13 +84,11 @@ class Main { - @ForceInline public static void method3(long j) { System.out.println("In method3"); throw null; } - @ForceInline public static void method2(int j) { System.out.println("In method2"); for (int i = 0; i < 10; i++) { @@ -99,7 +96,6 @@ } } - @ForceInline public static void method1(String s) { System.out.println("In method1"); for (int i = 0; i < 10; i++) {
diff --git a/src/test/java/com/android/tools/r8/naming/retraceproguard/LineDeltaTest.java b/src/test/java/com/android/tools/r8/naming/retraceproguard/LineDeltaTest.java index a96ad88..273adb0 100644 --- a/src/test/java/com/android/tools/r8/naming/retraceproguard/LineDeltaTest.java +++ b/src/test/java/com/android/tools/r8/naming/retraceproguard/LineDeltaTest.java
@@ -6,49 +6,60 @@ import static org.junit.Assert.assertEquals; -import com.android.tools.r8.ForceInline; 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 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 LineDeltaTest extends TestBase { - public String runTest(Backend backend) throws Exception { - return testForR8(backend) - .enableForceInliningAnnotations() - .addProgramClasses(LineDeltaTestClass.class) - .addKeepMainRule(LineDeltaTestClass.class) - .addKeepRules("-keepattributes LineNumberTable") - .run(LineDeltaTestClass.class) - .assertSuccessWithOutput( - StringUtils.lines( - "In test1() - 1", - "In test1() - 2", - "In test1() - 3", - "In test1() - 4", - "In test2() - 1", - "In test2() - 2", - "In test2() - 3", - "In test2() - 4")) - .proguardMap(); + + @Parameter(0) + public TestParameters parameters; + + @Parameters(name = "{0}") + public static TestParametersCollection parameters() { + return getTestParameters().withAllRuntimesAndApiLevels().build(); + } + + @Test + public void test() throws Exception { + String proguardMap = + testForR8(parameters.getBackend()) + .addProgramClasses(LineDeltaTestClass.class) + .addKeepMainRule(LineDeltaTestClass.class) + .addKeepRules("-keepattributes LineNumberTable") + .setMinApi(parameters.getApiLevel()) + .compile() + .inspect( + inspector -> + assertEquals(1, inspector.clazz(LineDeltaTestClass.class).allMethods().size())) + .run(parameters.getRuntime(), LineDeltaTestClass.class) + .assertSuccessWithOutput( + StringUtils.lines( + "In test1() - 1", + "In test1() - 2", + "In test1() - 3", + "In test1() - 4", + "In test2() - 1", + "In test2() - 2", + "In test2() - 3", + "In test2() - 4")) + .proguardMap(); + assertEquals(parameters.isCfRuntime() ? 5 : 17, mapLines(proguardMap)); } private long mapLines(String map) { return StringUtils.splitLines(map).stream().filter(line -> !line.startsWith("#")).count(); } - - @Test - public void testDex() throws Exception { - assertEquals(17, mapLines(runTest(Backend.DEX))); - } - - @Test - public void testCf() throws Exception { - assertEquals(5, mapLines(runTest(Backend.CF))); - } } class LineDeltaTestClass { - @ForceInline static void test1() { System.out.println("In test1() - 1"); // One line comment. @@ -63,7 +74,6 @@ System.out.println("In test1() - 4"); } - @ForceInline static void test2() { System.out.println("In test2() - 1"); // Seven line comments.
diff --git a/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java b/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java index 62c4de9..c84c685 100644 --- a/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java +++ b/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java
@@ -53,7 +53,6 @@ .setMode(mode) .enableProguardTestOptions() .addProgramClasses(getClasses()) - .addForceInliningAnnotations() .addKeepMainRule(getMainClass()) .addKeepRules(keepRules) .apply(this::configure)
diff --git a/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java b/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java index 42cd37e..d2e1d70 100644 --- a/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java +++ b/src/test/java/com/android/tools/r8/neverreturnsnormally/NeverReturnsNormallyTest.java
@@ -9,7 +9,6 @@ import static org.junit.Assert.assertTrue; import com.android.tools.r8.CompilationMode; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.R8Command; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; @@ -56,14 +55,12 @@ BiConsumer<CodeInspector, CompilationMode> inspection, boolean enableClassInliner, CompilationMode mode) throws Exception { R8Command.Builder builder = R8Command.builder(); - builder.addProgramFiles(ToolHelper.getClassFileForTestClass(ForceInline.class)); builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestClass.class)); builder.setProgramConsumer(emptyConsumer(parameters.getBackend())); builder.addLibraryFiles(runtimeJar(parameters.getBackend())); builder.setMode(mode); builder.addProguardConfiguration( ImmutableList.of( - "-forceinline class * { @com.android.tools.r8.ForceInline *; }", "-keep class " + TestClass.class.getTypeName() + " {", " public static void main(java.lang.String[]);", " *** test*(...);",
diff --git a/src/test/java/com/android/tools/r8/neverreturnsnormally/TestClass.java b/src/test/java/com/android/tools/r8/neverreturnsnormally/TestClass.java index e354c48..ed62754 100644 --- a/src/test/java/com/android/tools/r8/neverreturnsnormally/TestClass.java +++ b/src/test/java/com/android/tools/r8/neverreturnsnormally/TestClass.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.neverreturnsnormally; -import com.android.tools.r8.ForceInline; - public class TestClass { public static boolean throwNpe(String message) { String newMessage = "prefix:" + message + ":suffix"; @@ -13,7 +11,6 @@ throw new NullPointerException(newMessage); } - @ForceInline public static int throwToBeInlined() { throwNpe("throwToBeInlined"); return "Nobody cares".length();
diff --git a/src/test/java/com/android/tools/r8/regress/b191296688/Regress191296688.java b/src/test/java/com/android/tools/r8/regress/b191296688/Regress191296688.java index 8410836..f3b4ad9 100644 --- a/src/test/java/com/android/tools/r8/regress/b191296688/Regress191296688.java +++ b/src/test/java/com/android/tools/r8/regress/b191296688/Regress191296688.java
@@ -4,20 +4,18 @@ package com.android.tools.r8.regress.b191296688; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.CodeMatchers.isInvokeWithTarget; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertTrue; import com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestBase; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestRuntime; import com.android.tools.r8.TestRuntime.CfRuntime; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.utils.DescriptorUtils; import com.android.tools.r8.utils.codeinspector.ClassSubject; import com.android.tools.r8.utils.codeinspector.CodeInspector; @@ -64,7 +62,7 @@ .compile(); Path desugaredJar = testForD8(Backend.CF) - .addLibraryFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addLibraryFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addProgramFiles(ktClasses) .addProgramClasses(A.class) .setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java b/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java index d0cb2bf..d251e28 100644 --- a/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java +++ b/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java
@@ -24,7 +24,7 @@ @Parameterized.Parameters(name = "{0}") public static TestParametersCollection data() { - return getTestParameters().withAllRuntimes().build(); + return getTestParameters().withAllRuntimesAndApiLevels().build(); } public Regress69825683Test(TestParameters parameters) { @@ -48,10 +48,13 @@ .addKeepRules( "-assumemayhavesideeffects class " + inner.getName() + " {", " synthetic void <init>(...);", + "}", + "-keepunusedarguments class " + inner.getName() + " {", + " synthetic void <init>(...);", "}") .addOptionsModification(options -> options.enableClassInlining = false) .noMinification() - .setMinApi(parameters.getRuntime()) + .setMinApi(parameters.getApiLevel()) .run(parameters.getRuntime(), outer) // Run code to check that the constructor with synthetic class as argument is present. .assertSuccessWithOutputThatMatches(startsWith(innerName)) @@ -82,7 +85,7 @@ "}") .noMinification() .addOptionsModification(o -> o.enableClassInlining = false) - .setMinApi(parameters.getRuntime()) + .setMinApi(parameters.getApiLevel()) // Run code to check that the constructor with synthetic class as argument is present. .run(parameters.getRuntime(), clazz) .assertSuccessWithOutputThatMatches(startsWith(clazz.getName()))
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java index 4dcead3..48c4221 100644 --- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java +++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java
@@ -11,7 +11,6 @@ import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.TestParametersCollection; -import com.android.tools.r8.TestRuntime; import com.android.tools.r8.graph.AppView; import com.android.tools.r8.graph.DexMethod; import com.android.tools.r8.graph.DexProgramClass; @@ -41,7 +40,7 @@ @Test public void testResolution() throws Exception { - assumeTrue(parameters.getRuntime().equals(TestRuntime.getDefaultJavaRuntime())); + assumeTrue(parameters.useRuntimeAsNoneRuntime()); AppView<AppInfoWithLiveness> appView = computeAppViewWithLiveness( buildClasses(A.class, I.class)
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 e0eb6ca..3d3331b 100644 --- a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java +++ b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java
@@ -4,8 +4,6 @@ package com.android.tools.r8.retrace; import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.containsLinePositions; import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineFrame; import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineStack; @@ -81,7 +79,7 @@ public void testRuntime() throws Exception { testForRuntime(parameters) .addProgramFiles(compilationResults.getForConfiguration(kotlinc, targetVersion)) - .addRunClasspathFiles(buildOnDexRuntime(parameters, getKotlinStdlibJar(kotlinc))) + .addRunClasspathFiles(buildOnDexRuntime(parameters, kotlinc.getKotlinStdlibJar())) .run(parameters.getRuntime(), MAIN) .assertFailureWithErrorThatMatches(containsString("foo")) .assertFailureWithErrorThatMatches( @@ -96,7 +94,7 @@ CodeInspector kotlinInspector = new CodeInspector(kotlinSources); testForR8(parameters.getBackend()) .addProgramFiles(compilationResults.getForConfiguration(kotlinc, targetVersion)) - .addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAttributes("SourceFile", "LineNumberTable") .setMode(CompilationMode.RELEASE) .addKeepMainRule(MAIN)
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 032a370..f1000fb 100644 --- a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java +++ b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java
@@ -5,8 +5,6 @@ package com.android.tools.r8.retrace; import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; import static com.android.tools.r8.utils.codeinspector.Matchers.containsLinePositions; import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineFrame; import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineStack; @@ -91,7 +89,7 @@ public void testRuntime() throws Exception { testForRuntime(parameters) .addProgramFiles(compilationResults.getForConfiguration(kotlinc, targetVersion)) - .addRunClasspathFiles(buildOnDexRuntime(parameters, getKotlinStdlibJar(kotlinc))) + .addRunClasspathFiles(buildOnDexRuntime(parameters, kotlinc.getKotlinStdlibJar())) .run(parameters.getRuntime(), "retrace.MainKt") .assertFailureWithErrorThatMatches(containsString("inlineExceptionStatic")) .assertFailureWithErrorThatMatches(containsString("at retrace.MainKt.main(Main.kt:15)")); @@ -105,7 +103,7 @@ CodeInspector kotlinInspector = new CodeInspector(kotlinSources); testForR8(parameters.getBackend()) .addProgramFiles( - kotlinSources, getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + kotlinSources, kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAttributes("SourceFile", "LineNumberTable") .allowDiagnosticWarningMessages() .setMode(CompilationMode.RELEASE) @@ -135,7 +133,7 @@ CodeInspector kotlinInspector = new CodeInspector(kotlinSources); testForR8(parameters.getBackend()) .addProgramFiles( - kotlinSources, getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + kotlinSources, kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAttributes("SourceFile", "LineNumberTable") .allowDiagnosticWarningMessages() .setMode(CompilationMode.RELEASE) @@ -168,7 +166,7 @@ CodeInspector kotlinInspector = new CodeInspector(kotlinSources); testForR8(parameters.getBackend()) .addProgramFiles( - kotlinSources, getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + kotlinSources, kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAttributes("SourceFile", "LineNumberTable") .allowDiagnosticWarningMessages() .setMode(CompilationMode.RELEASE) @@ -200,7 +198,7 @@ CodeInspector kotlinInspector = new CodeInspector(kotlinSources); testForR8(parameters.getBackend()) .addProgramFiles( - kotlinSources, getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc)) + kotlinSources, kotlinc.getKotlinStdlibJar(), kotlinc.getKotlinAnnotationJar()) .addKeepAttributes("SourceFile", "LineNumberTable") .allowDiagnosticWarningMessages() .setMode(CompilationMode.RELEASE)
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java index 3a8fd5b..d1a074b 100644 --- a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java +++ b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
@@ -42,6 +42,7 @@ import com.android.tools.r8.retrace.stacktraces.NamedModuleStackTrace; import com.android.tools.r8.retrace.stacktraces.NoObfuscatedLineNumberWithOverrideTest; import com.android.tools.r8.retrace.stacktraces.NoObfuscationRangeMappingWithStackTrace; +import com.android.tools.r8.retrace.stacktraces.NpeInlineRetraceStackTrace; import com.android.tools.r8.retrace.stacktraces.NullStackTrace; import com.android.tools.r8.retrace.stacktraces.ObfucatedExceptionClassStackTrace; import com.android.tools.r8.retrace.stacktraces.ObfuscatedRangeToSingleLineStackTrace; @@ -309,6 +310,11 @@ runRetraceTest(new AmbiguousWithSignatureVerboseStackTrace()); } + @Test + public void testNpeInlineRetraceStackTrace() throws Exception { + runExperimentalRetraceTest(new NpeInlineRetraceStackTrace()); + } + private void inspectRetraceTest( StackTraceForTest stackTraceForTest, Consumer<Retracer> inspection) { inspection.accept(
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiRewriteFrameInlineNpeTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiRewriteFrameInlineNpeTest.java new file mode 100644 index 0000000..41c56cc --- /dev/null +++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiRewriteFrameInlineNpeTest.java
@@ -0,0 +1,113 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.retrace.api; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.android.tools.r8.Diagnostic; +import com.android.tools.r8.DiagnosticsHandler; +import com.android.tools.r8.TestParameters; +import com.android.tools.r8.references.Reference; +import com.android.tools.r8.retrace.ProguardMapProducer; +import com.android.tools.r8.retrace.RetraceClassElement; +import com.android.tools.r8.retrace.RetraceFrameElement; +import com.android.tools.r8.retrace.RetraceStackTraceContext; +import com.android.tools.r8.retrace.RetracedMethodReference; +import com.android.tools.r8.retrace.Retracer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class RetraceApiRewriteFrameInlineNpeTest extends RetraceApiTestBase { + + public RetraceApiRewriteFrameInlineNpeTest(TestParameters parameters) { + super(parameters); + } + + @Override + protected Class<? extends RetraceApiBinaryTest> binaryTestClass() { + return ApiTest.class; + } + + public static class ApiTest implements RetraceApiBinaryTest { + + private final String npeDescriptor = "Ljava/lang/NullPointerException;"; + + private final String mapping = + "# { id: 'com.android.tools.r8.mapping', version: 'experimental' }\n" + + "some.Class -> a:\n" + + " 4:4:void other.Class.inlinee():23:23 -> a\n" + + " 4:4:void caller(other.Class):7 -> a\n" + + " # { id: 'com.android.tools.r8.rewriteFrame', " + + " conditions: ['throws(" + + npeDescriptor + + ")'], " + + " actions: ['removeInnerFrames(1)']" + + " }"; + + @Test + public void testFirstStackLineIsRemoved() { + TestDiagnosticsHandler testDiagnosticsHandler = new TestDiagnosticsHandler(); + Retracer retracer = + Retracer.createExperimental( + ProguardMapProducer.fromString(mapping), testDiagnosticsHandler); + + List<RetraceClassElement> npeRetraced = + retracer.retraceClass(Reference.classFromDescriptor(npeDescriptor)).stream() + .collect(Collectors.toList()); + assertEquals(1, npeRetraced.size()); + + RetraceStackTraceContext context = npeRetraced.get(0).getContextWhereClassWasThrown(); + + List<RetraceFrameElement> retraceFrameElements = + retracer.retraceClass(Reference.classFromTypeName("a")).stream() + .flatMap(element -> element.lookupFrame(Optional.of(4), "a").stream()) + .collect(Collectors.toList()); + assertEquals(1, retraceFrameElements.size()); + + RetraceFrameElement retraceFrameElement = retraceFrameElements.get(0); + // Check that rewriting the frames will remove the top 1 frames if the condition is active. + Map<Integer, RetracedMethodReference> results = new LinkedHashMap<>(); + retraceFrameElement.visitRewrittenFrames( + context, + (methodReference, index) -> { + RetracedMethodReference existingValue = results.put(index, methodReference); + assertNull(existingValue); + }); + assertEquals(1, results.size()); + assertEquals(7, results.get(0).getOriginalPositionOrDefault(4)); + assertEquals(results.get(0).getMethodName(), "caller"); + } + + private static class TestDiagnosticsHandler implements com.android.tools.r8.DiagnosticsHandler { + + private List<Diagnostic> infoMessages = new ArrayList<>(); + + @Override + public void warning(Diagnostic warning) { + throw new RuntimeException("Warning not expected"); + } + + @Override + public void error(Diagnostic error) { + throw new RuntimeException("Error not expected"); + } + + @Override + public void info(Diagnostic info) { + DiagnosticsHandler.super.info(info); + infoMessages.add(info); + } + } + } +}
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedFrameTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedFrameTest.java index e1ad580..376a274 100644 --- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedFrameTest.java +++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedFrameTest.java
@@ -11,6 +11,7 @@ import com.android.tools.r8.references.Reference; import com.android.tools.r8.retrace.ProguardMapProducer; import com.android.tools.r8.retrace.RetraceFrameElement; +import com.android.tools.r8.retrace.RetraceStackTraceContext; import com.android.tools.r8.retrace.RetracedMethodReference; import com.android.tools.r8.retrace.Retracer; import java.util.ArrayList; @@ -57,7 +58,8 @@ retraceFrameElement.visitAllFrames((method, ignored) -> allFrames.add(method)); assertEquals(2, allFrames.size()); List<RetracedMethodReference> nonSyntheticFrames = new ArrayList<>(); - retraceFrameElement.visitNonCompilerSynthesizedFrames( + retraceFrameElement.visitRewrittenFrames( + RetraceStackTraceContext.getInitialContext(), (method, ignored) -> nonSyntheticFrames.add(method)); assertEquals(1, nonSyntheticFrames.size()); assertEquals(nonSyntheticFrames.get(0), allFrames.get(0));
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedInnerFrameTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedInnerFrameTest.java index 73367a6..c7b8d7a 100644 --- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedInnerFrameTest.java +++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSynthesizedInnerFrameTest.java
@@ -11,6 +11,7 @@ import com.android.tools.r8.references.Reference; import com.android.tools.r8.retrace.ProguardMapProducer; import com.android.tools.r8.retrace.RetraceFrameElement; +import com.android.tools.r8.retrace.RetraceStackTraceContext; import com.android.tools.r8.retrace.RetracedMethodReference; import com.android.tools.r8.retrace.Retracer; import java.util.ArrayList; @@ -57,7 +58,8 @@ retraceFrameElement.visitAllFrames((method, ignored) -> allFrames.add(method)); assertEquals(2, allFrames.size()); List<RetracedMethodReference> nonSyntheticFrames = new ArrayList<>(); - retraceFrameElement.visitNonCompilerSynthesizedFrames( + retraceFrameElement.visitRewrittenFrames( + RetraceStackTraceContext.getInitialContext(), (method, ignored) -> nonSyntheticFrames.add(method)); assertEquals(allFrames, nonSyntheticFrames); }
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java index 9c84754..98ccb02 100644 --- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java +++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java
@@ -44,7 +44,8 @@ RetraceApiSynthesizedMethodTest.ApiTest.class, RetraceApiSynthesizedFrameTest.ApiTest.class, RetraceApiSynthesizedInnerFrameTest.ApiTest.class, - RetraceApiUnknownJsonTest.ApiTest.class); + RetraceApiUnknownJsonTest.ApiTest.class, + RetraceApiRewriteFrameInlineNpeTest.ApiTest.class); public static List<Class<? extends RetraceApiBinaryTest>> CLASSES_PENDING_BINARY_COMPATIBILITY = ImmutableList.of();
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java index 5ce9e89..3facf5f 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java
@@ -47,8 +47,7 @@ + " main(java.lang.String[])(Main.java)", "\tat com.android.tools.r8.naming.retrace.Main.com.android.Foo" + " main(java.lang.String[],com.android.Bar)(Main.java)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.c(Main.java)", "\tat com.android.tools.r8.naming.retrace.Main.void main(com.android.Bar)(Main.java)", "\tat com.android.tools.r8.naming.retrace.Main.com.android.Foo"
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java index 3442711..484fb5f 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java
@@ -25,13 +25,61 @@ @Override public List<String> retracedStackTrace() { return Arrays.asList( - "There are 8 ambiguous stack traces. Use --verbose to have all listed.", "com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.bar(R8.java:7)", " at com.android.tools.r8.R8.bar(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.bar(R8.java:9)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java:7)", + " at com.android.tools.r8.R8.bar(R8.java:8)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:9)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java:7)", + " at com.android.tools.r8.R8.foo(R8.java:8)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java:9)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java:7)", + " at com.android.tools.r8.R8.foo(R8.java:8)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:9)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:7)", + " at com.android.tools.r8.R8.bar(R8.java:8)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java:9)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:7)", + " at com.android.tools.r8.R8.bar(R8.java:8)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:9)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:7)", + " at com.android.tools.r8.R8.foo(R8.java:8)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java:9)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:7)", + " at com.android.tools.r8.R8.foo(R8.java:8)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java:9)", " ... 42 more"); } @@ -46,56 +94,49 @@ "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:9)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:7)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java:9)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:7)", " at com.android.tools.r8.R8.void foo(int)(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:9)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:7)", " at com.android.tools.r8.R8.void foo(int)(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java:9)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java:7)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:9)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java:7)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java:9)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java:7)", " at com.android.tools.r8.R8.void foo(int)(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java:9)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java:7)", " at com.android.tools.r8.R8.void foo(int)(R8.java:8)", " at com.android.tools.r8.R8.main(Unknown Source)",
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java index 989868f..f6704a4 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java
@@ -25,13 +25,61 @@ @Override public List<String> retracedStackTrace() { return Arrays.asList( - "There are 8 ambiguous stack traces. Use --verbose to have all listed.", "com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.bar(R8.java)", " at com.android.tools.r8.R8.bar(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", " ... 42 more"); } @@ -46,56 +94,49 @@ "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)",
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureNonVerboseStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureNonVerboseStackTrace.java index 97f2162..7c0c0c2 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureNonVerboseStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureNonVerboseStackTrace.java
@@ -43,16 +43,13 @@ "java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.boolean foo(int,int)(Internal.java)", - "< OR >", - "java.lang.IndexOutOfBoundsException", + "<OR> java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.void foo(int)(Internal.java)", - "< OR >", - "java.lang.IndexOutOfBoundsException", + "<OR> java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.void foo(int,boolean)(Internal.java)", - "< OR >", - "java.lang.IndexOutOfBoundsException", + "<OR> java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.void foo(int,int)(Internal.java)"); }
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureVerboseStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureVerboseStackTrace.java index 23991fb..a00b7bf 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureVerboseStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousWithSignatureVerboseStackTrace.java
@@ -43,16 +43,13 @@ "java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.boolean foo(int,int)(Internal.java)", - "< OR >", - "java.lang.IndexOutOfBoundsException", + "<OR> java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.void foo(int)(Internal.java)", - "< OR >", - "java.lang.IndexOutOfBoundsException", + "<OR> java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.void foo(int,boolean)(Internal.java)", - "< OR >", - "java.lang.IndexOutOfBoundsException", + "<OR> java.lang.IndexOutOfBoundsException", "\tat java.util.ArrayList.get(ArrayList.java:411)", "\tat com.android.tools.r8.Internal.void foo(int,int)(Internal.java)"); }
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/MultipleLinesNoLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/MultipleLinesNoLineNumberStackTrace.java index 004b7d5..6df2b28 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/MultipleLinesNoLineNumberStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/MultipleLinesNoLineNumberStackTrace.java
@@ -29,8 +29,10 @@ @Override public List<String> retracedStackTrace() { return Arrays.asList( - "There are 2 ambiguous stack traces. Use --verbose to have all listed.", "Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java)", "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)"); } @@ -40,8 +42,7 @@ "There are 2 ambiguous stack traces.", "Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void method1(java.lang.String)(Main.java)", "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java)"); }
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java index 858c06b..2e57740 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java
@@ -35,11 +35,25 @@ @Override public List<String> retracedStackTrace() { return Arrays.asList( - "There are 4 ambiguous stack traces. Use --verbose to have all listed.", "Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:3)", "\tat com.android.tools.r8.naming.retrace.Main.overload1(Main.java:7)", "\tat com.android.tools.r8.naming.retrace.Main.definedOverload(Main.java:7)", + "\tat com.android.tools.r8.naming.retrace.Main.mainPC(Main.java:42)", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:3)", + "\tat com.android.tools.r8.naming.retrace.Main.overload1(Main.java:7)", + "\tat com.android.tools.r8.naming.retrace.Main.definedOverload(Main.java:11)", + "\tat com.android.tools.r8.naming.retrace.Main.mainPC(Main.java:42)", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:3)", + "\tat com.android.tools.r8.naming.retrace.Main.overload2(Main.java:11)", + "\tat com.android.tools.r8.naming.retrace.Main.definedOverload(Main.java:7)", + "\tat com.android.tools.r8.naming.retrace.Main.mainPC(Main.java:42)", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:3)", + "\tat com.android.tools.r8.naming.retrace.Main.overload2(Main.java:11)", + "\tat com.android.tools.r8.naming.retrace.Main.definedOverload(Main.java:11)", "\tat com.android.tools.r8.naming.retrace.Main.mainPC(Main.java:42)"); } @@ -53,24 +67,21 @@ "\tat com.android.tools.r8.naming.retrace.Main.void definedOverload()(Main.java:7)", "\tat com.android.tools.r8.naming.retrace.Main.void" + " mainPC(java.lang.String[])(Main.java:42)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String)(Main.java:3)", "\tat com.android.tools.r8.naming.retrace.Main.void overload1()(Main.java:7)", "\tat com.android.tools.r8.naming.retrace.Main.void" + " definedOverload(java.lang.String)(Main.java:11)", "\tat com.android.tools.r8.naming.retrace.Main.void" + " mainPC(java.lang.String[])(Main.java:42)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String)(Main.java:3)", "\tat com.android.tools.r8.naming.retrace.Main.void" + " overload2(java.lang.String)(Main.java:11)", "\tat com.android.tools.r8.naming.retrace.Main.void definedOverload()(Main.java:7)", "\tat com.android.tools.r8.naming.retrace.Main.void" + " mainPC(java.lang.String[])(Main.java:42)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String)(Main.java:3)", "\tat com.android.tools.r8.naming.retrace.Main.void" + " overload2(java.lang.String)(Main.java:11)",
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/NpeInlineRetraceStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/NpeInlineRetraceStackTrace.java new file mode 100644 index 0000000..3857154 --- /dev/null +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/NpeInlineRetraceStackTrace.java
@@ -0,0 +1,49 @@ +// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.android.tools.r8.retrace.stacktraces; + +import com.android.tools.r8.utils.StringUtils; +import java.util.Arrays; +import java.util.List; + +public class NpeInlineRetraceStackTrace implements StackTraceForTest { + + @Override + public List<String> obfuscatedStackTrace() { + return Arrays.asList( + "Exception in thread \"main\" java.lang.NullPointerException", "\tat a.a(:4)"); + } + + @Override + public String mapping() { + return StringUtils.lines( + "# { id: 'com.android.tools.r8.mapping', version: 'experimental' }", + "some.Class -> a:", + " 4:4:void other.Class():23:23 -> a", + " 4:4:void caller(other.Class):7 -> a", + " # { id: 'com.android.tools.r8.rewriteFrame', " + + "conditions: ['throws(Ljava/lang/NullPointerException;)'], " + + "actions: ['removeInnerFrames(1)'] }"); + } + + @Override + public List<String> retracedStackTrace() { + return Arrays.asList( + "Exception in thread \"main\" java.lang.NullPointerException", + "\tat some.Class.caller(Class.java:7)"); + } + + @Override + public List<String> retraceVerboseStackTrace() { + return Arrays.asList( + "Exception in thread \"main\" java.lang.NullPointerException", + "\tat some.Class.void caller(other.Class)(Class.java:7)"); + } + + @Override + public int expectedWarnings() { + return 0; + } +}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java index c5fe164..277e4b3 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java
@@ -29,9 +29,12 @@ @Override public List<String> retracedStackTrace() { return Arrays.asList( - "There are 3 ambiguous stack traces. Use --verbose to have all listed.", "Exception in thread \"main\" java.lang.NullPointerException", - "\tat com.android.tools.r8.naming.retrace.Main.overload(Main.java:7)"); + "\tat com.android.tools.r8.naming.retrace.Main.overload(Main.java:7)", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.overload(Main.java:15)", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.overload(Main.java:13)"); } @Override @@ -40,11 +43,9 @@ "There are 3 ambiguous stack traces.", "Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void overload()(Main.java:7)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void overload(int)(Main.java:15)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void" + " overload(java.lang.String)(Main.java:13)"); }
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java index 120cd8e..8f6e183 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java
@@ -36,13 +36,19 @@ @Override public List<String> retracedStackTrace() { return Arrays.asList( - "There are 2 ambiguous stack traces. Use --verbose to have all listed.", "Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java:42)", "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:28)", "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java:42)", "\tat com.android.tools.r8.naming.retrace.Main.main2(Main.java:29)", "\tat com.android.tools.r8.naming.retrace.Main.main3(Main.java:30)", + "\tat com.android.tools.r8.naming.retrace.Main.main4(Main.java:153)", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", + "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java:42)", + "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:28)", + "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java:42)", + "\tat com.android.tools.r8.naming.retrace.Main.main2(Main.java:29)", + "\tat com.android.tools.r8.naming.retrace.Main.method3(Main.java:72)", "\tat com.android.tools.r8.naming.retrace.Main.main4(Main.java:153)"); } @@ -62,8 +68,7 @@ + " main3(java.lang.String[])(Main.java:30)", "\tat com.android.tools.r8.naming.retrace.Main.void" + " main4(java.lang.String[])(Main.java:153)", - "< OR >", - "Exception in thread \"main\" java.lang.NullPointerException", + "<OR> Exception in thread \"main\" java.lang.NullPointerException", "\tat com.android.tools.r8.naming.retrace.Main.void" + " method1(java.lang.String)(Main.java:42)", "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java:28)",
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java index 2f946f8..3697b0c 100644 --- a/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java +++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java
@@ -25,13 +25,61 @@ @Override public List<String> retracedStackTrace() { return Arrays.asList( - "There are 8 ambiguous stack traces. Use --verbose to have all listed.", "com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.bar(R8.java)", " at com.android.tools.r8.R8.bar(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.bar(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.bar(R8.java)", + " ... 42 more", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.foo(R8.java)", + " at com.android.tools.r8.R8.main(Unknown Source)", + "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", + " at com.android.tools.r8.R8.foo(R8.java)", " ... 42 more"); } @@ -46,56 +94,49 @@ "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)", "Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void bar(int,int)(R8.java)", " ... 42 more", - "< OR >", - "com.android.tools.r8.CompilationException: foo[parens](Source:3)", + "<OR> com.android.tools.r8.CompilationException: foo[parens](Source:3)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.void foo(int)(R8.java)", " at com.android.tools.r8.R8.main(Unknown Source)",
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java index 22ba711..4d2837b 100644 --- a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java +++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java
@@ -14,13 +14,12 @@ import com.android.tools.r8.AssertionsConfiguration; import com.android.tools.r8.D8TestBuilder; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; import com.android.tools.r8.KotlinTestBase; import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.R8FullTestBuilder; import com.android.tools.r8.TestParameters; import com.android.tools.r8.ThrowableConsumer; -import com.android.tools.r8.ToolHelper; -import com.android.tools.r8.ToolHelper.KotlinTargetVersion; import com.android.tools.r8.utils.BooleanUtils; import com.android.tools.r8.utils.ThrowingConsumer; import com.android.tools.r8.utils.codeinspector.ClassSubject; @@ -93,7 +92,7 @@ } private Path kotlinStdlibLibraryForRuntime() throws Exception { - Path kotlinStdlibCf = ToolHelper.getKotlinStdlibJar(kotlinc); + Path kotlinStdlibCf = kotlinc.getKotlinStdlibJar(); if (parameters.getRuntime().isCf()) { return kotlinStdlibCf; } @@ -114,7 +113,7 @@ throws Exception { if (kotlinStdlibAsLibrary) { testForD8() - .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addClasspathFiles(kotlinc.getKotlinStdlibJar()) .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion)) .setMinApi(parameters.getApiLevel()) .apply(builderConsumer) @@ -126,7 +125,7 @@ .assertSuccessWithOutputLines(outputLines); } else { testForD8() - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addProgramFiles(kotlinc.getKotlinStdlibJar()) .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion)) .setMinApi(parameters.getApiLevel()) .apply(builderConsumer) @@ -157,11 +156,11 @@ .applyIf( kotlinStdlibAsLibrary, b -> { - b.addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc)); + b.addClasspathFiles(kotlinc.getKotlinStdlibJar()); b.addRunClasspathFiles(kotlinStdlibLibraryForRuntime()); }, - b -> b.addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc))) - .addClasspathFiles(ToolHelper.getKotlinAnnotationJar(kotlinc)) + b -> b.addProgramFiles(kotlinc.getKotlinStdlibJar())) + .addClasspathFiles(kotlinc.getKotlinAnnotationJar()) .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion)) .addKeepMainRule(testClassKt) .addKeepClassAndMembersRules(class1, class2)
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java b/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java index a9574e8..76e8f34 100644 --- a/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java +++ b/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java
@@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.rewrite.enums; +import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; @@ -58,7 +59,6 @@ .addProgramClassesAndInnerClasses(Ordinals.class) .addKeepMainRule(Ordinals.class) .enableConstantArgumentAnnotations() - .enableForceInliningAnnotations() .enableInliningAnnotations() .enableSideEffectAnnotations() .addOptionsModification(this::configure) @@ -100,6 +100,8 @@ assertOrdinalWasNotReplaced(clazz.uniqueMethodWithName("libraryType")); assertOrdinalWasNotReplaced(clazz.uniqueMethodWithName("phi")); + + assertThat(clazz.uniqueMethodWithName("inlined2"), isAbsent()); } @Test @@ -108,7 +110,6 @@ .addProgramClassesAndInnerClasses(Names.class) .addKeepMainRule(Names.class) .enableConstantArgumentAnnotations() - .enableForceInliningAnnotations() .enableInliningAnnotations() .enableSideEffectAnnotations() .addOptionsModification(this::configure) @@ -147,6 +148,8 @@ assertNameWasNotReplaced(clazz.uniqueMethodWithName("libraryType")); assertNameWasNotReplaced(clazz.uniqueMethodWithName("phi")); + + assertThat(clazz.uniqueMethodWithName("inlined2"), isAbsent()); } @Test @@ -155,7 +158,6 @@ .addProgramClassesAndInnerClasses(ToStrings.class) .addKeepMainRule(ToStrings.class) .enableConstantArgumentAnnotations() - .enableForceInliningAnnotations() .enableInliningAnnotations() .enableSideEffectAnnotations() .addOptionsModification(this::configure) @@ -197,6 +199,8 @@ assertToStringWasNotReplaced(clazz.uniqueMethodWithName("libraryType")); assertToStringWasNotReplaced(clazz.uniqueMethodWithName("phi")); + + assertThat(clazz.uniqueMethodWithName("inlined2"), isAbsent()); } private static void assertOrdinalReplacedWithConst(MethodSubject method, int expectedConst) {
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/Names.java b/src/test/java/com/android/tools/r8/rewrite/enums/Names.java index 1c2964c..10a70c4a 100644 --- a/src/test/java/com/android/tools/r8/rewrite/enums/Names.java +++ b/src/test/java/com/android/tools/r8/rewrite/enums/Names.java
@@ -5,7 +5,6 @@ package com.android.tools.r8.rewrite.enums; import com.android.tools.r8.AssumeMayHaveSideEffects; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.KeepConstantArguments; import com.android.tools.r8.NeverInline; import java.util.concurrent.TimeUnit; @@ -48,7 +47,6 @@ return inlined2(Number.TWO); } - @ForceInline private static String inlined2(Number number) { return number.name(); }
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java b/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java index c3fbffc..de4677d 100644 --- a/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java +++ b/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java
@@ -5,7 +5,6 @@ package com.android.tools.r8.rewrite.enums; import com.android.tools.r8.AssumeMayHaveSideEffects; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.KeepConstantArguments; import com.android.tools.r8.NeverInline; import java.util.concurrent.TimeUnit; @@ -44,7 +43,7 @@ private static long inlined() { return inlined2(Number.TWO); } - @ForceInline + private static long inlined2(Number number) { return number.ordinal(); }
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java b/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java index 020f5fd..957a5e1 100644 --- a/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java +++ b/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java
@@ -5,7 +5,6 @@ package com.android.tools.r8.rewrite.enums; import com.android.tools.r8.AssumeMayHaveSideEffects; -import com.android.tools.r8.ForceInline; import com.android.tools.r8.KeepConstantArguments; import com.android.tools.r8.NeverInline; import java.util.Locale; @@ -85,7 +84,6 @@ return inlined2(NoToString.TWO); } - @ForceInline private static String inlined2(NoToString number) { return number.toString(); }
diff --git a/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java b/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java index 7f6323a..b99494e 100644 --- a/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java +++ b/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java
@@ -80,17 +80,17 @@ @RunWith(Parameterized.class) public class ParameterTypeTest extends TestBase { - private final boolean enableArgumentRemoval; + private final boolean enableArgumentPropagation; private final TestParameters parameters; - @Parameters(name = "{1}, argument removal: {0}") + @Parameters(name = "{1}, argument propagation: {0}") public static List<Object[]> data() { return buildParameters( BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build()); } - public ParameterTypeTest(boolean enableArgumentRemoval, TestParameters parameters) { - this.enableArgumentRemoval = enableArgumentRemoval; + public ParameterTypeTest(boolean enableArgumentPropagation, TestParameters parameters) { + this.enableArgumentPropagation = enableArgumentPropagation; this.parameters = parameters; } @@ -228,7 +228,7 @@ options -> { // Disable inlining to avoid the (short) tested method from being inlined and removed. options.enableInlining = false; - options.enableArgumentRemoval = enableArgumentRemoval; + options.callSiteOptimizationOptions().setEnabled(enableArgumentPropagation); }); // Run processed (output) program on ART @@ -239,7 +239,7 @@ CodeInspector inspector = new CodeInspector(processedApp); ClassSubject subSubject = inspector.clazz(sub.name); - assertNotEquals(enableArgumentRemoval, subSubject.isPresent()); + assertNotEquals(enableArgumentPropagation, subSubject.isPresent()); } @Test @@ -307,7 +307,7 @@ options -> { // Disable inlining to avoid the (short) tested method from being inlined and removed. options.enableInlining = false; - options.enableArgumentRemoval = enableArgumentRemoval; + options.callSiteOptimizationOptions().setEnabled(enableArgumentPropagation); }) .noMinification() .setMinApi(parameters.getApiLevel()) @@ -315,11 +315,11 @@ .inspect( inspector -> { ClassSubject subSubject = inspector.clazz(sub.name); - assertNotEquals(enableArgumentRemoval, subSubject.isPresent()); + assertNotEquals(enableArgumentPropagation, subSubject.isPresent()); }) .run(parameters.getRuntime(), mainClassName) .applyIf( - enableArgumentRemoval || parameters.isCfRuntime(), + enableArgumentPropagation || parameters.isCfRuntime(), SingleTestRunResult::assertSuccess, result -> result.assertFailureWithErrorThatMatches( @@ -410,7 +410,7 @@ options -> { // Disable inlining to avoid the (short) tested method from being inlined and removed. options.enableInlining = false; - options.enableArgumentRemoval = enableArgumentRemoval; + options.callSiteOptimizationOptions().setEnabled(enableArgumentPropagation); }); // Run processed (output) program on ART @@ -422,6 +422,6 @@ CodeInspector inspector = new CodeInspector(processedApp); ClassSubject subSubject = inspector.clazz(sub.name); - assertNotEquals(enableArgumentRemoval, subSubject.isPresent()); + assertNotEquals(enableArgumentPropagation, subSubject.isPresent()); } }
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java index c93200c..a296b9b 100644 --- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java +++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -1720,8 +1720,7 @@ @Test public void parse_testInlineOptions() { - List<String> options = ImmutableList.of( - "-neverinline", "-forceinline"); + List<String> options = ImmutableList.of("-neverinline"); for (String option : options) { try { reset();
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 662ad5e..852c86f 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
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.shaking.annotations; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; 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; @@ -98,7 +97,7 @@ testForR8Compat(parameters.getBackend()) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .addKeepMainRule(MAIN_CLASS_NAME) .addKeepRules(KEEP_ANNOTATIONS) @@ -136,7 +135,7 @@ testForR8Compat(parameters.getBackend()) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .addKeepMainRule(MAIN_CLASS_NAME) .addKeepRules(KEEP_ANNOTATIONS) @@ -178,7 +177,7 @@ testForR8Compat(parameters.getBackend()) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .addKeepMainRule(MAIN_CLASS_NAME) .addKeepRules(KEEP_ANNOTATIONS) @@ -216,7 +215,7 @@ testForR8(parameters.getBackend()) .addProgramFiles( compiledJars.getForConfiguration(kotlinc, targetVersion), - getKotlinAnnotationJar(kotlinc)) + kotlinc.getKotlinAnnotationJar()) .addProgramFiles(getJavaJarFile(FOLDER)) .addKeepMainRule(MAIN_CLASS_NAME) .allowDiagnosticWarningMessages()
diff --git a/src/test/java/com/android/tools/r8/shaking/annotations/b137392797/B137392797.java b/src/test/java/com/android/tools/r8/shaking/annotations/b137392797/B137392797.java index 184cd68..161d685 100644 --- a/src/test/java/com/android/tools/r8/shaking/annotations/b137392797/B137392797.java +++ b/src/test/java/com/android/tools/r8/shaking/annotations/b137392797/B137392797.java
@@ -4,13 +4,12 @@ package com.android.tools.r8.shaking.annotations.b137392797; -import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar; -import static com.android.tools.r8.ToolHelper.getKotlinC_1_3_72; -import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar; +import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_3_72; import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; +import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; import com.android.tools.r8.utils.BooleanUtils; @@ -59,14 +58,14 @@ @Test public void testR8() throws Exception { + KotlinCompiler compiler = KOTLINC_1_3_72.getCompiler(); testForR8(parameters.getBackend()) .addProgramClassFileData( classWireField(defaultEnumValueInAnnotation), classWireFieldLabel(), classTest(defaultEnumValueInAnnotation)) .addProgramClasses(TestClass.class) - .addClasspathFiles( - getKotlinStdlibJar(getKotlinC_1_3_72()), getKotlinAnnotationJar(getKotlinC_1_3_72())) + .addClasspathFiles(compiler.getKotlinStdlibJar(), compiler.getKotlinAnnotationJar()) .addKeepClassAndMembersRules( "com.squareup.wire.WireField", "com.squareup.demo.myapplication.Test") .addKeepMainRule(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java b/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java index 5d5a4b9..422ec12 100644 --- a/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java +++ b/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java
@@ -4,13 +4,11 @@ package com.android.tools.r8.shaking.b134858535; -import static com.android.tools.r8.ToolHelper.getKotlinCompilers; - import com.android.tools.r8.CompilationFailedException; -import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; +import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; +import com.android.tools.r8.KotlinTestParameters; import com.android.tools.r8.TestBase; import com.android.tools.r8.TestParameters; -import com.android.tools.r8.ToolHelper; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -20,18 +18,21 @@ @RunWith(Parameterized.class) public class EventPublisherTest extends TestBase { - private final KotlinCompiler kotlinc; + private final KotlinTestParameters kotlinTestParameters; private final TestParameters parameters; @Parameters(name = "{1}, {0}") public static List<Object[]> data() { return buildParameters( - getKotlinCompilers(), + getKotlinTestParameters() + .withAllCompilers() + .withTargetVersion(KotlinTargetVersion.JAVA_8) + .build(), TestBase.getTestParameters().withDexRuntimes().withAllApiLevels().build()); } - public EventPublisherTest(KotlinCompiler kotlinc, TestParameters parameters) { - this.kotlinc = kotlinc; + public EventPublisherTest(KotlinTestParameters kotlinTestParameters, TestParameters parameters) { + this.kotlinTestParameters = kotlinTestParameters; this.parameters = parameters; } @@ -47,7 +48,7 @@ SdkConfiguration.class, TrackBatchEventResponse.class) .addProgramClassFileData(EventPublisher$bDump.dump()) - .addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc)) + .addProgramFiles(kotlinTestParameters.getCompiler().getKotlinStdlibJar()) .addKeepClassRules(Interface.class) .addKeepMainRule(Main.class) .setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/shaking/testrules/A.java b/src/test/java/com/android/tools/r8/shaking/testrules/A.java deleted file mode 100644 index 23aa04e..0000000 --- a/src/test/java/com/android/tools/r8/shaking/testrules/A.java +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.android.tools.r8.shaking.testrules; - -import com.android.tools.r8.NoHorizontalClassMerging; - -@NoHorizontalClassMerging -public class A { - - public static int m(int a, int b) { - int r = a + b; - System.out.println(a + " + " + b + " = " + r); - return r; - } - - public static int method() { - return m(m(m(1, 2), m(3, 4)), m(m(5, 6), m(7, 8))); - } -}
diff --git a/src/test/java/com/android/tools/r8/shaking/testrules/B.java b/src/test/java/com/android/tools/r8/shaking/testrules/B.java deleted file mode 100644 index 4d1f085..0000000 --- a/src/test/java/com/android/tools/r8/shaking/testrules/B.java +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.android.tools.r8.shaking.testrules; - -public class B { - - public int m(int a, int b) { - int r = a + b; - System.out.println(a + " + " + b + " = " + r); - return r; - } - public int method() { - return m(m(m(1, 2), m(3, 4)), m(m(5, 6), m(7, 8))); - } -}
diff --git a/src/test/java/com/android/tools/r8/shaking/testrules/C.java b/src/test/java/com/android/tools/r8/shaking/testrules/C.java deleted file mode 100644 index 497c218..0000000 --- a/src/test/java/com/android/tools/r8/shaking/testrules/C.java +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.android.tools.r8.shaking.testrules; - -import com.android.tools.r8.NeverInline; - -public class C { - - private static int i; - - @NeverInline - public static int x() { - return i; - } -}
diff --git a/src/test/java/com/android/tools/r8/shaking/testrules/ForceInlineTest.java b/src/test/java/com/android/tools/r8/shaking/testrules/ForceInlineTest.java deleted file mode 100644 index aaafe0c..0000000 --- a/src/test/java/com/android/tools/r8/shaking/testrules/ForceInlineTest.java +++ /dev/null
@@ -1,139 +0,0 @@ -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.android.tools.r8.shaking.testrules; - -import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.fail; - -import com.android.tools.r8.TestBase; -import com.android.tools.r8.TestParameters; -import com.android.tools.r8.TestParametersCollection; -import com.android.tools.r8.utils.codeinspector.ClassSubject; -import com.android.tools.r8.utils.codeinspector.CodeInspector; -import com.google.common.collect.ImmutableList; -import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -@RunWith(Parameterized.class) -public class ForceInlineTest extends TestBase { - - private TestParameters parameters; - - @Parameterized.Parameters(name = "{0}") - public static TestParametersCollection data() { - return getTestParameters().withAllRuntimesAndApiLevels().build(); - } - - public ForceInlineTest(TestParameters parameters) { - this.parameters = parameters; - } - - private CodeInspector runTest(List<String> proguardConfiguration) throws Exception { - return testForR8(parameters.getBackend()) - .addProgramClasses(Main.class, A.class, B.class, C.class) - .addKeepRules(proguardConfiguration) - .enableInliningAnnotations() - .enableNoHorizontalClassMergingAnnotations() - .enableNoHorizontalClassMergingAnnotations() - .enableProguardTestOptions() - .compile() - .inspector(); - } - - @Test - public void testDefaultInlining() throws Exception { - CodeInspector inspector = - runTest( - ImmutableList.of( - "-keep class **.Main { *; }", - "-neverinline class *{ @com.android.tools.r8.NeverInline <methods>;}", - "-dontobfuscate")); - - ClassSubject classA = inspector.clazz(A.class); - ClassSubject classB = inspector.clazz(B.class); - ClassSubject classC = inspector.clazz(C.class); - ClassSubject classMain = inspector.clazz(Main.class); - assertThat(classA, isPresent()); - assertThat(classB, isPresent()); - assertThat(classC, not(isPresent())); - assertThat(classMain, isPresent()); - - // By default A.m *will not* be inlined (called several times and not small). - assertThat(classA.method("int", "m", ImmutableList.of("int", "int")), isPresent()); - // By default A.method *will* be inlined (called only once). - assertThat(classA.method("int", "method", ImmutableList.of()), not(isPresent())); - // By default B.m *will not* be inlined (called several times and not small). - assertThat(classB.method("int", "m", ImmutableList.of("int", "int")), isPresent()); - // By default B.method *will* be inlined (called only once). - assertThat(classB.method("int", "method", ImmutableList.of()), not(isPresent())); - } - - @Test - public void testNeverInline() throws Exception { - CodeInspector inspector = - runTest( - ImmutableList.of( - "-neverinline class **.A { method(); }", - "-neverinline class **.B { method(); }", - "-keep class **.Main { *; }", - "-neverinline class *{ @com.android.tools.r8.NeverInline <methods>;}", - "-dontobfuscate")); - - ClassSubject classA = inspector.clazz(A.class); - ClassSubject classB = inspector.clazz(B.class); - ClassSubject classC = inspector.clazz(C.class); - ClassSubject classMain = inspector.clazz(Main.class); - assertThat(classA, isPresent()); - assertThat(classB, isPresent()); - assertThat(classC, not(isPresent())); - assertThat(classMain, isPresent()); - - // Compared to the default method is no longer inlined. - assertThat(classA.method("int", "m", ImmutableList.of("int", "int")), isPresent()); - assertThat(classA.method("int", "method", ImmutableList.of()), isPresent()); - assertThat(classB.method("int", "m", ImmutableList.of("int", "int")), isPresent()); - assertThat(classB.method("int", "method", ImmutableList.of()), isPresent()); - } - - @Test - public void testForceInline() throws Exception { - CodeInspector inspector = - runTest( - ImmutableList.of( - "-forceinline class **.A { int m(int, int); }", - "-forceinline class **.B { int m(int, int); }", - "-keep class **.Main { *; }", - "-neverinline class *{ @com.android.tools.r8.NeverInline <methods>;}", - "-dontobfuscate")); - - // Compared to the default m is now inlined and method still is, so classes A and B are gone. - assertThat(inspector.clazz(A.class), not(isPresent())); - assertThat(inspector.clazz(B.class), not(isPresent())); - assertThat(inspector.clazz(C.class), not(isPresent())); - assertThat(inspector.clazz(Main.class), isPresent()); - } - - @Test - public void testForceInlineFails() { - try { - runTest( - ImmutableList.of( - "-forceinline class **.A { int x(); }", - "-keep class **.Main { *; }", - "-dontobfuscate")); - fail("Force inline of non-inlinable method succeeded"); - } catch (Throwable t) { - // Ignore assertion error. - } - } -} \ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/shaking/testrules/Main.java b/src/test/java/com/android/tools/r8/shaking/testrules/Main.java deleted file mode 100644 index d326216..0000000 --- a/src/test/java/com/android/tools/r8/shaking/testrules/Main.java +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.android.tools.r8.shaking.testrules; - -public class Main { - - public static void main(String[] args) { - System.out.println(A.method()); - System.out.println(new B().method()); - System.out.println(C.x()); - } -}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java index b100332..9c057e6 100644 --- a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java +++ b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
@@ -4,6 +4,8 @@ package com.android.tools.r8.utils.codeinspector; +import static com.google.common.base.Predicates.alwaysTrue; + import com.android.tools.r8.graph.ClassAccessFlags; import com.android.tools.r8.graph.DexMethod; import com.android.tools.r8.graph.DexProgramClass; @@ -17,7 +19,6 @@ import com.android.tools.r8.smali.SmaliBuilder; import com.android.tools.r8.synthesis.SyntheticItemsTestUtils; import com.android.tools.r8.utils.ListUtils; -import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import java.lang.reflect.Method; import java.util.ArrayList; @@ -41,7 +42,7 @@ public abstract void forAllMethods(Consumer<FoundMethodSubject> inspection); public final List<FoundMethodSubject> allMethods() { - return allMethods(Predicates.alwaysTrue()); + return allMethods(alwaysTrue()); } public final List<FoundMethodSubject> allMethods(Predicate<FoundMethodSubject> predicate) { @@ -58,7 +59,7 @@ public abstract void forAllVirtualMethods(Consumer<FoundMethodSubject> inspection); public final List<FoundMethodSubject> virtualMethods() { - return virtualMethods(Predicates.alwaysTrue()); + return virtualMethods(alwaysTrue()); } public final List<FoundMethodSubject> virtualMethods(Predicate<FoundMethodSubject> predicate) { @@ -111,6 +112,10 @@ return method("void", "main", ImmutableList.of("java.lang.String[]")); } + public MethodSubject uniqueMethod() { + return uniqueMethodThatMatches(alwaysTrue()); + } + public MethodSubject clinit() { return method("void", "<clinit>", ImmutableList.of()); }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java index 76d76e5..d753ca5 100644 --- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java +++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -177,7 +177,7 @@ public Retracer getRetracer() { if (lazyRetracer == null) { - lazyRetracer = new RetracerImpl(mapping); + lazyRetracer = new RetracerImpl(mapping, new TestDiagnosticMessagesImpl()); } return lazyRetracer; }
diff --git a/third_party/kotlin/kotlin-compiler-dev.tar.gz.sha1 b/third_party/kotlin/kotlin-compiler-dev.tar.gz.sha1 new file mode 100644 index 0000000..9aefa3f --- /dev/null +++ b/third_party/kotlin/kotlin-compiler-dev.tar.gz.sha1
@@ -0,0 +1 @@ +d78e3bea626ae7f07cce1160a0af5c5c6812468e \ No newline at end of file
diff --git a/third_party/retrace/binary_compatibility.tar.gz.sha1 b/third_party/retrace/binary_compatibility.tar.gz.sha1 index c3fc5b5..7fbd228 100644 --- a/third_party/retrace/binary_compatibility.tar.gz.sha1 +++ b/third_party/retrace/binary_compatibility.tar.gz.sha1
@@ -1 +1 @@ -8a3bfb12c41dc6fc56545c186729f234f2680b55 \ No newline at end of file +6b7ccd6aa40c22bea72017bfabca022d4d90d70a \ No newline at end of file
diff --git a/tools/download_kotlin_dev.py b/tools/download_kotlin_dev.py new file mode 100755 index 0000000..c6c127e --- /dev/null +++ b/tools/download_kotlin_dev.py
@@ -0,0 +1,78 @@ +#!/usr/bin/env python +# Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +from HTMLParser import HTMLParser +import os +import sys +import urllib +import utils + +JETBRAINS_KOTLIN_MAVEN_URL = "https://maven.pkg.jetbrains.space/kotlin/p/" \ + "kotlin/bootstrap/org/jetbrains/kotlin/" +KOTLIN_RELEASE_URL = JETBRAINS_KOTLIN_MAVEN_URL + "kotlin-compiler/" + +def download_newest(): + response = urllib.urlopen(KOTLIN_RELEASE_URL) + if response.getcode() != 200: + raise Exception('Url: %s \n returned %s' + % (KOTLIN_RELEASE_URL, response.getcode())) + content = response.read() + release_candidates = [] + + class HTMLContentParser(HTMLParser): + def handle_data(self, data): + if ('-dev-' in data): + release_candidates.append(data) + + parser = HTMLContentParser() + parser.feed(content) + + top_most_version = (0, 0, 0, 0) + top_most_version_and_build = None + + for version in release_candidates: + # The compiler version is on the form <major>.<minor>.<revision>-dev-<build>/ + version = version.replace('/', '') + version_build_args = version.split('-') + version_components = version_build_args[0].split('.') + version_components.append(version_build_args[2]) + current_version = tuple(map(int, version_components)) + if (current_version > top_most_version): + top_most_version = current_version + top_most_version_and_build = version + + if (top_most_version_and_build is None): + raise Exception('Url: %s \n returned %s' + % (KOTLIN_RELEASE_URL, response.getcode())) + + # We can now download all files related to the kotlin compiler version. + print("Downloading version: " + top_most_version_and_build) + + kotlinc_lib = os.path.join( + utils.THIRD_PARTY, "kotlin", "kotlin-compiler-dev", "kotlinc", "lib") + + utils.DownloadFromGoogleCloudStorage( + os.path.join( + utils.THIRD_PARTY, "kotlin", "kotlin-compiler-dev.tar.gz.sha1")) + + download_and_save( + JETBRAINS_KOTLIN_MAVEN_URL + "kotlin-compiler/{0}/kotlin-compiler-{0}.jar" + .format(top_most_version_and_build), kotlinc_lib, "kotlin-compiler.jar") + download_and_save( + JETBRAINS_KOTLIN_MAVEN_URL + "kotlin-stdlib/{0}/kotlin-stdlib-{0}.jar" + .format(top_most_version_and_build), kotlinc_lib, "kotlin-stdlib.jar") + download_and_save( + JETBRAINS_KOTLIN_MAVEN_URL + "kotlin-reflect/{0}/kotlin-reflect-{0}.jar" + .format(top_most_version_and_build), kotlinc_lib, "kotlin-reflect.jar") + + +def download_and_save(url, path, name): + print('Downloading: ' + url) + urllib.urlretrieve(url, os.path.join(path, name)) + + +if __name__ == '__main__': + sys.exit(download_newest()) +
diff --git a/tools/test.py b/tools/test.py index 6553358..c719ea2 100755 --- a/tools/test.py +++ b/tools/test.py
@@ -8,6 +8,7 @@ # force the tests to run, even if no input changed. import archive_desugar_jdk_libs +import download_kotlin_dev import notify import optparse import os @@ -187,6 +188,10 @@ '--stacktrace', help='Pass --stacktrace to the gradle run', default=False, action='store_true') + result.add_option('--kotlin-compiler-dev', + help='Specify to download a kotlin dev compiler and run ' + 'tests with that', + default=False, action='store_true') return result.parse_args() def archive_failures(): @@ -275,6 +280,9 @@ gradle_args.append('-Pprint_full_stacktraces') if options.print_obfuscated_stacktraces: gradle_args.append('-Pprint_obfuscated_stacktraces') + if options.kotlin_compiler_dev: + gradle_args.append('-Dcom.android.tools.r8.kotlincompilerdev=1') + download_kotlin_dev.download_newest() if os.name == 'nt': # temporary hack gradle_args.append('-Pno_internal')