Skip to content

Commit 18c6660

Browse files
fzhinkinshanshin
authored andcommitted
[ABI Validation] Filter out $suspendImpl functions from dumps
* Enable default interface methods generation * Filter out $suspendImpl methods. Closes Kotlin/binary-compatibility-validator#270 Pull request Kotlin/binary-compatibility-validator#271 Moved from Kotlin/binary-compatibility-validator@91dc2a9
1 parent 6e48018 commit 18c6660

File tree

7 files changed

+60
-3
lines changed

7 files changed

+60
-3
lines changed

libraries/tools/abi-validation/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ kotlin {
109109
tasks.compileTestKotlin {
110110
compilerOptions {
111111
languageVersion.set(KotlinVersion.KOTLIN_1_9)
112+
freeCompilerArgs.add("-Xjvm-default=all-compatibility")
112113
}
113114
}
114115

libraries/tools/abi-validation/src/main/kotlin/api/KotlinMetadataSignature.kt

+9
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ internal data class MethodBinarySignature(
6060
super.isEffectivelyPublic(classAccess, classVisibility)
6161
&& !isAccessOrAnnotationsMethod()
6262
&& !isDummyDefaultConstructor()
63+
&& !isSuspendImplMethod()
6364

6465
override fun findMemberVisibility(classVisibility: ClassVisibility?): MemberVisibility? {
6566
return super.findMemberVisibility(classVisibility)
@@ -71,6 +72,14 @@ internal data class MethodBinarySignature(
7172

7273
private fun isDummyDefaultConstructor() =
7374
access.isSynthetic && name == "<init>" && desc == "(Lkotlin/jvm/internal/DefaultConstructorMarker;)V"
75+
76+
/**
77+
* Kotlin compiler emits special `<originalFunctionName>$suspendImpl` methods for open
78+
* suspendable functions. These synthetic functions could only be invoked from original function,
79+
* or from a corresponding continuation. They don't constitute class's public ABI, but in some cases
80+
* they might be declared public (namely, in case of default interface methods).
81+
*/
82+
private fun isSuspendImplMethod() = access.isSynthetic && name.endsWith("\$suspendImpl")
7483
}
7584

7685
/**

libraries/tools/abi-validation/src/test/kotlin/cases/default/default.txt

+2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ public class cases/default/ClassFunctions {
77

88
public abstract interface class cases/default/InterfaceFunctions {
99
public abstract fun withAllDefaults (ILjava/lang/String;)V
10+
public static synthetic fun withAllDefaults$default (Lcases/default/InterfaceFunctions;ILjava/lang/String;ILjava/lang/Object;)V
1011
public abstract fun withSomeDefaults (ILjava/lang/String;)V
12+
public static synthetic fun withSomeDefaults$default (Lcases/default/InterfaceFunctions;ILjava/lang/String;ILjava/lang/Object;)V
1113
}
1214

1315
public final class cases/default/InterfaceFunctions$DefaultImpls {

libraries/tools/abi-validation/src/test/kotlin/cases/interfaces/interfaces.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
public abstract interface class cases/interfaces/BaseWithImpl {
2-
public abstract fun foo ()I
2+
public fun foo ()I
33
}
44

55
public final class cases/interfaces/BaseWithImpl$DefaultImpls {
66
public static fun foo (Lcases/interfaces/BaseWithImpl;)I
77
}
88

99
public abstract interface class cases/interfaces/DerivedWithImpl : cases/interfaces/BaseWithImpl {
10-
public abstract fun foo ()I
10+
public fun foo ()I
1111
}
1212

1313
public final class cases/interfaces/DerivedWithImpl$DefaultImpls {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2016-2024 JetBrains s.r.o.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package cases.suspend
7+
8+
public interface I {
9+
suspend fun openFunction(): Int = 42
10+
}
11+
12+
public interface II : I {
13+
override suspend fun openFunction(): Int {
14+
return super.openFunction() + 1
15+
}
16+
}
17+
18+
public open class C : II {
19+
override suspend fun openFunction(): Int {
20+
return super.openFunction() + 2
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
public class cases/suspend/C : cases/suspend/II {
2+
public fun <init> ()V
3+
public fun openFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
4+
}
5+
6+
public abstract interface class cases/suspend/I {
7+
public fun openFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
8+
}
9+
10+
public final class cases/suspend/I$DefaultImpls {
11+
public static fun openFunction (Lcases/suspend/I;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
12+
}
13+
14+
public abstract interface class cases/suspend/II : cases/suspend/I {
15+
public fun openFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
16+
}
17+
18+
public final class cases/suspend/II$DefaultImpls {
19+
public static fun openFunction (Lcases/suspend/II;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
20+
}
21+

libraries/tools/abi-validation/src/test/kotlin/tests/CasesPublicAPITest.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2020 JetBrains s.r.o.
2+
* Copyright 2016-2024 JetBrains s.r.o.
33
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
44
*/
55

@@ -58,6 +58,8 @@ class CasesPublicAPITest {
5858

5959
@Test fun special() { snapshotAPIAndCompare(testName.methodName) }
6060

61+
@Test fun suspend() { snapshotAPIAndCompare(testName.methodName) }
62+
6163
@Test fun whenMappings() { snapshotAPIAndCompare(testName.methodName) }
6264

6365
@Test fun enums() { snapshotAPIAndCompare(testName.methodName) }

0 commit comments

Comments
 (0)