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:
Dmitry Petrov
2017-03-07 18:02:46 +03:00
parent 5e8afd26e1
commit d188de3086
4 changed files with 75 additions and 15 deletions
@@ -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>
+17
View File
@@ -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
+41
View File
@@ -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");