[PL] ABI compatibility tests for reworked partial linkage

This commit is contained in:
Dmitriy Dolovov
2023-03-22 13:59:33 +01:00
committed by Space Team
parent 2a4d880037
commit 4f1155b06f
262 changed files with 4278 additions and 1359 deletions
@@ -1,21 +1,26 @@
public fun publicToInternalTopLevelFunction() = "publicToInternalTopLevelFunction.v1"
public fun publicToInternalPATopLevelFunction() = "publicToInternalPATopLevelFunction.v1"
public fun publicToPrivateTopLevelFunction() = "publicToPrivateTopLevelFunction.v1"
open class Container {
public fun publicToProtectedFunction() = "Container.publicToProtectedFunction.v1"
public fun publicToInternalFunction() = "Container.publicToInternalFunction.v1"
public fun publicToInternalPAFunction() = "Container.publicToInternalPAFunction.v1"
public fun publicToPrivateFunction() = "Container.publicToPrivateFunction.v1"
protected fun protectedToPublicFunction() = "Container.protectedToPublicFunction.v1"
protected fun protectedToInternalFunction() = "Container.protectedToInternalFunction.v1"
protected fun protectedToInternalPAFunction() = "Container.protectedToInternalPAFunction.v1"
protected fun protectedToPrivateFunction() = "Container.protectedToPrivateFunction.v1"
public open fun publicToProtectedOverriddenFunction() = "Container.publicToProtectedOverriddenFunction.v1"
public open fun publicToInternalOverriddenFunction() = "Container.publicToInternalOverriddenFunction.v1"
public open fun publicToInternalPAOverriddenFunction() = "Container.publicToInternalPAOverriddenFunction.v1"
public open fun publicToPrivateOverriddenFunction() = "Container.publicToPrivateOverriddenFunction.v1"
protected open fun protectedToPublicOverriddenFunction() = "Container.protectedToPublicOverriddenFunction.v1"
protected open fun protectedToInternalOverriddenFunction() = "Container.protectedToInternalOverriddenFunction.v1"
protected open fun protectedToInternalPAOverriddenFunction() = "Container.protectedToInternalPAOverriddenFunction.v1"
protected open fun protectedToPrivateOverriddenFunction() = "Container.protectedToPrivateOverriddenFunction.v1"
// public fun newPublicFunction() = "Container.newPublicFunction.v1"
@@ -24,5 +29,7 @@ open class Container {
// protected open fun newOpenProtectedFunction() = "Container.newOpenProtectedFunction.v1"
// internal fun newInternalFunction() = "Container.newInternalFunction.v1"
// internal open fun newOpenInternalFunction() = "Container.newOpenInternalFunction.v1"
// @PublishedApi internal fun newInternalPAFunction() = "Container.newInternalPAFunction.v1"
// @PublishedApi internal open fun newOpenInternalPAFunction() = "Container.newOpenInternalPAFunction.v1"
// private fun newPrivateFunction() = "Container.newPrivateFunction.v1"
}
@@ -1,21 +1,26 @@
internal fun publicToInternalTopLevelFunction() = "publicToInternalTopLevelFunction.v2"
@PublishedApi internal fun publicToInternalPATopLevelFunction() = "publicToInternalPATopLevelFunction.v2"
private fun publicToPrivateTopLevelFunction() = "publicToPrivateTopLevelFunction.v2"
open class Container {
protected fun publicToProtectedFunction() = "Container.publicToProtectedFunction.v2"
internal fun publicToInternalFunction() = "Container.publicToInternalFunction.v2"
@PublishedApi internal fun publicToInternalPAFunction() = "Container.publicToInternalPAFunction.v2"
private fun publicToPrivateFunction() = "Container.publicToPrivateFunction.v2"
public fun protectedToPublicFunction() = "Container.protectedToPublicFunction.v2"
internal fun protectedToInternalFunction() = "Container.protectedToInternalFunction.v2"
@PublishedApi internal fun protectedToInternalPAFunction() = "Container.protectedToInternalPAFunction.v2"
private fun protectedToPrivateFunction() = "Container.protectedToPrivateFunction.v2"
protected open fun publicToProtectedOverriddenFunction() = "Container.publicToProtectedOverriddenFunction.v2"
internal open fun publicToInternalOverriddenFunction() = "Container.publicToInternalOverriddenFunction.v2"
@PublishedApi internal open fun publicToInternalPAOverriddenFunction() = "Container.publicToInternalPAOverriddenFunction.v2"
private /*open*/ fun publicToPrivateOverriddenFunction() = "Container.publicToPrivateOverriddenFunction.v2"
public open fun protectedToPublicOverriddenFunction() = "Container.protectedToPublicOverriddenFunction.v2"
internal open fun protectedToInternalOverriddenFunction() = "Container.protectedToInternalOverriddenFunction.v2"
@PublishedApi internal open fun protectedToInternalPAOverriddenFunction() = "Container.protectedToInternalPAOverriddenFunction.v2"
private /*open*/ fun protectedToPrivateOverriddenFunction() = "Container.protectedToPrivateOverriddenFunction.v2"
public fun newPublicFunction() = "Container.newPublicFunction.v2"
@@ -24,5 +29,7 @@ open class Container {
protected open fun newOpenProtectedFunction() = "Container.newOpenProtectedFunction.v2"
internal fun newInternalFunction() = "Container.newInternalFunction.v2"
internal open fun newOpenInternalFunction() = "Container.newOpenInternalFunction.v2"
@PublishedApi internal fun newInternalPAFunction() = "Container.newInternalPAFunction.v2"
@PublishedApi internal open fun newOpenInternalPAFunction() = "Container.newOpenInternalPAFunction.v2"
private fun newPrivateFunction() = "Container.newPrivateFunction.v2"
}
@@ -2,25 +2,30 @@ class ContainerImpl : Container() {
// Just to check that accessing from within the class hierarchy has the same effect as accessing from the outside:
fun publicToProtectedFunctionAccess() = publicToProtectedFunction()
fun publicToInternalFunctionAccess() = publicToInternalFunction()
fun publicToInternalPAFunctionAccess() = publicToInternalPAFunction()
fun publicToPrivateFunctionAccess() = publicToPrivateFunction()
// As far as protected members can't be accessed outside of the class hierarchy, we need special accessors.
fun protectedToPublicFunctionAccess() = protectedToPublicFunction()
fun protectedToInternalFunctionAccess() = protectedToInternalFunction()
fun protectedToInternalPAFunctionAccess() = protectedToInternalPAFunction()
fun protectedToPrivateFunctionAccess() = protectedToPrivateFunction()
// Overridden functions with changed visibility:
override fun publicToProtectedOverriddenFunction() = "ContainerImpl.publicToProtectedOverriddenFunction"
override fun publicToInternalOverriddenFunction() = "ContainerImpl.publicToInternalOverriddenFunction"
override fun publicToInternalPAOverriddenFunction() = "ContainerImpl.publicToInternalPAOverriddenFunction"
override fun publicToPrivateOverriddenFunction() = "ContainerImpl.publicToPrivateOverriddenFunction"
override fun protectedToPublicOverriddenFunction() = "ContainerImpl.protectedToPublicOverriddenFunction"
override fun protectedToInternalOverriddenFunction() = "ContainerImpl.protectedToInternalOverriddenFunction"
override fun protectedToInternalPAOverriddenFunction() = "ContainerImpl.protectedToInternalPAOverriddenFunction"
override fun protectedToPrivateOverriddenFunction() = "ContainerImpl.protectedToPrivateOverriddenFunction"
// As far as protected members can't be accessed outside of the class hierarchy, we need special accessors.
fun protectedToPublicOverriddenFunctionAccess() = protectedToPublicOverriddenFunction()
fun protectedToInternalOverriddenFunctionAccess() = protectedToInternalOverriddenFunction()
fun protectedToInternalPAOverriddenFunctionAccess() = protectedToInternalPAOverriddenFunction()
fun protectedToPrivateOverriddenFunctionAccess() = protectedToPrivateOverriddenFunction()
// Functions that accedentally start to override/conflict with functions added to Container since version v2:
@@ -30,6 +35,8 @@ class ContainerImpl : Container() {
protected fun newOpenProtectedFunction() = "ContainerImpl.newOpenProtectedFunction"
internal fun newInternalFunction() = "ContainerImpl.newInternalFunction"
internal fun newOpenInternalFunction() = "ContainerImpl.newOpenInternalFunction"
@PublishedApi internal fun newInternalPAFunction() = "ContainerImpl.newInternalPAFunction"
@PublishedApi internal fun newOpenInternalPAFunction() = "ContainerImpl.newOpenInternalPAFunction"
private fun newPrivateFunction() = "ContainerImpl.newPrivateFunction"
// As far as protected/private members can't be accessed outside of the class hierarchy, and internal can't be accessed
@@ -38,5 +45,7 @@ class ContainerImpl : Container() {
fun newOpenProtectedFunctionAccess() = newOpenProtectedFunction()
fun newInternalFunctionAccess() = newInternalFunction()
fun newOpenInternalFunctionAccess() = newOpenInternalFunction()
fun newInternalPAFunctionAccess() = newInternalPAFunction()
fun newOpenInternalPAFunctionAccess() = newOpenInternalPAFunction()
fun newPrivateFunctionAccess() = newPrivateFunction()
}
+59 -27
View File
@@ -1,33 +1,65 @@
import abitestutils.abiTest
import abitestutils.TestBuilder
import abitestutils.TestMode.NATIVE_CACHE_STATIC_EVERYWHERE
fun box() = abiTest {
val c = Container()
val ci = ContainerImpl()
expectSuccess("publicToInternalTopLevelFunction.v2") { publicToInternalTopLevelFunction() }
expectFailure(prefixed("function publicToPrivateTopLevelFunction can not be called")) { publicToPrivateTopLevelFunction() }
expectSuccess("Container.publicToProtectedFunction.v2") { c.publicToProtectedFunction() }
expectSuccess("Container.publicToProtectedFunction.v2") { ci.publicToProtectedFunction() }
expectFailure(prefixed("function publicToInternalFunction can not be called")) { c.publicToInternalFunction() }
expectFailure(prefixed("function publicToInternalFunction can not be called")) { ci.publicToInternalFunction() }
expectFailure(prefixed("function publicToPrivateFunction can not be called")) { c.publicToPrivateFunction() }
expectFailure(prefixed("function publicToPrivateFunction can not be called")) { ci.publicToPrivateFunction() }
expectSuccess("Container.publicToProtectedFunction.v2") { ci.publicToProtectedFunctionAccess() }
expectFailure(prefixed("function publicToInternalFunction can not be called")) { ci.publicToInternalFunctionAccess() }
expectFailure(prefixed("function publicToPrivateFunction can not be called")) { ci.publicToPrivateFunctionAccess() }
expectSuccess("Container.protectedToPublicFunction.v2") { ci.protectedToPublicFunctionAccess() }
expectFailure(prefixed("function protectedToInternalFunction can not be called")) { ci.protectedToInternalFunctionAccess() }
expectFailure(prefixed("function protectedToPrivateFunction can not be called")) { ci.protectedToPrivateFunctionAccess() }
expectSuccess("ContainerImpl.publicToProtectedOverriddenFunction") { ci.publicToProtectedOverriddenFunction() }
expectSuccess("ContainerImpl.publicToInternalOverriddenFunction") { ci.publicToInternalOverriddenFunction() }
expectSuccess("ContainerImpl.publicToPrivateOverriddenFunction") { ci.publicToPrivateOverriddenFunction() }
expectSuccess("ContainerImpl.protectedToPublicOverriddenFunction") { ci.protectedToPublicOverriddenFunctionAccess() }
expectSuccess("ContainerImpl.protectedToInternalOverriddenFunction") { ci.protectedToInternalOverriddenFunctionAccess() }
expectSuccess("ContainerImpl.protectedToPrivateOverriddenFunction") { ci.protectedToPrivateOverriddenFunctionAccess() }
expectSuccess("ContainerImpl.newPublicFunction") { ci.newPublicFunction() }
expectSuccess("ContainerImpl.newOpenPublicFunction") { ci.newOpenPublicFunction() }
expectSuccess("ContainerImpl.newProtectedFunction") { ci.newProtectedFunctionAccess() }
expectSuccess("ContainerImpl.newOpenProtectedFunction") { ci.newOpenProtectedFunctionAccess() }
expectSuccess("ContainerImpl.newInternalFunction") { ci.newInternalFunctionAccess() }
expectSuccess("ContainerImpl.newOpenInternalFunction") { ci.newOpenInternalFunctionAccess() }
expectSuccess("ContainerImpl.newPrivateFunction") { ci.newPrivateFunctionAccess() }
success("publicToInternalTopLevelFunction.v2") { publicToInternalTopLevelFunction() } // Signature remains the same.
success("publicToInternalPATopLevelFunction.v2") { publicToInternalPATopLevelFunction() } // Signature remains the same.
unlinkedSymbol("/publicToPrivateTopLevelFunction") { publicToPrivateTopLevelFunction() } // Signature changed.
success("Container.publicToProtectedFunction.v2") { c.publicToProtectedFunction() } // Signature remains the same.
success("Container.publicToProtectedFunction.v2") { ci.publicToProtectedFunction() } // Signature remains the same.
// TODO: KT-54469, Container.publicToInternalFunction() should fail because it is accessed from another module.
success("Container.publicToInternalFunction.v2") { c.publicToInternalFunction() } // Signature remains the same.
unlinkedSymbol("/ContainerImpl.publicToInternalFunction") { ci.publicToInternalFunction() } // FOs are not generated for internal members from other module.
// TODO: KT-54469, Container.publicToInternalPAFunction() should fail because it is accessed from another module.
success("Container.publicToInternalPAFunction.v2") { c.publicToInternalPAFunction() } // Signature remains the same.
unlinkedSymbol("/ContainerImpl.publicToInternalPAFunction") { ci.publicToInternalPAFunction() } // FOs are not generated for internal members from other module.
inaccessible("publicToPrivateFunction") { c.publicToPrivateFunction() } // Inaccessible from other module though signature remains the same.
unlinkedSymbol("/ContainerImpl.publicToPrivateFunction") { ci.publicToPrivateFunction() } // FOs are not generated for private members.
success("Container.publicToProtectedFunction.v2") { ci.publicToProtectedFunctionAccess() } // Signature remains the same.
unlinkedSymbol("/ContainerImpl.publicToInternalFunction") { ci.publicToInternalFunctionAccess() } // FOs are not generated for internal members from other module.
unlinkedSymbol("/ContainerImpl.publicToInternalPAFunction") { ci.publicToInternalPAFunctionAccess() } // FOs are not generated for internal members from other module.
unlinkedSymbol("/ContainerImpl.publicToPrivateFunction") { ci.publicToPrivateFunctionAccess() } // FOs are not generated for private members.
success("Container.protectedToPublicFunction.v2") { ci.protectedToPublicFunctionAccess() } // Signature remains the same.
unlinkedSymbol("/ContainerImpl.protectedToInternalFunction") { ci.protectedToInternalFunctionAccess() } // FOs are not generated for internal members from other module.
unlinkedSymbol("/ContainerImpl.protectedToInternalPAFunction") { ci.protectedToInternalPAFunctionAccess() } // FOs are not generated for internal members from other module.
unlinkedSymbol("/ContainerImpl.protectedToPrivateFunction") { ci.protectedToPrivateFunctionAccess() } // FOs are not generated for private members.
success("ContainerImpl.publicToProtectedOverriddenFunction") { ci.publicToProtectedOverriddenFunction() }
success("ContainerImpl.publicToInternalOverriddenFunction") { ci.publicToInternalOverriddenFunction() }
success("ContainerImpl.publicToInternalPAOverriddenFunction") { ci.publicToInternalPAOverriddenFunction() }
success("ContainerImpl.publicToPrivateOverriddenFunction") { ci.publicToPrivateOverriddenFunction() }
success("ContainerImpl.protectedToPublicOverriddenFunction") { ci.protectedToPublicOverriddenFunctionAccess() }
success("ContainerImpl.protectedToInternalOverriddenFunction") { ci.protectedToInternalOverriddenFunctionAccess() }
success("ContainerImpl.protectedToInternalPAOverriddenFunction") { ci.protectedToInternalPAOverriddenFunctionAccess() }
success("ContainerImpl.protectedToPrivateOverriddenFunction") { ci.protectedToPrivateOverriddenFunctionAccess() }
success("ContainerImpl.newPublicFunction") { ci.newPublicFunction() }
success("ContainerImpl.newOpenPublicFunction") { ci.newOpenPublicFunction() }
success("ContainerImpl.newProtectedFunction") { ci.newProtectedFunctionAccess() }
success("ContainerImpl.newOpenProtectedFunction") { ci.newOpenProtectedFunctionAccess() }
success("ContainerImpl.newInternalFunction") { ci.newInternalFunctionAccess() }
success("ContainerImpl.newOpenInternalFunction") { ci.newOpenInternalFunctionAccess() }
success("ContainerImpl.newInternalPAFunction") { ci.newInternalPAFunctionAccess() }
success("ContainerImpl.newOpenInternalPAFunction") { ci.newOpenInternalPAFunctionAccess() }
success("ContainerImpl.newPrivateFunction") { ci.newPrivateFunctionAccess() }
}
// Shortcuts:
private inline fun TestBuilder.success(expectedOutcome: String, noinline block: () -> String) =
expectSuccess(expectedOutcome, block)
private inline fun TestBuilder.unlinkedSymbol(signature: String, noinline block: () -> Unit) {
val functionName = signature.removePrefix("/").substringAfterLast(".")
expectFailure(linkage("Function '$functionName' can not be called: No function found for symbol '$signature'"), block)
}
private inline fun TestBuilder.inaccessible(functionName: String, noinline block: () -> Unit) = expectFailure(
linkage("Function '$functionName' can not be called: Private function declared in module <lib1> can not be accessed in module <main>"),
block
)
@@ -1,4 +1,3 @@
MUTED
MODULES: lib1, lib2, main
STEP 0: