An overridden abstract member with a more specific "return type" than an overridden concrete member
should be explicitly overridden even if the class in question can have abstract members.
This commit is contained in:
Dmitry Petrov
2017-01-18 17:39:09 +03:00
parent f89de02ff0
commit b36e3bc083
8 changed files with 291 additions and 129 deletions
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERR
import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
class OverrideResolver( class OverrideResolver(
private val trace: BindingTrace, private val trace: BindingTrace,
@@ -74,10 +75,10 @@ class OverrideResolver(
private interface CheckInheritedSignaturesReportStrategy { private interface CheckInheritedSignaturesReportStrategy {
fun abstractMemberNotImplemented(descriptor: CallableMemberDescriptor) fun abstractMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun abstractBaseClassMemberNotImplemented(descriptor: CallableMemberDescriptor) fun abstractBaseClassMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor)
fun multipleImplementationsMemberNotImplemented(descriptor: CallableMemberDescriptor) fun multipleImplementationsMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun conflictingInterfaceMemberNotImplemented(descriptor: CallableMemberDescriptor) fun conflictingInterfaceMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor)
fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor)
} }
private class CollectMissingImplementationsStrategy : CheckInheritedSignaturesReportStrategy { private class CollectMissingImplementationsStrategy : CheckInheritedSignaturesReportStrategy {
@@ -101,12 +102,12 @@ class OverrideResolver(
} }
} }
override fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) { override fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) {
// don't care // don't care
} }
override fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor) { override fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor) {
// don't care shouldImplement.add(abstractMember)
} }
} }
@@ -115,11 +116,11 @@ class OverrideResolver(
private val classDescriptor: ClassDescriptor private val classDescriptor: ClassDescriptor
) : CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy { ) : CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy {
private val abstractNoImpl = Sets.newLinkedHashSet<CallableMemberDescriptor>() private val abstractNoImpl = linkedSetOf<CallableMemberDescriptor>()
private val multipleImplementations = Sets.newLinkedHashSet<CallableMemberDescriptor>() private val abstractInBaseClassNoImpl = linkedSetOf<CallableMemberDescriptor>()
private val abstractInBaseClassNoImpl = Sets.newLinkedHashSet<CallableMemberDescriptor>() private val multipleImplementations = linkedSetOf<CallableMemberDescriptor>()
private val conflictingInterfaceMembers = Sets.newLinkedHashSet<CallableMemberDescriptor>() private val conflictingInterfaceMembers = linkedSetOf<CallableMemberDescriptor>()
private val conflictingReturnTypes = Sets.newHashSet<CallableMemberDescriptor>() private val conflictingReturnTypes = linkedSetOf<CallableMemberDescriptor>()
private val onceErrorsReported = SmartHashSet<DiagnosticFactoryWithPsiElement<*, *>>() private val onceErrorsReported = SmartHashSet<DiagnosticFactoryWithPsiElement<*, *>>()
@@ -139,25 +140,27 @@ class OverrideResolver(
conflictingInterfaceMembers.add(descriptor) conflictingInterfaceMembers.add(descriptor)
} }
override fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) { override fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) {
conflictingReturnTypes.add(descriptor1) conflictingReturnTypes.add(descriptor1)
conflictingReturnTypes.add(descriptor2) conflictingReturnTypes.add(descriptor2)
reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) if (descriptor1 is PropertyDescriptor && descriptor2 is PropertyDescriptor) {
} if (descriptor1.isVar || descriptor2.isVar) {
reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2)
override fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor) { }
conflictingReturnTypes.add(descriptor1) else {
conflictingReturnTypes.add(descriptor2) reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2)
}
if (descriptor1.isVar || descriptor2.isVar) {
reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2)
} }
else { else {
reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2)
} }
} }
override fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor) {
typeMismatchOnInheritance(abstractMember, concreteMember)
}
private fun reportInheritanceConflictIfRequired( private fun reportInheritanceConflictIfRequired(
diagnosticFactory: DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor>, diagnosticFactory: DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor>,
descriptor1: CallableMemberDescriptor, descriptor1: CallableMemberDescriptor,
@@ -208,13 +211,12 @@ class OverrideResolver(
} }
internal fun doReportErrors() { internal fun doReportErrors() {
if (!classCanHaveAbstractMembers(classDescriptor)) { val canHaveAbstractMembers = classCanHaveAbstractMembers(classDescriptor)
if (!abstractInBaseClassNoImpl.isEmpty()) { if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.iterator().next())) trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first()))
} }
else if (!abstractNoImpl.isEmpty()) { else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next())) trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.first()))
}
} }
conflictingInterfaceMembers.removeAll(conflictingReturnTypes) conflictingInterfaceMembers.removeAll(conflictingReturnTypes)
@@ -386,7 +388,7 @@ class OverrideResolver(
} }
private fun checkNameAndDefaultForDeclaredParameter(descriptor: ValueParameterDescriptor, multipleDefaultsInSuper: Boolean) { private fun checkNameAndDefaultForDeclaredParameter(descriptor: ValueParameterDescriptor, multipleDefaultsInSuper: Boolean) {
val parameter = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as KtParameter? ?: error("Declaration not found for parameter: " + descriptor) val parameter = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as? KtParameter ?: error("Declaration not found for parameter: " + descriptor)
if (descriptor.declaresDefaultValue()) { if (descriptor.declaresDefaultValue()) {
trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter)) trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter))
@@ -530,7 +532,7 @@ class OverrideResolver(
val relevantDirectlyOverridden = getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations) val relevantDirectlyOverridden = getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations)
checkInheritedDescriptorsGroup(relevantDirectlyOverridden, descriptor, reportingStrategy) checkInheritedDescriptorsGroup(descriptor, relevantDirectlyOverridden, reportingStrategy)
if (kind == DELEGATION && overrideReportStrategyForDelegates != null) { if (kind == DELEGATION && overrideReportStrategyForDelegates != null) {
checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates) checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates)
@@ -540,36 +542,30 @@ class OverrideResolver(
checkMissingOverridesByJava8Restrictions(relevantDirectlyOverridden, reportingStrategy) checkMissingOverridesByJava8Restrictions(relevantDirectlyOverridden, reportingStrategy)
} }
val implementations = collectImplementations(relevantDirectlyOverridden) val (concreteOverridden, abstractOverridden) = relevantDirectlyOverridden
.filter { !isOrOverridesSynthesized(it) }
.partition { it.modality != Modality.ABSTRACT }
val numImplementations = implementations.size val numImplementations = concreteOverridden.size
// The most common case: there's one implementation in the supertypes with the matching return type when (numImplementations) {
if (numImplementations == 1 && isReturnTypeOkForOverride(descriptor, implementations[0])) return 0 ->
if (kind != DELEGATION) {
val abstractOverridden = ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size) abstractOverridden.forEach {
val concreteOverridden = ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size) reportingStrategy.abstractMemberNotImplemented(it)
filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden) }
if (numImplementations == 0) {
if (kind != DELEGATION) {
for (member in abstractOverridden) {
reportingStrategy.abstractMemberNotImplemented(member)
} }
} 1 ->
} if (kind != DELEGATION) {
else if (numImplementations > 1) { val implementation = concreteOverridden.first()
for (member in concreteOverridden) { collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementation).forEach {
reportingStrategy.multipleImplementationsMemberNotImplemented(member) reportingStrategy.abstractMemberWithMoreSpecificType(it, implementation)
} }
} }
else { else ->
if (kind != DELEGATION) { concreteOverridden.forEach {
val membersWithMoreSpecificReturnType = collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations[0]) reportingStrategy.multipleImplementationsMemberNotImplemented(it)
for (member in membersWithMoreSpecificReturnType) {
reportingStrategy.abstractMemberNotImplemented(member)
} }
}
} }
} }
@@ -615,58 +611,6 @@ class OverrideResolver(
} }
} }
private fun collectImplementations(relevantDirectlyOverridden: Set<CallableMemberDescriptor>): List<CallableMemberDescriptor> {
val result = ArrayList<CallableMemberDescriptor>(relevantDirectlyOverridden.size)
for (overriddenDescriptor in relevantDirectlyOverridden) {
if (isImplementation(overriddenDescriptor)) {
result.add(overriddenDescriptor)
}
}
return result
}
private fun isImplementation(callableMemberDescriptor: CallableMemberDescriptor): Boolean {
// An abstract member is not an implementation.
if (callableMemberDescriptor.modality === Modality.ABSTRACT) return false
// Interfaces contain fake overrides for 'toString', 'hashCode', 'equals'.
// They are not considered implementations if their dispatch receiver type is 'Any'.
val containingDeclaration = callableMemberDescriptor.containingDeclaration
assert(containingDeclaration is ClassDescriptor) { "ClassDescriptor expected, got $containingDeclaration for $callableMemberDescriptor" }
val containingClassDescriptor = containingDeclaration as ClassDescriptor
if (containingClassDescriptor.kind == ClassKind.INTERFACE && callableMemberDescriptor.kind == FAKE_OVERRIDE) {
val dispatchReceiverParameter = callableMemberDescriptor.dispatchReceiverParameter ?: return false
if (KotlinBuiltIns.isAny(dispatchReceiverParameter.type)) return false
}
// A FAKE_OVERRIDE is an implementation iff it overrides an implementation.
if (callableMemberDescriptor.kind == FAKE_OVERRIDE) {
for (overriddenDescriptor in callableMemberDescriptor.overriddenDescriptors) {
if (isImplementation(overriddenDescriptor)) return true
}
return false
}
return true
}
private fun filterNotSynthesizedDescriptorsByModality(
allOverriddenDeclarations: Set<CallableMemberDescriptor>,
abstractOverridden: MutableList<CallableMemberDescriptor>,
concreteOverridden: MutableList<CallableMemberDescriptor>
) {
for (overridden in allOverriddenDeclarations) {
if (!isOrOverridesSynthesized(overridden)) {
if (overridden.modality === Modality.ABSTRACT) {
abstractOverridden.add(overridden)
}
else {
concreteOverridden.add(overridden)
}
}
}
}
private fun collectAbstractMethodsWithMoreSpecificReturnType( private fun collectAbstractMethodsWithMoreSpecificReturnType(
abstractOverridden: List<CallableMemberDescriptor>, abstractOverridden: List<CallableMemberDescriptor>,
implementation: CallableMemberDescriptor implementation: CallableMemberDescriptor
@@ -742,24 +686,24 @@ class OverrideResolver(
} }
private fun checkInheritedDescriptorsGroup( private fun checkInheritedDescriptorsGroup(
inheritedDescriptors: Collection<CallableMemberDescriptor>, descriptor: CallableMemberDescriptor,
mostSpecific: CallableMemberDescriptor, overriddenDescriptors: Collection<CallableMemberDescriptor>,
reportingStrategy: CheckInheritedSignaturesReportStrategy reportingStrategy: CheckInheritedSignaturesReportStrategy
) { ) {
if (inheritedDescriptors.size > 1) { if (overriddenDescriptors.size <= 1) return
val mostSpecificProperty = if (mostSpecific is PropertyDescriptor) mostSpecific else null
for (inheritedDescriptor in inheritedDescriptors) { val propertyDescriptor = descriptor as? PropertyDescriptor
if (mostSpecificProperty != null) {
assert(inheritedDescriptor is PropertyDescriptor) { inheritedDescriptor.toString() + " inherited from " + mostSpecificProperty + " is not a property" }
val inheritedPropertyDescriptor = inheritedDescriptor as PropertyDescriptor
if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) { for (overriddenDescriptor in overriddenDescriptors) {
reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificProperty, inheritedPropertyDescriptor) if (propertyDescriptor != null) {
} val overriddenPropertyDescriptor = overriddenDescriptor.assertedCast<PropertyDescriptor> { "$overriddenDescriptor is not a property" }
if (!isPropertyTypeOkForOverride(overriddenPropertyDescriptor, propertyDescriptor)) {
reportingStrategy.typeMismatchOnInheritance(propertyDescriptor, overriddenPropertyDescriptor)
} }
else if (!isReturnTypeOkForOverride(inheritedDescriptor, mostSpecific)) { }
reportingStrategy.returnTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor) else {
if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor)) {
reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor)
} }
} }
} }
@@ -775,8 +719,9 @@ class OverrideResolver(
if (overriddenDescriptors.isEmpty()) { if (overriddenDescriptors.isEmpty()) {
val containingDeclaration = declared.containingDeclaration val containingDeclaration = declared.containingDeclaration
assert(containingDeclaration is ClassDescriptor) { "Overrides may only be resolved in a class, but $declared comes from $containingDeclaration" } val declaringClass = containingDeclaration.assertedCast<ClassDescriptor> {
val declaringClass = containingDeclaration as ClassDescriptor "Overrides may only be resolved in a class, but $declared comes from $containingDeclaration"
}
val invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass) val invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass)
if (invisibleOverriddenDescriptor != null) { if (invisibleOverriddenDescriptor != null) {
@@ -796,15 +741,14 @@ class OverrideResolver(
val propertyMemberDescriptor = if (memberDescriptor is PropertyDescriptor) memberDescriptor else null val propertyMemberDescriptor = if (memberDescriptor is PropertyDescriptor) memberDescriptor else null
for (overridden in overriddenDescriptors) { for (overridden in overriddenDescriptors) {
// if (overridden == null) continue
if (!overridden.isOverridable) { if (!overridden.isOverridable) {
reportError.overridingFinalMember(memberDescriptor, overridden) reportError.overridingFinalMember(memberDescriptor, overridden)
} }
if (propertyMemberDescriptor != null) { if (propertyMemberDescriptor != null) {
assert(overridden is PropertyDescriptor) { overridden.toString() + " is overridden by property " + propertyMemberDescriptor } val overriddenProperty = overridden.assertedCast<PropertyDescriptor> {
val overriddenProperty = overridden as PropertyDescriptor "$overridden is overridden by property $propertyMemberDescriptor"
}
if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) { if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) {
reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty) reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty)
} }
@@ -0,0 +1,13 @@
interface IFooAny {
val foo: Any
}
interface IFooStr : IFooAny {
override val foo: String
}
abstract class BaseAny(override val foo: Any): IFooAny
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class BaseStr<!> : BaseAny(42), IFooStr
class C : BaseStr()
@@ -0,0 +1,39 @@
package
public abstract class BaseAny : IFooAny {
public constructor BaseAny(/*0*/ foo: kotlin.Any)
public open override /*1*/ val foo: kotlin.Any
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*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class BaseStr : BaseAny, IFooStr {
public constructor BaseStr()
public open override /*2*/ /*fake_override*/ val foo: kotlin.String
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class C : BaseStr {
public constructor C()
public open override /*1*/ /*fake_override*/ val foo: kotlin.String
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*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IFooAny {
public abstract val foo: kotlin.Any
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*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IFooStr : IFooAny {
public abstract override /*1*/ val foo: kotlin.String
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*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,47 @@
// FILE: K.kt
abstract class ATest1 : TestNN.JNullVsNotNull()
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class ATest2<!> : TestNN.JUnknownImpl(), TestNN.JNotNull
abstract class ATest3 : TestNN.JUnknownVsNotNull()
class CTest1 : TestNN.JNullVsNotNull()
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class CTest2<!> : TestNN.JUnknownImpl(), TestNN.JNotNull
class CTest3 : TestNN.JUnknownVsNotNull()
// FILE: TestNN.java
import org.jetbrains.annotations.*;
public class TestNN {
public interface JNull {
@Nullable Object foo();
}
public interface JNotNull {
@NotNull Object foo();
}
public static class JNullVsNotNull implements JNull, JNotNull {
public Object foo() {
return this;
}
}
public static class JNullBase {
@Nullable public Object foo() {
return null;
}
}
public static class JUnknownImpl extends JNullBase {
public Object foo() {
return this;
}
}
public static class JUnknownVsNotNull extends JUnknownImpl implements JNotNull {
}
}
@@ -0,0 +1,106 @@
package
public abstract class ATest1 : TestNN.JNullVsNotNull {
public constructor ATest1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class ATest2 : TestNN.JUnknownImpl, TestNN.JNotNull {
public constructor ATest2()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull public open override /*2*/ /*fake_override*/ fun foo(): kotlin.Any
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class ATest3 : TestNN.JUnknownVsNotNull {
public constructor ATest3()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class CTest1 : TestNN.JNullVsNotNull {
public constructor CTest1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class CTest2 : TestNN.JUnknownImpl, TestNN.JNotNull {
public constructor CTest2()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull public open override /*2*/ /*fake_override*/ fun foo(): kotlin.Any
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class CTest3 : TestNN.JUnknownVsNotNull {
public constructor CTest3()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class TestNN {
public constructor TestNN()
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*/ /*fake_override*/ fun toString(): kotlin.String
public interface JNotNull {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull public abstract fun foo(): kotlin.Any
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface JNull {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.Nullable public abstract fun foo(): kotlin.Any?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class JNullBase {
public constructor JNullBase()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.Nullable public open fun foo(): kotlin.Any?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class JNullVsNotNull : TestNN.JNull, TestNN.JNotNull {
public constructor JNullVsNotNull()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ fun foo(): kotlin.Any
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class JUnknownImpl : TestNN.JNullBase {
public constructor JUnknownImpl()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun foo(): kotlin.Any?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class JUnknownVsNotNull : TestNN.JUnknownImpl, TestNN.JNotNull {
public constructor JUnknownVsNotNull()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull public open override /*2*/ /*fake_override*/ fun foo(): kotlin.Any
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
// Static members
public final /*synthesized*/ fun JNotNull(/*0*/ function: () -> kotlin.Any): TestNN.JNotNull
public final /*synthesized*/ fun JNull(/*0*/ function: () -> kotlin.Any?): TestNN.JNull
}
+2 -2
View File
@@ -6,6 +6,6 @@ open class B {
open fun f(): CharSequence = "charSequence" open fun f(): CharSequence = "charSequence"
} }
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C<!> : B(), A <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class C<!> : B(), A
val d: A = <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>object<!> : B(), A {} val d: A = <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>object<!> : B(), A {}
@@ -14613,6 +14613,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt13355.kt")
public void testKt13355() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt");
doTest(fileName);
}
@TestMetadata("kt13355viaJava.kt")
public void testKt13355viaJava() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt");
doTest(fileName);
}
@TestMetadata("kt9550.kt") @TestMetadata("kt9550.kt")
public void testKt9550() throws Exception { public void testKt9550() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt");
@@ -80,6 +80,7 @@ fun <T: Any> T.check(predicate: (T) -> Boolean): T? = if (predicate(this)) this
inline fun <reified T : Any> Any?.safeAs(): T? = this as? T inline fun <reified T : Any> Any?.safeAs(): T? = this as? T
inline fun <reified T : Any> Any?.cast(): T = this as T inline fun <reified T : Any> Any?.cast(): T = this as T
inline fun <reified T : Any> Any?.assertedCast(message: () -> String): T = this as? T ?: throw AssertionError(message())
fun <T : Any> constant(calculator: () -> T): T { fun <T : Any> constant(calculator: () -> T): T {
val cached = constantMap[calculator] val cached = constantMap[calculator]