Java-style lambda class merging.
Adds support for Kotlin java-style lambda class merging implemented in
the same way and scope as similar merging of kotlin-style lambda classes.
Actually, there are just few differences between kotlin- and java-style
lambdas synthesized by Kotlin compiler and most of the implementation
is shared.
As before, the scope of the merging depends on proguard rules, on
tachiyomi with most optimistic expectetions (assuming no lambda classes
are pinned by blanket keep rules, allowaccessmodification is specified,
and none of [Signature, InnerClasses, EnclosingMethod] is kept) we get:
K-STYLE LAMBDAS:
422 lambda classes total
303 lambda classes in 81 groups after invalid and non-grouped lambdas removed
222 lambda classes removed
J-STYLE LAMBDA CLASSES:
503 lambda classes total
310 lambda classes in 83 groups after invalid and non-grouped lambdas removed
227 lambda classes removed
DEX size w/o optimization : 4865332 bytes
DEX size with optimization: 4774368 bytes (-91K, -1.87%)
Bug:72858983
Change-Id: I86602f8ef2a1e452bb5e320a9af4b39a7958ca06
diff --git a/src/test/kotlinR8TestResources/lambdas_singleton/main.kt b/src/test/kotlinR8TestResources/lambdas_singleton/main.kt
new file mode 100644
index 0000000..8e34a0c
--- /dev/null
+++ b/src/test/kotlinR8TestResources/lambdas_singleton/main.kt
@@ -0,0 +1,46 @@
+// 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 lambdas.singleton
+
+private var COUNT = 0
+
+fun nextInt() = COUNT++
+fun next() = "${nextInt()}".padStart(3, '0')
+
+fun main(args: Array<String>) {
+ test()
+}
+
+private fun test() {
+ test2(listOf(next(), next(), next(), next(), next(), next(), next(), next(), next(), next()))
+}
+
+private fun Collection<String>.flatten() =
+ this.joinToString(prefix = "(*", postfix = "*)", separator = "*")
+
+private fun Array<String>.flatten() =
+ this.joinToString(prefix = "(*", postfix = "*)", separator = "*")
+
+private fun test2(args: Collection<String>) {
+ println(args.sortedByDescending { it.length }.flatten())
+ println(args.sortedByDescending { -it.length }.flatten())
+ process(::println)
+ process(::println)
+ val lambda: (Array<String>) -> Unit = {}
+}
+
+private inline fun process(crossinline f: (String) -> Unit) {
+ feed2 { f(it.flatten()) }
+ feed3 { f(it.flatten()) }
+}
+
+private fun feed3(f: (Array<String>) -> Unit) {
+ f(arrayOf(next(), next(), next()))
+}
+
+private fun feed2(f: (Array<String>) -> Unit) {
+ f(arrayOf(next(), next()))
+}
+