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.resolve.DescriptorUtils.classCanHaveAbstractMembers
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
class OverrideResolver(
private val trace: BindingTrace,
@@ -74,10 +75,10 @@ class OverrideResolver(
private interface CheckInheritedSignaturesReportStrategy {
fun abstractMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun abstractBaseClassMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor)
fun multipleImplementationsMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun conflictingInterfaceMemberNotImplemented(descriptor: CallableMemberDescriptor)
fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor)
fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor)
fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor)
}
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
}
override fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor) {
// don't care
override fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor) {
shouldImplement.add(abstractMember)
}
}
@@ -115,11 +116,11 @@ class OverrideResolver(
private val classDescriptor: ClassDescriptor
) : CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy {
private val abstractNoImpl = Sets.newLinkedHashSet<CallableMemberDescriptor>()
private val multipleImplementations = Sets.newLinkedHashSet<CallableMemberDescriptor>()
private val abstractInBaseClassNoImpl = Sets.newLinkedHashSet<CallableMemberDescriptor>()
private val conflictingInterfaceMembers = Sets.newLinkedHashSet<CallableMemberDescriptor>()
private val conflictingReturnTypes = Sets.newHashSet<CallableMemberDescriptor>()
private val abstractNoImpl = linkedSetOf<CallableMemberDescriptor>()
private val abstractInBaseClassNoImpl = linkedSetOf<CallableMemberDescriptor>()
private val multipleImplementations = linkedSetOf<CallableMemberDescriptor>()
private val conflictingInterfaceMembers = linkedSetOf<CallableMemberDescriptor>()
private val conflictingReturnTypes = linkedSetOf<CallableMemberDescriptor>()
private val onceErrorsReported = SmartHashSet<DiagnosticFactoryWithPsiElement<*, *>>()
@@ -139,25 +140,27 @@ class OverrideResolver(
conflictingInterfaceMembers.add(descriptor)
}
override fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) {
override fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) {
conflictingReturnTypes.add(descriptor1)
conflictingReturnTypes.add(descriptor2)
reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2)
}
override fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor) {
conflictingReturnTypes.add(descriptor1)
conflictingReturnTypes.add(descriptor2)
if (descriptor1.isVar || descriptor2.isVar) {
reportInheritanceConflictIfRequired(VAR_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)
}
else {
reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2)
}
}
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(
diagnosticFactory: DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor>,
descriptor1: CallableMemberDescriptor,
@@ -208,13 +211,12 @@ class OverrideResolver(
}
internal fun doReportErrors() {
if (!classCanHaveAbstractMembers(classDescriptor)) {
if (!abstractInBaseClassNoImpl.isEmpty()) {
trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.iterator().next()))
}
else if (!abstractNoImpl.isEmpty()) {
trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()))
}
val canHaveAbstractMembers = classCanHaveAbstractMembers(classDescriptor)
if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first()))
}
else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.first()))
}
conflictingInterfaceMembers.removeAll(conflictingReturnTypes)
@@ -386,7 +388,7 @@ class OverrideResolver(
}
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()) {
trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter))
@@ -530,7 +532,7 @@ class OverrideResolver(
val relevantDirectlyOverridden = getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations)
checkInheritedDescriptorsGroup(relevantDirectlyOverridden, descriptor, reportingStrategy)
checkInheritedDescriptorsGroup(descriptor, relevantDirectlyOverridden, reportingStrategy)
if (kind == DELEGATION && overrideReportStrategyForDelegates != null) {
checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates)
@@ -540,36 +542,30 @@ class OverrideResolver(
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
if (numImplementations == 1 && isReturnTypeOkForOverride(descriptor, implementations[0])) return
val abstractOverridden = ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size)
val concreteOverridden = ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size)
filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden)
if (numImplementations == 0) {
if (kind != DELEGATION) {
for (member in abstractOverridden) {
reportingStrategy.abstractMemberNotImplemented(member)
when (numImplementations) {
0 ->
if (kind != DELEGATION) {
abstractOverridden.forEach {
reportingStrategy.abstractMemberNotImplemented(it)
}
}
}
}
else if (numImplementations > 1) {
for (member in concreteOverridden) {
reportingStrategy.multipleImplementationsMemberNotImplemented(member)
}
}
else {
if (kind != DELEGATION) {
val membersWithMoreSpecificReturnType = collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations[0])
for (member in membersWithMoreSpecificReturnType) {
reportingStrategy.abstractMemberNotImplemented(member)
1 ->
if (kind != DELEGATION) {
val implementation = concreteOverridden.first()
collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementation).forEach {
reportingStrategy.abstractMemberWithMoreSpecificType(it, implementation)
}
}
else ->
concreteOverridden.forEach {
reportingStrategy.multipleImplementationsMemberNotImplemented(it)
}
}
}
}
@@ -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(
abstractOverridden: List<CallableMemberDescriptor>,
implementation: CallableMemberDescriptor
@@ -742,24 +686,24 @@ class OverrideResolver(
}
private fun checkInheritedDescriptorsGroup(
inheritedDescriptors: Collection<CallableMemberDescriptor>,
mostSpecific: CallableMemberDescriptor,
descriptor: CallableMemberDescriptor,
overriddenDescriptors: Collection<CallableMemberDescriptor>,
reportingStrategy: CheckInheritedSignaturesReportStrategy
) {
if (inheritedDescriptors.size > 1) {
val mostSpecificProperty = if (mostSpecific is PropertyDescriptor) mostSpecific else null
if (overriddenDescriptors.size <= 1) return
for (inheritedDescriptor in inheritedDescriptors) {
if (mostSpecificProperty != null) {
assert(inheritedDescriptor is PropertyDescriptor) { inheritedDescriptor.toString() + " inherited from " + mostSpecificProperty + " is not a property" }
val inheritedPropertyDescriptor = inheritedDescriptor as PropertyDescriptor
val propertyDescriptor = descriptor as? PropertyDescriptor
if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) {
reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificProperty, inheritedPropertyDescriptor)
}
for (overriddenDescriptor in overriddenDescriptors) {
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()) {
val containingDeclaration = declared.containingDeclaration
assert(containingDeclaration is ClassDescriptor) { "Overrides may only be resolved in a class, but $declared comes from $containingDeclaration" }
val declaringClass = containingDeclaration as ClassDescriptor
val declaringClass = containingDeclaration.assertedCast<ClassDescriptor> {
"Overrides may only be resolved in a class, but $declared comes from $containingDeclaration"
}
val invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass)
if (invisibleOverriddenDescriptor != null) {
@@ -796,15 +741,14 @@ class OverrideResolver(
val propertyMemberDescriptor = if (memberDescriptor is PropertyDescriptor) memberDescriptor else null
for (overridden in overriddenDescriptors) {
// if (overridden == null) continue
if (!overridden.isOverridable) {
reportError.overridingFinalMember(memberDescriptor, overridden)
}
if (propertyMemberDescriptor != null) {
assert(overridden is PropertyDescriptor) { overridden.toString() + " is overridden by property " + propertyMemberDescriptor }
val overriddenProperty = overridden as PropertyDescriptor
val overriddenProperty = overridden.assertedCast<PropertyDescriptor> {
"$overridden is overridden by property $propertyMemberDescriptor"
}
if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) {
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"
}
<!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);
}
@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")
public void testKt9550() throws Exception {
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?.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 {
val cached = constantMap[calculator]