[PL] Make call an exception in case of several inherited implementations
^KT-57701
This commit is contained in:
committed by
Space Team
parent
fde8909e6f
commit
ee1608ec99
+5
-2
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.ir.linkage.partial
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrOverridableDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
|
||||||
interface IrUnimplementedOverridesStrategy {
|
interface IrUnimplementedOverridesStrategy {
|
||||||
class Customization(val origin: IrDeclarationOrigin?, val modality: Modality?) {
|
class Customization(val origin: IrDeclarationOrigin?, val modality: Modality?) {
|
||||||
@@ -17,9 +19,10 @@ interface IrUnimplementedOverridesStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : IrOverridableMember> computeCustomization(overridableMember: T, parent: IrClass): Customization
|
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> computeCustomization(overridableMember: T, parent: IrClass): Customization
|
||||||
|
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> postProcessGeneratedFakeOverride(overridableMember: T, parent: IrClass) {}
|
||||||
|
|
||||||
object ProcessAsFakeOverrides : IrUnimplementedOverridesStrategy {
|
object ProcessAsFakeOverrides : IrUnimplementedOverridesStrategy {
|
||||||
override fun <T : IrOverridableMember> computeCustomization(overridableMember: T, parent: IrClass) = Customization.NO
|
override fun <S : IrSymbol, T : IrOverridableDeclaration<S>> computeCustomization(overridableMember: T, parent: IrClass) = Customization.NO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,4 +172,11 @@ sealed interface PartialLinkageCase {
|
|||||||
val annotationConstructorSymbol: IrConstructorSymbol,
|
val annotationConstructorSymbol: IrConstructorSymbol,
|
||||||
val holderDeclarationSymbol: IrSymbol
|
val holderDeclarationSymbol: IrSymbol
|
||||||
) : PartialLinkageCase
|
) : PartialLinkageCase
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callable, which is not implemented, but inherited several implementations from super interfaces.
|
||||||
|
*
|
||||||
|
* Applicable to: Declarations (functions, properties).
|
||||||
|
*/
|
||||||
|
class AmbiguousNonOverriddenCallable(val callable: IrOverridableDeclaration<*>) : PartialLinkageCase
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -15,6 +15,9 @@ enum class PartiallyLinkedDeclarationOrigin : IrDeclarationOrigin {
|
|||||||
/** The abstract callable member that needs to be implemented in non-abstract class */
|
/** The abstract callable member that needs to be implemented in non-abstract class */
|
||||||
UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER,
|
UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER,
|
||||||
|
|
||||||
|
/** The callable member is not implemented and inherit several implementations from interfaces, but no implementation from class */
|
||||||
|
AMBIGUOUS_NON_OVERRIDDEN_CALLABLE_MEMBER,
|
||||||
|
|
||||||
/** Auxiliary declaration generated by [PartiallyLinkedIrTreePatcher] */
|
/** Auxiliary declaration generated by [PartiallyLinkedIrTreePatcher] */
|
||||||
AUXILIARY_GENERATED_DECLARATION;
|
AUXILIARY_GENERATED_DECLARATION;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,13 @@ abstract class FakeOverrideBuilderStrategy(
|
|||||||
private val friendModules: Map<String, Collection<String>>,
|
private val friendModules: Map<String, Collection<String>>,
|
||||||
private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy
|
private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy
|
||||||
) {
|
) {
|
||||||
open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember =
|
fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember =
|
||||||
buildFakeOverrideMember(superType, member, clazz, friendModules, unimplementedOverridesStrategy)
|
buildFakeOverrideMember(superType, member, clazz, friendModules, unimplementedOverridesStrategy)
|
||||||
|
|
||||||
|
fun postProcessGeneratedFakeOverride(fakeOverride: IrOverridableMember, clazz: IrClass) {
|
||||||
|
unimplementedOverridesStrategy.postProcessGeneratedFakeOverride(fakeOverride as IrOverridableDeclaration<*>, clazz)
|
||||||
|
}
|
||||||
|
|
||||||
fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) {
|
fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) {
|
||||||
when (fakeOverride) {
|
when (fakeOverride) {
|
||||||
is IrFunctionWithLateBinding -> linkFunctionFakeOverride(fakeOverride, compatibilityMode)
|
is IrFunctionWithLateBinding -> linkFunctionFakeOverride(fakeOverride, compatibilityMode)
|
||||||
@@ -437,6 +441,7 @@ class IrOverridingUtil(
|
|||||||
|
|
||||||
addedFakeOverrides.add(fakeOverride)
|
addedFakeOverrides.add(fakeOverride)
|
||||||
fakeOverrideBuilder.linkFakeOverride(fakeOverride, compatibilityMode)
|
fakeOverrideBuilder.linkFakeOverride(fakeOverride, compatibilityMode)
|
||||||
|
fakeOverrideBuilder.postProcessGeneratedFakeOverride(fakeOverride, currentClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isVisibilityMoreSpecific(
|
private fun isVisibilityMoreSpecific(
|
||||||
|
|||||||
+46
-7
@@ -6,23 +6,22 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.linkage.partial
|
package org.jetbrains.kotlin.backend.common.linkage.partial
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
|
||||||
import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy
|
import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy
|
||||||
import org.jetbrains.kotlin.ir.linkage.partial.PartiallyLinkedDeclarationOrigin
|
import org.jetbrains.kotlin.ir.linkage.partial.PartiallyLinkedDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.isNothing
|
import org.jetbrains.kotlin.ir.types.isNothing
|
||||||
|
import org.jetbrains.kotlin.ir.util.collectRealOverrides
|
||||||
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
|
|
||||||
internal class ImplementAsErrorThrowingStubs(
|
internal class ImplementAsErrorThrowingStubs(
|
||||||
private val partialLinkageSupport: PartialLinkageSupportForLinker
|
private val partialLinkageSupport: PartialLinkageSupportForLinker
|
||||||
) : IrUnimplementedOverridesStrategy {
|
) : IrUnimplementedOverridesStrategy {
|
||||||
override fun <T : IrOverridableMember> computeCustomization(overridableMember: T, parent: IrClass) =
|
override fun <S : IrSymbol, T : IrOverridableDeclaration<S>> computeCustomization(overridableMember: T, parent: IrClass) =
|
||||||
if (overridableMember.isAbstract
|
if (overridableMember.isAbstract
|
||||||
&& parent.isConcrete
|
&& parent.isConcrete
|
||||||
&& !parent.isExternal
|
&& parent.isEligibleForPartialLinkage()
|
||||||
&& !parent.delegatesToNothing
|
&& !parent.delegatesToNothing
|
||||||
&& !partialLinkageSupport.shouldBeSkipped(parent)
|
|
||||||
) {
|
) {
|
||||||
IrUnimplementedOverridesStrategy.Customization(
|
IrUnimplementedOverridesStrategy.Customization(
|
||||||
origin = PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER,
|
origin = PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER,
|
||||||
@@ -30,6 +29,46 @@ internal class ImplementAsErrorThrowingStubs(
|
|||||||
)
|
)
|
||||||
} else IrUnimplementedOverridesStrategy.Customization.NO
|
} else IrUnimplementedOverridesStrategy.Customization.NO
|
||||||
|
|
||||||
|
override fun <S : IrSymbol, T : IrOverridableDeclaration<S>> postProcessGeneratedFakeOverride(overridableMember: T, parent: IrClass) {
|
||||||
|
if (parent.isEligibleForPartialLinkage() && overridableMember.isAmbiguous()) {
|
||||||
|
fun IrOverridableDeclaration<*>.mark() {
|
||||||
|
if (isFakeOverride) {
|
||||||
|
origin = PartiallyLinkedDeclarationOrigin.AMBIGUOUS_NON_OVERRIDDEN_CALLABLE_MEMBER
|
||||||
|
isFakeOverride = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
overridableMember.mark()
|
||||||
|
if (overridableMember is IrProperty) {
|
||||||
|
overridableMember.getter?.mark()
|
||||||
|
overridableMember.setter?.mark()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function returns if fake override has unique implementation in super classes to be chosen on call
|
||||||
|
*
|
||||||
|
* Candidates is a list of real functions we override, which are not overridden themselves
|
||||||
|
* by any other function in the list.
|
||||||
|
*
|
||||||
|
* If there is a **real** super-class function in the list, it must be unique.
|
||||||
|
* In that case it is preferred over functions coming from default implementation in interfaces.
|
||||||
|
*
|
||||||
|
* If there is no such function, but there are several interface function - it is an incompatible change.
|
||||||
|
*
|
||||||
|
* This is done to mimic jvm behaviour.
|
||||||
|
*/
|
||||||
|
private fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.isAmbiguous(): Boolean {
|
||||||
|
val candidates = collectRealOverrides().filter { !it.isAbstract }
|
||||||
|
if (candidates.any { ((it.symbol.owner as IrDeclaration).parent as? IrClass)?.isInterface == false }) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return candidates.size > 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.isEligibleForPartialLinkage() = !isExternal && !partialLinkageSupport.shouldBeSkipped(this)
|
||||||
|
|
||||||
|
|
||||||
private val IrOverridableMember.isAbstract: Boolean
|
private val IrOverridableMember.isAbstract: Boolean
|
||||||
get() = modality == Modality.ABSTRACT
|
get() = modality == Modality.ABSTRACT
|
||||||
|
|
||||||
|
|||||||
+9
@@ -79,6 +79,8 @@ internal fun PartialLinkageCase.renderLinkageError(): String = buildString {
|
|||||||
|
|
||||||
is UnimplementedAbstractCallable -> unimplementedAbstractCallable(callable)
|
is UnimplementedAbstractCallable -> unimplementedAbstractCallable(callable)
|
||||||
is UnusableAnnotation -> unusableAnnotation(annotationConstructorSymbol, holderDeclarationSymbol)
|
is UnusableAnnotation -> unusableAnnotation(annotationConstructorSymbol, holderDeclarationSymbol)
|
||||||
|
|
||||||
|
is AmbiguousNonOverriddenCallable -> ambiguousNonOverriddenCallable(callable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,6 +590,13 @@ private fun Appendable.unusableAnnotation(annotationConstructorSymbol: IrConstru
|
|||||||
append("Unusable annotation ").declarationName(annotationConstructorSymbol)
|
append("Unusable annotation ").declarationName(annotationConstructorSymbol)
|
||||||
.append(" has been removed from ").declarationKindName(holderDeclarationSymbol, capitalized = false)
|
.append(" has been removed from ").declarationKindName(holderDeclarationSymbol, capitalized = false)
|
||||||
|
|
||||||
|
private fun Appendable.ambiguousNonOverriddenCallable(callable: IrOverridableDeclaration<*>): Appendable =
|
||||||
|
declarationKindName(callable.symbol, capitalized = true)
|
||||||
|
.append(" in ")
|
||||||
|
.declarationKindName(callable.parentAsClass.symbol, capitalized = false)
|
||||||
|
.append(" inherits more than one default implementation")
|
||||||
|
|
||||||
|
|
||||||
private fun Appendable.appendCapitalized(text: String, capitalized: Boolean): Appendable {
|
private fun Appendable.appendCapitalized(text: String, capitalized: Boolean): Appendable {
|
||||||
if (capitalized && text.isNotEmpty()) {
|
if (capitalized && text.isNotEmpty()) {
|
||||||
val firstChar = text[0]
|
val firstChar = text[0]
|
||||||
|
|||||||
+1
@@ -265,6 +265,7 @@ internal class PartiallyLinkedIrTreePatcher(
|
|||||||
// Compute the linkage case.
|
// Compute the linkage case.
|
||||||
val partialLinkageCase = when (declaration.origin) {
|
val partialLinkageCase = when (declaration.origin) {
|
||||||
PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER -> UnimplementedAbstractCallable(declaration)
|
PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER -> UnimplementedAbstractCallable(declaration)
|
||||||
|
PartiallyLinkedDeclarationOrigin.AMBIGUOUS_NON_OVERRIDDEN_CALLABLE_MEMBER -> AmbiguousNonOverriddenCallable(declaration)
|
||||||
PartiallyLinkedDeclarationOrigin.MISSING_DECLARATION -> MissingDeclaration(declaration.symbol)
|
PartiallyLinkedDeclarationOrigin.MISSING_DECLARATION -> MissingDeclaration(declaration.symbol)
|
||||||
else -> unusableClassifierInSignature?.let { DeclarationWithUnusableClassifier(declaration.symbol, it) }
|
else -> unusableClassifierInSignature?.let { DeclarationWithUnusableClassifier(declaration.symbol, it) }
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -24,15 +24,16 @@ sealed interface FailurePattern
|
|||||||
|
|
||||||
private typealias Block<T> = () -> T
|
private typealias Block<T> = () -> T
|
||||||
|
|
||||||
enum class TestMode(val isJs: Boolean = false, val isNative: Boolean = false) {
|
enum class TestMode(val isJs: Boolean = false, val isNative: Boolean = false, val hasCachesEnabled: Boolean = false) {
|
||||||
JS_NO_IC(isJs = true),
|
JS_NO_IC(isJs = true),
|
||||||
JS_WITH_IC(isJs = true),
|
JS_WITH_IC(isJs = true),
|
||||||
NATIVE_CACHE_NO(isNative = true),
|
NATIVE_CACHE_NO(isNative = true),
|
||||||
NATIVE_CACHE_STATIC_ONLY_DIST(isNative = true),
|
NATIVE_CACHE_STATIC_ONLY_DIST(isNative = true, hasCachesEnabled = true),
|
||||||
NATIVE_CACHE_STATIC_EVERYWHERE(isNative = true);
|
NATIVE_CACHE_STATIC_EVERYWHERE(isNative = true, hasCachesEnabled = true);
|
||||||
|
|
||||||
init {
|
init {
|
||||||
check(isJs xor isNative)
|
check(isJs xor isNative)
|
||||||
|
check(isNative || !hasCachesEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package lib1
|
||||||
|
|
||||||
|
interface I {
|
||||||
|
}
|
||||||
|
|
||||||
|
interface J {
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Default {
|
||||||
|
fun foo(): String = "Default v1"
|
||||||
|
val bar: String get() = "Default v1"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RemovedDefault {
|
||||||
|
fun foo(): String = "RemovedDefault v1"
|
||||||
|
val bar: String get() = "RemovedDefault v1"
|
||||||
|
}
|
||||||
|
|
||||||
|
open class Unrelated
|
||||||
|
|
||||||
|
abstract class AbstractUnrelated
|
||||||
|
|
||||||
|
open class WithFakeOverride : I
|
||||||
|
|
||||||
|
open class WithRealOverride : I
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package lib1
|
||||||
|
|
||||||
|
interface I {
|
||||||
|
fun foo(): String = "I v2"
|
||||||
|
val bar: String get() = "I v2"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface J {
|
||||||
|
fun foo(): String = "J v2"
|
||||||
|
val bar: String get() = "J v2"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Default {
|
||||||
|
fun foo(): String = "Default v2"
|
||||||
|
val bar: String get() = "Default v2"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RemovedDefault {
|
||||||
|
fun foo(): String
|
||||||
|
val bar: String
|
||||||
|
}
|
||||||
|
|
||||||
|
open class Unrelated {
|
||||||
|
fun foo(): String = "Unrelated v2"
|
||||||
|
val bar: String = "Unrelated v2"
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AbstractUnrelated {
|
||||||
|
abstract fun foo(): String
|
||||||
|
abstract val bar: String
|
||||||
|
}
|
||||||
|
|
||||||
|
open class WithFakeOverride : I
|
||||||
|
|
||||||
|
open class WithRealOverride : I {
|
||||||
|
override fun foo() = "WithRealOverride v2"
|
||||||
|
override val bar = "WithRealOverride v2"
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
STEP 0:
|
||||||
|
dependencies: stdlib
|
||||||
|
modifications:
|
||||||
|
U : l1.kt.0 -> l1.kt
|
||||||
|
STEP 1:
|
||||||
|
dependencies: stdlib
|
||||||
|
modifications:
|
||||||
|
U : l1.kt.1 -> l1.kt
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package lib2
|
||||||
|
|
||||||
|
import lib1.*
|
||||||
|
|
||||||
|
class I_Default : I, Default
|
||||||
|
class Default_I : Default, I
|
||||||
|
class I_RemovedDefault : I, RemovedDefault
|
||||||
|
class RemovedDefault_I : RemovedDefault, I
|
||||||
|
class I_J_Default : I, J, Default
|
||||||
|
class Default_J_I : Default, I, J
|
||||||
|
class I_J_RemovedDefault : I, J, RemovedDefault
|
||||||
|
class RemovedDefault_J_I : RemovedDefault, I, J
|
||||||
|
|
||||||
|
|
||||||
|
class Unrelated_I_Default : Unrelated(), I, Default
|
||||||
|
class Unrelated_Default_I : Unrelated(), Default, I
|
||||||
|
class Unrelated_I_RemovedDefault : Unrelated(), I, RemovedDefault
|
||||||
|
class Unrelated_RemovedDefault_I : Unrelated(), RemovedDefault, I
|
||||||
|
class Unrelated_I_J_Default : Unrelated(), I, J, Default
|
||||||
|
class Unrelated_Default_J_I : Unrelated(), Default, I, J
|
||||||
|
class Unrelated_I_J_RemovedDefault : Unrelated(), I, J, RemovedDefault
|
||||||
|
class Unrelated_RemovedDefault_J_I : Unrelated(), RemovedDefault, I, J
|
||||||
|
|
||||||
|
class AbstractUnrelated_I_Default : AbstractUnrelated(), I, Default
|
||||||
|
class AbstractUnrelated_Default_I : AbstractUnrelated(), Default, I
|
||||||
|
class AbstractUnrelated_I_RemovedDefault : AbstractUnrelated(), I, RemovedDefault
|
||||||
|
class AbstractUnrelated_RemovedDefault_I : AbstractUnrelated(), RemovedDefault, I
|
||||||
|
class AbstractUnrelated_I_J_Default : AbstractUnrelated(), I, J, Default
|
||||||
|
class AbstractUnrelated_Default_J_I : AbstractUnrelated(), Default, I, J
|
||||||
|
class AbstractUnrelated_I_J_RemovedDefault : AbstractUnrelated(), I, J, RemovedDefault
|
||||||
|
class AbstractUnrelated_RemovedDefault_J_I : AbstractUnrelated(), RemovedDefault, I, J
|
||||||
|
|
||||||
|
|
||||||
|
class WithFakeOverride_I_Default : WithFakeOverride(), I, Default
|
||||||
|
class WithFakeOverride_Default_I : WithFakeOverride(), Default, I
|
||||||
|
class WithFakeOverride_I_RemovedDefault : WithFakeOverride(), I, RemovedDefault
|
||||||
|
class WithFakeOverride_RemovedDefault_I : WithFakeOverride(), RemovedDefault, I
|
||||||
|
class WithFakeOverride_I_J_Default : WithFakeOverride(), I, J, Default
|
||||||
|
class WithFakeOverride_Default_J_I : WithFakeOverride(), Default, I, J
|
||||||
|
class WithFakeOverride_I_J_RemovedDefault : WithFakeOverride(), I, J, RemovedDefault
|
||||||
|
class WithFakeOverride_RemovedDefault_J_I : WithFakeOverride(), RemovedDefault, I, J
|
||||||
|
|
||||||
|
class WithRealOverride_I_Default : WithRealOverride(), I, Default
|
||||||
|
class WithRealOverride_Default_I : WithRealOverride(), Default, I
|
||||||
|
class WithRealOverride_I_RemovedDefault : WithRealOverride(), I, RemovedDefault
|
||||||
|
class WithRealOverride_RemovedDefault_I : WithRealOverride(), RemovedDefault, I
|
||||||
|
class WithRealOverride_I_J_Default : WithRealOverride(), I, J, Default
|
||||||
|
class WithRealOverride_Default_J_I : WithRealOverride(), Default, I, J
|
||||||
|
class WithRealOverride_I_J_RemovedDefault : WithRealOverride(), I, J, RemovedDefault
|
||||||
|
class WithRealOverride_RemovedDefault_J_I : WithRealOverride(), RemovedDefault, I, J
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
STEP 0:
|
||||||
|
dependencies: stdlib, lib1
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
import abitestutils.*
|
||||||
|
import lib1.*
|
||||||
|
import lib2.*
|
||||||
|
|
||||||
|
private fun TestBuilder.fe(className: String) = linkage("Function 'foo' in class '${className}' inherits more than one default implementation")
|
||||||
|
private fun TestBuilder.pe(className: String) = linkage("Property accessor 'bar.<get-bar>' in class '${className}' inherits more than one default implementation")
|
||||||
|
|
||||||
|
fun box() = abiTest {
|
||||||
|
// For now it's not working with caches, because of incorrect lazy-IR usage.
|
||||||
|
// Check KT-54019 for details.
|
||||||
|
if (testMode.hasCachesEnabled) {
|
||||||
|
expectSuccess("OK") { "OK" }
|
||||||
|
return@abiTest
|
||||||
|
}
|
||||||
|
val instance_I_Default = I_Default()
|
||||||
|
val instance_Default_I = Default_I()
|
||||||
|
val instance_I_RemovedDefault = I_RemovedDefault()
|
||||||
|
val instance_RemovedDefault_I = RemovedDefault_I()
|
||||||
|
val instance_I_J_Default = I_J_Default()
|
||||||
|
val instance_Default_J_I = Default_J_I()
|
||||||
|
val instance_I_J_RemovedDefault = I_J_RemovedDefault()
|
||||||
|
val instance_RemovedDefault_J_I = RemovedDefault_J_I()
|
||||||
|
val instance_Unrelated_I_Default = Unrelated_I_Default()
|
||||||
|
val instance_Unrelated_Default_I = Unrelated_Default_I()
|
||||||
|
val instance_Unrelated_I_RemovedDefault = Unrelated_I_RemovedDefault()
|
||||||
|
val instance_Unrelated_RemovedDefault_I = Unrelated_RemovedDefault_I()
|
||||||
|
val instance_Unrelated_I_J_Default = Unrelated_I_J_Default()
|
||||||
|
val instance_Unrelated_Default_J_I = Unrelated_Default_J_I()
|
||||||
|
val instance_Unrelated_I_J_RemovedDefault = Unrelated_I_J_RemovedDefault()
|
||||||
|
val instance_Unrelated_RemovedDefault_J_I = Unrelated_RemovedDefault_J_I()
|
||||||
|
val instance_AbstractUnrelated_I_Default = AbstractUnrelated_I_Default()
|
||||||
|
val instance_AbstractUnrelated_Default_I = AbstractUnrelated_Default_I()
|
||||||
|
val instance_AbstractUnrelated_I_RemovedDefault = AbstractUnrelated_I_RemovedDefault()
|
||||||
|
val instance_AbstractUnrelated_RemovedDefault_I = AbstractUnrelated_RemovedDefault_I()
|
||||||
|
val instance_AbstractUnrelated_I_J_Default = AbstractUnrelated_I_J_Default()
|
||||||
|
val instance_AbstractUnrelated_Default_J_I = AbstractUnrelated_Default_J_I()
|
||||||
|
val instance_AbstractUnrelated_I_J_RemovedDefault = AbstractUnrelated_I_J_RemovedDefault()
|
||||||
|
val instance_AbstractUnrelated_RemovedDefault_J_I = AbstractUnrelated_RemovedDefault_J_I()
|
||||||
|
val instance_WithFakeOverride_I_Default = WithFakeOverride_I_Default()
|
||||||
|
val instance_WithFakeOverride_Default_I = WithFakeOverride_Default_I()
|
||||||
|
val instance_WithFakeOverride_I_RemovedDefault = WithFakeOverride_I_RemovedDefault()
|
||||||
|
val instance_WithFakeOverride_RemovedDefault_I = WithFakeOverride_RemovedDefault_I()
|
||||||
|
val instance_WithFakeOverride_I_J_Default = WithFakeOverride_I_J_Default()
|
||||||
|
val instance_WithFakeOverride_Default_J_I = WithFakeOverride_Default_J_I()
|
||||||
|
val instance_WithFakeOverride_I_J_RemovedDefault = WithFakeOverride_I_J_RemovedDefault()
|
||||||
|
val instance_WithFakeOverride_RemovedDefault_J_I = WithFakeOverride_RemovedDefault_J_I()
|
||||||
|
val instance_WithRealOverride_I_Default = WithRealOverride_I_Default()
|
||||||
|
val instance_WithRealOverride_Default_I = WithRealOverride_Default_I()
|
||||||
|
val instance_WithRealOverride_I_RemovedDefault = WithRealOverride_I_RemovedDefault()
|
||||||
|
val instance_WithRealOverride_RemovedDefault_I = WithRealOverride_RemovedDefault_I()
|
||||||
|
val instance_WithRealOverride_I_J_Default = WithRealOverride_I_J_Default()
|
||||||
|
val instance_WithRealOverride_Default_J_I = WithRealOverride_Default_J_I()
|
||||||
|
val instance_WithRealOverride_I_J_RemovedDefault = WithRealOverride_I_J_RemovedDefault()
|
||||||
|
val instance_WithRealOverride_RemovedDefault_J_I = WithRealOverride_RemovedDefault_J_I()
|
||||||
|
|
||||||
|
expectFailure(fe("I_Default")) { instance_I_Default.foo() }
|
||||||
|
expectFailure(fe("Default_I")) { instance_Default_I.foo() }
|
||||||
|
expectSuccess("I v2") { instance_I_RemovedDefault.foo() }
|
||||||
|
expectSuccess("I v2") { instance_RemovedDefault_I.foo() }
|
||||||
|
expectFailure(fe("I_J_Default")) { instance_I_J_Default.foo() }
|
||||||
|
expectFailure(fe("Default_J_I")) { instance_Default_J_I.foo() }
|
||||||
|
expectFailure(fe("I_J_RemovedDefault")) { instance_I_J_RemovedDefault.foo() }
|
||||||
|
expectFailure(fe("RemovedDefault_J_I")) { instance_RemovedDefault_J_I.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_Default.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_Default_I.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_RemovedDefault.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_I.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_J_Default.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_Default_J_I.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_J_RemovedDefault.foo() }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_J_I.foo() }
|
||||||
|
expectFailure(fe("AbstractUnrelated_I_Default")) { instance_AbstractUnrelated_I_Default.foo() }
|
||||||
|
expectFailure(fe("AbstractUnrelated_Default_I")) { instance_AbstractUnrelated_Default_I.foo() }
|
||||||
|
expectSuccess("I v2") { instance_AbstractUnrelated_I_RemovedDefault.foo() }
|
||||||
|
expectSuccess("I v2") { instance_AbstractUnrelated_RemovedDefault_I.foo() }
|
||||||
|
expectFailure(fe("AbstractUnrelated_I_J_Default")) { instance_AbstractUnrelated_I_J_Default.foo() }
|
||||||
|
expectFailure(fe("AbstractUnrelated_Default_J_I")) { instance_AbstractUnrelated_Default_J_I.foo() }
|
||||||
|
expectFailure(fe("AbstractUnrelated_I_J_RemovedDefault")) { instance_AbstractUnrelated_I_J_RemovedDefault.foo() }
|
||||||
|
expectFailure(fe("AbstractUnrelated_RemovedDefault_J_I")) { instance_AbstractUnrelated_RemovedDefault_J_I.foo() }
|
||||||
|
expectFailure(fe("WithFakeOverride_I_Default")) { instance_WithFakeOverride_I_Default.foo() }
|
||||||
|
expectFailure(fe("WithFakeOverride_Default_I")) { instance_WithFakeOverride_Default_I.foo() }
|
||||||
|
expectSuccess("I v2") { instance_WithFakeOverride_I_RemovedDefault.foo() }
|
||||||
|
expectSuccess("I v2") { instance_WithFakeOverride_RemovedDefault_I.foo() }
|
||||||
|
expectFailure(fe("WithFakeOverride_I_J_Default")) { instance_WithFakeOverride_I_J_Default.foo() }
|
||||||
|
expectFailure(fe("WithFakeOverride_Default_J_I")) { instance_WithFakeOverride_Default_J_I.foo() }
|
||||||
|
expectFailure(fe("WithFakeOverride_I_J_RemovedDefault")) { instance_WithFakeOverride_I_J_RemovedDefault.foo() }
|
||||||
|
expectFailure(fe("WithFakeOverride_RemovedDefault_J_I")) { instance_WithFakeOverride_RemovedDefault_J_I.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_Default.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_I.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_RemovedDefault.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_I.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_Default.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_J_I.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_RemovedDefault.foo() }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_J_I.foo() }
|
||||||
|
|
||||||
|
expectFailure(pe("I_Default")) { instance_I_Default.bar }
|
||||||
|
expectFailure(pe("Default_I")) { instance_Default_I.bar }
|
||||||
|
expectSuccess("I v2") { instance_I_RemovedDefault.bar }
|
||||||
|
expectSuccess("I v2") { instance_RemovedDefault_I.bar }
|
||||||
|
expectFailure(pe("I_J_Default")) { instance_I_J_Default.bar }
|
||||||
|
expectFailure(pe("Default_J_I")) { instance_Default_J_I.bar }
|
||||||
|
expectFailure(pe("I_J_RemovedDefault")) { instance_I_J_RemovedDefault.bar }
|
||||||
|
expectFailure(pe("RemovedDefault_J_I")) { instance_RemovedDefault_J_I.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_Default.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_Default_I.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_RemovedDefault.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_I.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_J_Default.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_Default_J_I.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_I_J_RemovedDefault.bar }
|
||||||
|
expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_J_I.bar }
|
||||||
|
expectFailure(pe("AbstractUnrelated_I_Default")) { instance_AbstractUnrelated_I_Default.bar }
|
||||||
|
expectFailure(pe("AbstractUnrelated_Default_I")) { instance_AbstractUnrelated_Default_I.bar }
|
||||||
|
expectSuccess("I v2") { instance_AbstractUnrelated_I_RemovedDefault.bar }
|
||||||
|
expectSuccess("I v2") { instance_AbstractUnrelated_RemovedDefault_I.bar }
|
||||||
|
expectFailure(pe("AbstractUnrelated_I_J_Default")) { instance_AbstractUnrelated_I_J_Default.bar }
|
||||||
|
expectFailure(pe("AbstractUnrelated_Default_J_I")) { instance_AbstractUnrelated_Default_J_I.bar }
|
||||||
|
expectFailure(pe("AbstractUnrelated_I_J_RemovedDefault")) { instance_AbstractUnrelated_I_J_RemovedDefault.bar }
|
||||||
|
expectFailure(pe("AbstractUnrelated_RemovedDefault_J_I")) { instance_AbstractUnrelated_RemovedDefault_J_I.bar }
|
||||||
|
expectFailure(pe("WithFakeOverride_I_Default")) { instance_WithFakeOverride_I_Default.bar }
|
||||||
|
expectFailure(pe("WithFakeOverride_Default_I")) { instance_WithFakeOverride_Default_I.bar }
|
||||||
|
expectSuccess("I v2") { instance_WithFakeOverride_I_RemovedDefault.bar }
|
||||||
|
expectSuccess("I v2") { instance_WithFakeOverride_RemovedDefault_I.bar }
|
||||||
|
expectFailure(pe("WithFakeOverride_I_J_Default")) { instance_WithFakeOverride_I_J_Default.bar }
|
||||||
|
expectFailure(pe("WithFakeOverride_Default_J_I")) { instance_WithFakeOverride_Default_J_I.bar }
|
||||||
|
expectFailure(pe("WithFakeOverride_I_J_RemovedDefault")) { instance_WithFakeOverride_I_J_RemovedDefault.bar }
|
||||||
|
expectFailure(pe("WithFakeOverride_RemovedDefault_J_I")) { instance_WithFakeOverride_RemovedDefault_J_I.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_Default.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_I.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_RemovedDefault.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_I.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_Default.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_J_I.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_RemovedDefault.bar }
|
||||||
|
expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_J_I.bar }
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
STEP 0:
|
||||||
|
dependencies: stdlib, lib1, lib2
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
MODULES: lib1, lib2, main
|
||||||
|
|
||||||
|
STEP 0:
|
||||||
|
libs: lib1, lib2, main
|
||||||
|
|
||||||
|
STEP 1:
|
||||||
|
libs: lib1
|
||||||
Generated
+6
@@ -145,6 +145,12 @@ public class FirJsPartialLinkageNoICTestCaseGenerated extends AbstractFirJsParti
|
|||||||
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("severalInheritedImplementations")
|
||||||
|
public void testSeveralInheritedImplementations() throws Exception {
|
||||||
|
runTest("compiler/testData/klibABI/severalInheritedImplementations/");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasChanges")
|
@TestMetadata("typeAliasChanges")
|
||||||
public void testTypeAliasChanges() throws Exception {
|
public void testTypeAliasChanges() throws Exception {
|
||||||
|
|||||||
Generated
+6
@@ -145,6 +145,12 @@ public class JsPartialLinkageNoICES6TestCaseGenerated extends AbstractJsPartialL
|
|||||||
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("severalInheritedImplementations")
|
||||||
|
public void testSeveralInheritedImplementations() throws Exception {
|
||||||
|
runTest("compiler/testData/klibABI/severalInheritedImplementations/");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasChanges")
|
@TestMetadata("typeAliasChanges")
|
||||||
public void testTypeAliasChanges() throws Exception {
|
public void testTypeAliasChanges() throws Exception {
|
||||||
|
|||||||
Generated
+6
@@ -145,6 +145,12 @@ public class JsPartialLinkageNoICTestCaseGenerated extends AbstractJsPartialLink
|
|||||||
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("severalInheritedImplementations")
|
||||||
|
public void testSeveralInheritedImplementations() throws Exception {
|
||||||
|
runTest("compiler/testData/klibABI/severalInheritedImplementations/");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasChanges")
|
@TestMetadata("typeAliasChanges")
|
||||||
public void testTypeAliasChanges() throws Exception {
|
public void testTypeAliasChanges() throws Exception {
|
||||||
|
|||||||
Generated
+6
@@ -145,6 +145,12 @@ public class JsPartialLinkageWithICTestCaseGenerated extends AbstractJsPartialLi
|
|||||||
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("severalInheritedImplementations")
|
||||||
|
public void testSeveralInheritedImplementations() throws Exception {
|
||||||
|
runTest("compiler/testData/klibABI/severalInheritedImplementations/");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasChanges")
|
@TestMetadata("typeAliasChanges")
|
||||||
public void testTypeAliasChanges() throws Exception {
|
public void testTypeAliasChanges() throws Exception {
|
||||||
|
|||||||
+6
@@ -148,6 +148,12 @@ public class FirNativePartialLinkageTestGenerated extends AbstractNativePartialL
|
|||||||
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("severalInheritedImplementations")
|
||||||
|
public void testSeveralInheritedImplementations() throws Exception {
|
||||||
|
runTest("compiler/testData/klibABI/severalInheritedImplementations/");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasChanges")
|
@TestMetadata("typeAliasChanges")
|
||||||
public void testTypeAliasChanges() throws Exception {
|
public void testTypeAliasChanges() throws Exception {
|
||||||
|
|||||||
+6
@@ -144,6 +144,12 @@ public class NativePartialLinkageTestGenerated extends AbstractNativePartialLink
|
|||||||
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
runTest("compiler/testData/klibABI/replaceCallableReturnType/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("severalInheritedImplementations")
|
||||||
|
public void testSeveralInheritedImplementations() throws Exception {
|
||||||
|
runTest("compiler/testData/klibABI/severalInheritedImplementations/");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasChanges")
|
@TestMetadata("typeAliasChanges")
|
||||||
public void testTypeAliasChanges() throws Exception {
|
public void testTypeAliasChanges() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user