KT-6014 Wrong ABSTRACT_MEMBER_NOT_IMPLEMENTED for toString implemented by delegation
Members declared in interface or overriding members declared in super-interfaces can be implemented by delegation even if they override members declared in super-class (NB for interface this can be only 'kotlin.Any').
This commit is contained in:
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
|
||||
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
|
||||
@@ -91,20 +90,17 @@ class DelegationResolver<T : CallableMemberDescriptor> private constructor(
|
||||
}
|
||||
|
||||
|
||||
private fun getDelegatableMembers(interfaceType: KotlinType): Collection<T> {
|
||||
val classSupertypeMembers =
|
||||
TypeUtils.getAllSupertypes(interfaceType).firstOrNull {
|
||||
val typeConstructor = it.constructor.declarationDescriptor
|
||||
typeConstructor is ClassDescriptor && typeConstructor.kind != ClassKind.INTERFACE
|
||||
}?.let {
|
||||
memberExtractor.getMembersByType(it)
|
||||
} ?: emptyList<CallableMemberDescriptor>()
|
||||
return memberExtractor.getMembersByType(interfaceType).filter { descriptor ->
|
||||
descriptor.isOverridable &&
|
||||
!classSupertypeMembers.any { isOverridableBy(it, descriptor) } &&
|
||||
delegationFilter.filter(descriptor, languageVersionSettings)
|
||||
}
|
||||
}
|
||||
private fun getDelegatableMembers(interfaceType: KotlinType): Collection<T> =
|
||||
memberExtractor.getMembersByType(interfaceType).filter { descriptor ->
|
||||
descriptor.isOverridable &&
|
||||
(descriptor.kind.isReal || !descriptor.overridesClassMembersOnly()) &&
|
||||
delegationFilter.filter(descriptor, languageVersionSettings)
|
||||
}
|
||||
|
||||
private fun T.overridesClassMembersOnly() =
|
||||
DescriptorUtils.getAllOverriddenDeclarations(this).all {
|
||||
DescriptorUtils.isClass(it.containingDeclaration)
|
||||
}
|
||||
|
||||
interface MemberExtractor<out T : CallableMemberDescriptor> {
|
||||
fun getMembersByType(type: KotlinType): Collection<T>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
interface IBase {
|
||||
override fun toString(): String
|
||||
}
|
||||
|
||||
interface IDerived : IBase
|
||||
|
||||
object BaseImpl : IBase {
|
||||
override fun toString(): String = "A"
|
||||
}
|
||||
|
||||
object DerivedImpl : IDerived {
|
||||
override fun toString(): String = "A"
|
||||
}
|
||||
|
||||
class Test1 : IBase by BaseImpl
|
||||
|
||||
class Test2 : IDerived by DerivedImpl
|
||||
@@ -0,0 +1,41 @@
|
||||
package
|
||||
|
||||
public object BaseImpl : IBase {
|
||||
private constructor BaseImpl()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public object DerivedImpl : IDerived {
|
||||
private constructor DerivedImpl()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface IBase {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public abstract override /*1*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface IDerived : IBase {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public abstract override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Test1 : IBase {
|
||||
public constructor Test1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*delegation*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Test2 : IDerived {
|
||||
public constructor Test2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*delegation*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -14332,6 +14332,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6014.kt")
|
||||
public void testKt6014() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/kt6014.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt880.kt")
|
||||
public void testKt880() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/kt880.kt");
|
||||
|
||||
Reference in New Issue
Block a user