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.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
|
||||||
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
|
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
|
||||||
import org.jetbrains.kotlin.types.isDynamic
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||||
|
|
||||||
@@ -91,20 +90,17 @@ class DelegationResolver<T : CallableMemberDescriptor> private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getDelegatableMembers(interfaceType: KotlinType): Collection<T> {
|
private fun getDelegatableMembers(interfaceType: KotlinType): Collection<T> =
|
||||||
val classSupertypeMembers =
|
memberExtractor.getMembersByType(interfaceType).filter { descriptor ->
|
||||||
TypeUtils.getAllSupertypes(interfaceType).firstOrNull {
|
descriptor.isOverridable &&
|
||||||
val typeConstructor = it.constructor.declarationDescriptor
|
(descriptor.kind.isReal || !descriptor.overridesClassMembersOnly()) &&
|
||||||
typeConstructor is ClassDescriptor && typeConstructor.kind != ClassKind.INTERFACE
|
delegationFilter.filter(descriptor, languageVersionSettings)
|
||||||
}?.let {
|
}
|
||||||
memberExtractor.getMembersByType(it)
|
|
||||||
} ?: emptyList<CallableMemberDescriptor>()
|
private fun T.overridesClassMembersOnly() =
|
||||||
return memberExtractor.getMembersByType(interfaceType).filter { descriptor ->
|
DescriptorUtils.getAllOverriddenDeclarations(this).all {
|
||||||
descriptor.isOverridable &&
|
DescriptorUtils.isClass(it.containingDeclaration)
|
||||||
!classSupertypeMembers.any { isOverridableBy(it, descriptor) } &&
|
}
|
||||||
delegationFilter.filter(descriptor, languageVersionSettings)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MemberExtractor<out T : CallableMemberDescriptor> {
|
interface MemberExtractor<out T : CallableMemberDescriptor> {
|
||||||
fun getMembersByType(type: KotlinType): Collection<T>
|
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);
|
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")
|
@TestMetadata("kt880.kt")
|
||||||
public void testKt880() throws Exception {
|
public void testKt880() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/kt880.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/kt880.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user