[Metadata] Check if inline function has default arguments
Bug: 211113454
Change-Id: I5b70568a88cc3cd0d1bb7b2bb09fcd8d78c32eb3
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java
index 9e79ee0..5022d48 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.kotlin;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.isValidMethodDescriptor;
+import static com.android.tools.r8.kotlin.KotlinMetadataUtils.toDefaultJvmMethodSignature;
import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
import com.android.tools.r8.graph.AppView;
@@ -18,6 +19,8 @@
import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.ImmutableList;
+import com.google.common.math.IntMath;
+import java.math.RoundingMode;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -87,7 +90,7 @@
}
continue;
}
- keepIfInline(kmFunction.getFlags(), method, keepByteCode);
+ keepIfInline(kmFunction.getFlags(), method, signature, methodSignatureMap, keepByteCode);
method.setKotlinMemberInfo(kotlinFunctionInfo);
originalAssignmentTracker.add(method.getReference());
}
@@ -138,8 +141,24 @@
}
private static void keepIfInline(
- int flags, DexEncodedMethod method, Consumer<DexEncodedMethod> keepByteCode) {
+ int flags,
+ DexEncodedMethod method,
+ JvmMethodSignature signature,
+ Map<String, DexEncodedMethod> methodSignatureMap,
+ Consumer<DexEncodedMethod> keepByteCode) {
if (Flags.IS_INLINE.get(flags)) {
+ // Check if we can find a default method. If there are more than 32 arguments another int
+ // index will be added to the default method.
+ for (int i = 1;
+ i <= IntMath.divide(method.getParameters().size(), 32, RoundingMode.CEILING);
+ i++) {
+ DexEncodedMethod defaultValueMethod =
+ methodSignatureMap.get(toDefaultJvmMethodSignature(signature, i).toString());
+ if (defaultValueMethod != null) {
+ keepByteCode.accept(defaultValueMethod);
+ return;
+ }
+ }
keepByteCode.accept(method);
}
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
index 2d6f39a..1d927fe 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.shaking.ProguardKeepRuleType;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.Pair;
+import com.google.common.base.Strings;
import kotlinx.metadata.KmExtensionType;
import kotlinx.metadata.KmProperty;
import kotlinx.metadata.KmPropertyExtensionVisitor;
@@ -99,13 +100,21 @@
return new JvmMethodSignature(method.name.toString(), descBuilder.toString());
}
+ static JvmMethodSignature toDefaultJvmMethodSignature(
+ JvmMethodSignature methodSignature, int intArguments) {
+ return new JvmMethodSignature(
+ methodSignature.getName() + "$default",
+ methodSignature
+ .getDesc()
+ .replace(")", Strings.repeat("I", intArguments) + "Ljava/lang/Object;)"));
+ }
+
static class KmPropertyProcessor {
private JvmFieldSignature fieldSignature = null;
// Custom getter via @get:JvmName("..."). Otherwise, null.
private JvmMethodSignature getterSignature = null;
// Custom getter via @set:JvmName("..."). Otherwise, null.
private JvmMethodSignature setterSignature = null;
-
KmPropertyProcessor(KmProperty kmProperty) {
kmProperty.accept(
new KmPropertyVisitor() {
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineBlockTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineBlockTest.java
index 63197d4..258230a 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineBlockTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteCrossinlineBlockTest.java
@@ -6,18 +6,13 @@
import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar;
import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertNotEquals;
-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.ProcessResult;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import java.nio.file.Path;
import java.util.Collection;
-import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -25,7 +20,11 @@
@RunWith(Parameterized.class)
public class MetadataRewriteCrossinlineBlockTest extends KotlinMetadataTestBase {
- private final String EXPECTED = StringUtils.lines("foo");
+ private final String EXPECTED =
+ StringUtils.lines(
+ "foo", "42", "42", "0", "42", "42", "42", "42", "42", "42", "42", "42", "42", "42", "42",
+ "42", "42", "42", "42", "42", "42", "42", "42", "42", "42", "42", "42", "42", "42", "42",
+ "42", "42", "42", "42");
private static final String PKG_LIB = PKG + ".crossinline_block_lib";
private static final String PKG_APP = PKG + ".crossinline_block_app";
@@ -74,26 +73,18 @@
.addKeepAllAttributes()
.compile()
.writeToZip();
- ProcessResult kotlinCompileResult =
+ Path output =
kotlinc(parameters.getRuntime().asCf(), kotlinc, targetVersion)
.addClasspathFiles(libJar)
.addSourceFiles(
getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main"))
.setOutputPath(temp.newFolder().toPath())
.enableAssertions()
- .compileRaw();
- // TODO(b/211113454): This compilation should not fail.
- assertNotEquals(0, kotlinCompileResult.exitCode);
- if (kotlinc.is(KotlinCompilerVersion.KOTLINC_1_3_72)) {
- assertThat(
- kotlinCompileResult.stderr,
- CoreMatchers.containsString(
- "java.lang.AssertionError: 'checkParameterIsNotNull' should be invoked on local"));
- } else {
- assertThat(
- kotlinCompileResult.stderr,
- CoreMatchers.containsString(
- "java.lang.AssertionError: 'checkNotNullParameter' should be invoked on local"));
- }
+ .compile();
+ testForJvm()
+ .addRunClasspathFiles(getKotlinStdlibJar(kotlinc), libJar)
+ .addClasspath(output)
+ .run(parameters.getRuntime(), PKG_APP + ".MainKt")
+ .assertSuccessWithOutput(EXPECTED);
}
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_app/main.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_app/main.kt
index c658ae8..b349233 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_app/main.kt
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_app/main.kt
@@ -4,11 +4,13 @@
package com.android.tools.r8.kotlin.metadata.crossinline_block_app
+import com.android.tools.r8.kotlin.metadata.crossinline_block_lib.bar
import com.android.tools.r8.kotlin.metadata.crossinline_block_lib.foo
fun main(args : Array<String>) {
if (args.isEmpty()) {
call("foo")
+ bar(bar3 = 0)
} else {
call("bar")
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_lib/lib.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_lib/lib.kt
index 075be3e..d7efaaf 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_lib/lib.kt
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/crossinline_block_lib/lib.kt
@@ -10,3 +10,73 @@
) {
block()
}
+
+public inline fun bar(
+ bar1: Int = 42,
+ bar2: Int = 42,
+ bar3: Int = 42,
+ bar4: Int = 42,
+ bar5: Int = 42,
+ bar6: Int = 42,
+ bar7: Int = 42,
+ bar8: Int = 42,
+ bar9: Int = 42,
+ bar10: Int = 42,
+ bar11: Int = 42,
+ bar12: Int = 42,
+ bar13: Int = 42,
+ bar14: Int = 42,
+ bar15: Int = 42,
+ bar16: Int = 42,
+ bar17: Int = 42,
+ bar18: Int = 42,
+ bar19: Int = 42,
+ bar20: Int = 42,
+ bar21: Int = 42,
+ bar22: Int = 42,
+ bar23: Int = 42,
+ bar24: Int = 42,
+ bar25: Int = 42,
+ bar26: Int = 42,
+ bar27: Int = 42,
+ bar28: Int = 42,
+ bar29: Int = 42,
+ bar30: Int = 42,
+ bar31: Int = 42,
+ bar32: Int = 42,
+ bar33: Int = 42
+) {
+ println(bar1)
+ println(bar2)
+ println(bar3)
+ println(bar4)
+ println(bar5)
+ println(bar6)
+ println(bar7)
+ println(bar8)
+ println(bar9)
+ println(bar10)
+ println(bar11)
+ println(bar12)
+ println(bar13)
+ println(bar14)
+ println(bar15)
+ println(bar16)
+ println(bar17)
+ println(bar18)
+ println(bar19)
+ println(bar20)
+ println(bar21)
+ println(bar22)
+ println(bar23)
+ println(bar24)
+ println(bar25)
+ println(bar26)
+ println(bar27)
+ println(bar28)
+ println(bar29)
+ println(bar30)
+ println(bar31)
+ println(bar32)
+ println(bar33)
+}
\ No newline at end of file