Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ kotlin {
tasks.compileTestKotlin {
compilerOptions {
languageVersion.set(KotlinVersion.KOTLIN_1_9)
freeCompilerArgs.add("-Xjvm-default=all-compatibility")
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/main/kotlin/api/KotlinMetadataSignature.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ internal data class MethodBinarySignature(
super.isEffectivelyPublic(classAccess, classVisibility)
&& !isAccessOrAnnotationsMethod()
&& !isDummyDefaultConstructor()
&& !isSuspendImplMethod()

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

private fun isDummyDefaultConstructor() =
access.isSynthetic && name == "<init>" && desc == "(Lkotlin/jvm/internal/DefaultConstructorMarker;)V"

/**
* Kotlin compiler emits special `<originalFunctionName>$suspendImpl` methods for open
* suspendable functions. These synthetic functions could only be invoked from original function,
* or from a corresponding continuation. They don't constitute class's public ABI, but in some cases
* they might be declared public (namely, in case of default interface methods).
*/
private fun isSuspendImplMethod() = access.isSynthetic && name.endsWith("\$suspendImpl")
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/test/kotlin/cases/default/default.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ public class cases/default/ClassFunctions {

public abstract interface class cases/default/InterfaceFunctions {
public abstract fun withAllDefaults (ILjava/lang/String;)V
public static synthetic fun withAllDefaults$default (Lcases/default/InterfaceFunctions;ILjava/lang/String;ILjava/lang/Object;)V
public abstract fun withSomeDefaults (ILjava/lang/String;)V
public static synthetic fun withSomeDefaults$default (Lcases/default/InterfaceFunctions;ILjava/lang/String;ILjava/lang/Object;)V
}

public final class cases/default/InterfaceFunctions$DefaultImpls {
Expand Down
4 changes: 2 additions & 2 deletions src/test/kotlin/cases/interfaces/interfaces.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
public abstract interface class cases/interfaces/BaseWithImpl {
public abstract fun foo ()I
public fun foo ()I
}

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

public abstract interface class cases/interfaces/DerivedWithImpl : cases/interfaces/BaseWithImpl {
public abstract fun foo ()I
public fun foo ()I
}

public final class cases/interfaces/DerivedWithImpl$DefaultImpls {
Expand Down
22 changes: 22 additions & 0 deletions src/test/kotlin/cases/suspend/suspend.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2016-2024 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package cases.suspend

public interface I {
suspend fun openFunction(): Int = 42
}

public interface II : I {
override suspend fun openFunction(): Int {
return super.openFunction() + 1
}
}

public open class C : II {
override suspend fun openFunction(): Int {
return super.openFunction() + 2
}
}
21 changes: 21 additions & 0 deletions src/test/kotlin/cases/suspend/suspend.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
public class cases/suspend/C : cases/suspend/II {
public fun <init> ()V
public fun openFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public abstract interface class cases/suspend/I {
public fun openFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class cases/suspend/I$DefaultImpls {
public static fun openFunction (Lcases/suspend/I;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public abstract interface class cases/suspend/II : cases/suspend/I {
public fun openFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class cases/suspend/II$DefaultImpls {
public static fun openFunction (Lcases/suspend/II;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

4 changes: 3 additions & 1 deletion src/test/kotlin/tests/CasesPublicAPITest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 JetBrains s.r.o.
* Copyright 2016-2024 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

Expand Down Expand Up @@ -58,6 +58,8 @@ class CasesPublicAPITest {

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

@Test fun suspend() { snapshotAPIAndCompare(testName.methodName) }

@Test fun whenMappings() { snapshotAPIAndCompare(testName.methodName) }

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