KT-1934 & KT-10197:

Naive approximation for fake overriding signature:
use upper bound for flexible types.
Check delegation errors.
This commit is contained in:
Dmitry Petrov
2015-12-04 17:18:00 +03:00
parent 6e2d42daf9
commit ef72c594c4
24 changed files with 1055 additions and 209 deletions
@@ -329,6 +329,15 @@ public interface Errors {
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> PROPERTY_TYPE_MISMATCH_ON_INHERITANCE =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> OVERRIDING_FINAL_MEMBER_BY_DELEGATION =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> PROPERTY_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, KtClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, KtClassOrObject, CallableMemberDescriptor> ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED =
@@ -563,6 +563,15 @@ public class DefaultErrorMessages {
MAP.put(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, "''{0}'' clashes with ''{1}'': property types are incompatible",
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(OVERRIDING_FINAL_MEMBER_BY_DELEGATION, "''{0}'' implicitly overrides a final member ''{1}'' by delegation",
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION, "Return type of ''{0}'' doesn't match ''{1}'' implicitly overridden by delegation",
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION, "Property type of ''{0}'' doesn't match ''{1}'' implicitly overridden by delegation",
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, "val-property ''{0}'' implicitly overrides a var-property ''{1}'' by delegation",
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(VAR_OVERRIDDEN_BY_VAL, "Var-property {0} cannot be overridden by val-property {1}", FQ_NAMES_IN_TYPES, FQ_NAMES_IN_TYPES);
MAP.put(ABSTRACT_MEMBER_NOT_IMPLEMENTED, "{0} must be declared abstract or implement abstract member {1}", RENDER_CLASS_OR_OBJECT,
@@ -25,6 +25,7 @@ import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.LinkedMultiMap;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.SmartHashSet;
import com.intellij.util.containers.hash.EqualityPolicy;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
@@ -32,6 +33,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryWithPsiElement;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
@@ -263,144 +266,229 @@ public class OverrideResolver {
checkOverrideForMember(member);
}
// Check if everything that must be overridden, actually is
// More than one implementation or no implementations at all
final Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
final Set<CallableMemberDescriptor> manyImpl = Sets.newLinkedHashSet();
final Set<CallableMemberDescriptor> abstractInBaseClassNoImpl = Sets.newLinkedHashSet();
final Set<CallableMemberDescriptor> conflictingInterfaceOverrides = Sets.newLinkedHashSet();
CollectErrorInformationForInheritedMembersStrategy inheritedMemberErrors =
new CollectErrorInformationForInheritedMembersStrategy(klass, classDescriptor);
checkInheritedSignatures(
classDescriptor,
new CheckInheritedSignaturesReportingStrategy() {
private boolean returnTypeMismatch = false;
private boolean propertyTypeMismatch = false;
@Override
public void abstractMemberNoImpl(CallableMemberDescriptor descriptor) {
abstractNoImpl.add(descriptor);
}
@Override
public void abstractBaseClassMemberNoImpl(CallableMemberDescriptor descriptor) {
abstractInBaseClassNoImpl.add(descriptor);
}
@Override
public void manyImplMemberNoImpl(CallableMemberDescriptor descriptor) {
manyImpl.add(descriptor);
}
@Override
public void conflictingMemberFromInterface(CallableMemberDescriptor descriptor) {
conflictingInterfaceOverrides.add(descriptor);
}
@Override
public void clashingWithReturnType(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
if (!returnTypeMismatch) {
returnTypeMismatch = true;
trace.report(RETURN_TYPE_MISMATCH_ON_INHERITANCE.on(klass, descriptor1, descriptor2));
}
}
@Override
public void clashingWithPropertyType(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
if (!propertyTypeMismatch) {
propertyTypeMismatch = true;
trace.report(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE.on(klass, descriptor1, descriptor2));
}
}
});
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()));
}
}
if (!conflictingInterfaceOverrides.isEmpty()) {
trace.report(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED.on(klass, klass, conflictingInterfaceOverrides.iterator().next()));
}
else if (!manyImpl.isEmpty()) {
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, manyImpl.iterator().next()));
}
checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors);
inheritedMemberErrors.doReportErrors();
}
@NotNull
public static Set<CallableMemberDescriptor> getMissingImplementations(@NotNull ClassDescriptor classDescriptor) {
CollectMissingImplementationsStrategy collector = new CollectMissingImplementationsStrategy();
checkInheritedSignatures(classDescriptor, collector);
checkInheritedAndDelegatedSignatures(classDescriptor, collector, null);
return collector.shouldImplement;
}
private interface CheckInheritedSignaturesReportingStrategy {
void abstractMemberNoImpl(CallableMemberDescriptor descriptor);
void abstractBaseClassMemberNoImpl(CallableMemberDescriptor descriptor);
void manyImplMemberNoImpl(CallableMemberDescriptor descriptor);
void conflictingMemberFromInterface(CallableMemberDescriptor descriptor);
void clashingWithReturnType(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
void clashingWithPropertyType(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
private interface CheckInheritedSignaturesReportStrategy {
void abstractMemberNotImplemented(CallableMemberDescriptor descriptor);
void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor);
void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor);
void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor);
void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
void propertyTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
}
private static class CollectMissingImplementationsStrategy implements CheckInheritedSignaturesReportingStrategy {
private static class CollectMissingImplementationsStrategy implements CheckInheritedSignaturesReportStrategy {
private Set<CallableMemberDescriptor> shouldImplement = new LinkedHashSet<CallableMemberDescriptor>();
@Override
public void abstractMemberNoImpl(CallableMemberDescriptor descriptor) {
public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
shouldImplement.add(descriptor);
}
@Override
public void abstractBaseClassMemberNoImpl(CallableMemberDescriptor descriptor) {
public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
// don't care
}
@Override
public void manyImplMemberNoImpl(CallableMemberDescriptor descriptor) {
public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
shouldImplement.add(descriptor);
}
@Override
public void conflictingMemberFromInterface(CallableMemberDescriptor descriptor) {
public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
// don't care
}
@Override
public void clashingWithReturnType(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
// don't care
}
@Override
public void clashingWithPropertyType(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
public void propertyTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
// don't care
}
}
private static void checkInheritedSignatures(
@NotNull ClassDescriptor classDescriptor,
@NotNull CheckInheritedSignaturesReportingStrategy reportingStrategy
) {
for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
if (member instanceof CallableMemberDescriptor) {
checkInheritedSignatures((CallableMemberDescriptor) member, reportingStrategy);
private class CollectErrorInformationForInheritedMembersStrategy
implements CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy {
private final KtClassOrObject klass;
private final ClassDescriptor classDescriptor;
private final Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
private final Set<CallableMemberDescriptor> multipleImplementations = Sets.newLinkedHashSet();
private final Set<CallableMemberDescriptor> abstractInBaseClassNoImpl = Sets.newLinkedHashSet();
private final Set<CallableMemberDescriptor> conflictingInterfaceMembers = Sets.newLinkedHashSet();
private final Set<CallableMemberDescriptor> conflictingReturnTypes = Sets.newHashSet();
private final Set<DiagnosticFactoryWithPsiElement> onceErrorsReported = new SmartHashSet<DiagnosticFactoryWithPsiElement>();
public CollectErrorInformationForInheritedMembersStrategy(
@NotNull KtClassOrObject klass,
@NotNull ClassDescriptor classDescriptor
) {
this.klass = klass;
this.classDescriptor = classDescriptor;
}
@Override
public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
abstractNoImpl.add(descriptor);
}
@Override
public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
abstractInBaseClassNoImpl.add(descriptor);
}
@Override
public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
multipleImplementations.add(descriptor);
}
@Override
public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
conflictingInterfaceMembers.add(descriptor);
}
@Override
public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
conflictingReturnTypes.add(descriptor1);
conflictingReturnTypes.add(descriptor2);
reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
}
@Override
public void propertyTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
conflictingReturnTypes.add(descriptor1);
conflictingReturnTypes.add(descriptor2);
reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
}
private void reportInheritanceConflictIfRequired(
@NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
@NotNull CallableMemberDescriptor descriptor1,
@NotNull CallableMemberDescriptor descriptor2
) {
if (!onceErrorsReported.contains(diagnosticFactory)) {
onceErrorsReported.add(diagnosticFactory);
trace.report(diagnosticFactory.on(klass, descriptor1, descriptor2));
}
}
@Override
public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
reportDelegationProblemIfRequired(OVERRIDING_FINAL_MEMBER_BY_DELEGATION, overriding, overridden);
}
@Override
public void returnTypeMismatchOnOverride(
@NotNull CallableMemberDescriptor overriding,
@NotNull CallableMemberDescriptor overridden
) {
conflictingReturnTypes.add(overridden);
reportDelegationProblemIfRequired(RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION, overriding, overridden);
}
@Override
public void propertyTypeMismatchOnOverride(
@NotNull CallableMemberDescriptor overriding,
@NotNull CallableMemberDescriptor overridden
) {
conflictingReturnTypes.add(overridden);
reportDelegationProblemIfRequired(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION, overriding, overridden);
}
@Override
public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
reportDelegationProblemIfRequired(VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, overriding, overridden);
}
private void reportDelegationProblemIfRequired(
@NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
@NotNull CallableMemberDescriptor delegate,
@NotNull CallableMemberDescriptor overridden
) {
assert delegate.getKind() == DELEGATION : "Delegate expected, got " + delegate + " of kind " + delegate.getKind();
if (!onceErrorsReported.contains(diagnosticFactory)) {
onceErrorsReported.add(diagnosticFactory);
trace.report(diagnosticFactory.on(klass, delegate, overridden));
}
}
@Override
public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
assert overriding.getKind() == DELEGATION : "Delegate expected, got " + overriding + " of kind " + overriding.getKind();
assert overriding.getKind() != DELEGATION : "Delegated member can't override an invisible member; " + invisibleOverridden;
}
@Override
public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
assert overriding.getKind() == DELEGATION : "Delegate expected, got " + overriding + " of kind " + overriding.getKind();
assert overriding.getKind() != DELEGATION : "Delegated member can't override nothing; " + overriding;
}
void 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()));
}
}
conflictingInterfaceMembers.removeAll(conflictingReturnTypes);
multipleImplementations.removeAll(conflictingReturnTypes);
if (!conflictingInterfaceMembers.isEmpty()) {
trace.report(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED.on(klass, klass, conflictingInterfaceMembers.iterator().next()));
}
else if (!multipleImplementations.isEmpty()) {
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, multipleImplementations.iterator().next()));
}
}
}
private static void checkInheritedSignatures(
@NotNull CallableMemberDescriptor descriptor,
@NotNull CheckInheritedSignaturesReportingStrategy reportingStrategy
private static void checkInheritedAndDelegatedSignatures(
@NotNull ClassDescriptor classDescriptor,
@NotNull CheckInheritedSignaturesReportStrategy inheritedReportStrategy,
@Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
) {
if (descriptor.getKind().isReal()) return;
for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
if (member instanceof CallableMemberDescriptor) {
checkInheritedAndDelegatedSignatures((CallableMemberDescriptor) member, inheritedReportStrategy, overrideReportStrategyForDelegates);
}
}
}
private static void checkInheritedAndDelegatedSignatures(
@NotNull CallableMemberDescriptor descriptor,
@NotNull CheckInheritedSignaturesReportStrategy reportingStrategy,
@Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
) {
CallableMemberDescriptor.Kind kind = descriptor.getKind();
if (kind != FAKE_OVERRIDE && kind != DELEGATION) return;
if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
if (directOverridden.size() == 0) {
throw new IllegalStateException("A 'fake override' " + descriptor.getName().asString() + " must override something");
throw new IllegalStateException(kind + " " + descriptor.getName().asString() + " must override something");
}
// collects map from the directly overridden descriptor to the set of declarations:
@@ -415,39 +503,55 @@ public class OverrideResolver {
Set<CallableMemberDescriptor> relevantDirectlyOverridden =
getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
checkInheritedSignaturesForFakeOverride(descriptor, relevantDirectlyOverridden, reportingStrategy);
checkInheritedDescriptorsGroup(relevantDirectlyOverridden, reportingStrategy);
collectJava8MissingOverrides(relevantDirectlyOverridden, reportingStrategy);
if (kind == DELEGATION) {
if (overrideReportStrategyForDelegates != null) {
checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates);
}
}
if (kind != DELEGATION) {
checkMissingOverridesByJava8Restrictions(descriptor, relevantDirectlyOverridden, reportingStrategy);
}
List<CallableMemberDescriptor> implementations = collectImplementations(relevantDirectlyOverridden);
if (implementations.size() == 1 && isReturnTypeOkForOverride(descriptor, implementations.get(0))) return;
int numImplementations = implementations.size();
if (numImplementations == 1 && isReturnTypeOkForOverride(descriptor, implementations.get(0))) return;
List<CallableMemberDescriptor> abstractOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
List<CallableMemberDescriptor> concreteOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden);
if (implementations.isEmpty()) {
for (CallableMemberDescriptor member : abstractOverridden) {
reportingStrategy.abstractMemberNoImpl(member);
if (numImplementations == 0) {
if (kind != DELEGATION) {
for (CallableMemberDescriptor member : abstractOverridden) {
reportingStrategy.abstractMemberNotImplemented(member);
}
}
}
else if (implementations.size() > 1) {
else if (numImplementations > 1) {
for (CallableMemberDescriptor member : concreteOverridden) {
reportingStrategy.manyImplMemberNoImpl(member);
reportingStrategy.multipleImplementationsMemberNotImplemented(member);
}
}
else {
List<CallableMemberDescriptor> membersWithMoreSpecificReturnType =
collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations.get(0));
for (CallableMemberDescriptor member : membersWithMoreSpecificReturnType) {
reportingStrategy.abstractMemberNoImpl(member);
if (kind != DELEGATION) {
List<CallableMemberDescriptor> membersWithMoreSpecificReturnType =
collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations.get(0));
for (CallableMemberDescriptor member : membersWithMoreSpecificReturnType) {
reportingStrategy.abstractMemberNotImplemented(member);
}
}
}
}
private static void collectJava8MissingOverrides(
private static void checkMissingOverridesByJava8Restrictions(
@NotNull CallableMemberDescriptor descriptor,
@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden,
@NotNull CheckInheritedSignaturesReportingStrategy reportingStrategy
@NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
) {
// Java 8:
// -- class should implement an abstract member of a super-class,
@@ -479,12 +583,11 @@ public class OverrideResolver {
}
if (overridesAbstractInBaseClass != null) {
reportingStrategy.abstractBaseClassMemberNoImpl(overridesAbstractInBaseClass);
reportingStrategy.abstractBaseClassMemberNotImplemented(overridesAbstractInBaseClass);
}
if (!overridesClassMember && overridesNonAbstractInterfaceMember && overriddenInterfaceMembers.size() > 1) {
for (CallableMemberDescriptor member : overriddenInterfaceMembers) {
reportingStrategy.conflictingMemberFromInterface(member);
reportingStrategy.conflictingInterfaceMemberNotImplemented(member);
}
}
}
@@ -634,17 +737,12 @@ public class OverrideResolver {
}
private interface CheckOverrideReportStrategy {
void overridingFinalMember(@NotNull CallableMemberDescriptor overridden);
void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden);
void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden);
void nothingToOverride();
void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden);
void nothingToOverride(@NotNull CallableMemberDescriptor overriding);
}
private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
@@ -675,7 +773,7 @@ public class OverrideResolver {
private boolean kindMismatchError = false;
@Override
public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
if (!finalOverriddenError) {
finalOverriddenError = true;
trace.report(OVERRIDING_FINAL_MEMBER.on(member, overridden, overridden.getContainingDeclaration()));
@@ -683,7 +781,7 @@ public class OverrideResolver {
}
@Override
public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
if (!typeMismatchError) {
typeMismatchError = true;
trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
@@ -691,7 +789,7 @@ public class OverrideResolver {
}
@Override
public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
if (!typeMismatchError) {
typeMismatchError = true;
trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
@@ -699,7 +797,7 @@ public class OverrideResolver {
}
@Override
public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
if (!kindMismatchError) {
kindMismatchError = true;
trace.report(VAR_OVERRIDDEN_BY_VAL.on(member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
@@ -707,12 +805,12 @@ public class OverrideResolver {
}
@Override
public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden));
}
@Override
public void nothingToOverride() {
public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
}
});
@@ -723,33 +821,28 @@ public class OverrideResolver {
}
}
private static void checkInheritedSignaturesForFakeOverride(
@NotNull CallableMemberDescriptor fakeOverride,
@NotNull Collection<CallableMemberDescriptor> relevantDirectlyOverridden,
@NotNull CheckInheritedSignaturesReportingStrategy reportingStrategy
private static void checkInheritedDescriptorsGroup(
@NotNull Collection<CallableMemberDescriptor> inheritedDescriptors,
@NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
) {
assert fakeOverride.getKind() == FAKE_OVERRIDE
: "Fake override expected; actual: " + fakeOverride + " of kind " + fakeOverride.getKind();
// FIXME This algorithm depends on transitiveness of sub-typing relation, which is broken in presence of flexible types.
// See override/clashesOnInheritance/flexibleReturnType.kt.
if (relevantDirectlyOverridden.size() > 1) {
Iterator<CallableMemberDescriptor> overriddenIterator = relevantDirectlyOverridden.iterator();
CallableMemberDescriptor mostSpecificOverridden = overriddenIterator.next();
while (overriddenIterator.hasNext()) {
CallableMemberDescriptor overriddenDescriptor = overriddenIterator.next();
if (OverridingUtil.isMoreSpecific(overriddenDescriptor, mostSpecificOverridden)) {
mostSpecificOverridden = overriddenDescriptor;
if (inheritedDescriptors.size() > 1) {
Iterator<CallableMemberDescriptor> inheritedIterator = inheritedDescriptors.iterator();
CallableMemberDescriptor mostSpecificInherited = inheritedIterator.next();
while (inheritedIterator.hasNext()) {
CallableMemberDescriptor overriddenDescriptor = inheritedIterator.next();
if (OverridingUtil.isMoreSpecific(overriddenDescriptor, mostSpecificInherited)) {
mostSpecificInherited = overriddenDescriptor;
}
}
for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
if (!OverridingUtil.isMoreSpecific(mostSpecificOverridden, overriddenDescriptor)) {
if (overriddenDescriptor instanceof PropertyDescriptor) {
reportingStrategy.clashingWithPropertyType(mostSpecificOverridden, overriddenDescriptor);
for (CallableMemberDescriptor inheritedDescriptor : inheritedDescriptors) {
if (!OverridingUtil.isMoreSpecific(mostSpecificInherited, inheritedDescriptor)) {
if (inheritedDescriptor instanceof PropertyDescriptor) {
reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificInherited, inheritedDescriptor);
}
else {
reportingStrategy.clashingWithReturnType(mostSpecificOverridden, overriddenDescriptor);
reportingStrategy.returnTypeMismatchOnInheritance(mostSpecificInherited, inheritedDescriptor);
}
}
}
@@ -763,25 +856,7 @@ public class OverrideResolver {
) {
Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
for (CallableMemberDescriptor overridden : overriddenDescriptors) {
if (overridden == null) continue;
if (!overridden.getModality().isOverridable()) {
reportError.overridingFinalMember(overridden);
}
if (declared instanceof PropertyDescriptor &&
!isPropertyTypeOkForOverride((PropertyDescriptor) overridden, (PropertyDescriptor) declared)) {
reportError.propertyTypeMismatchOnOverride(overridden);
}
else if (!isReturnTypeOkForOverride(overridden, declared)) {
reportError.returnTypeMismatchOnOverride(overridden);
}
if (checkPropertyKind(overridden, true) && checkPropertyKind(declared, false)) {
reportError.varOverriddenByVal(overridden);
}
}
checkOverridesForMember(declared, overriddenDescriptors, reportError);
if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
@@ -790,10 +865,36 @@ public class OverrideResolver {
CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
if (invisibleOverriddenDescriptor != null) {
reportError.cannotOverrideInvisibleMember(invisibleOverriddenDescriptor);
reportError.cannotOverrideInvisibleMember(declared, invisibleOverriddenDescriptor);
}
else {
reportError.nothingToOverride();
reportError.nothingToOverride(declared);
}
}
}
private static void checkOverridesForMember(
CallableMemberDescriptor memberDescriptor,
Collection<? extends CallableMemberDescriptor> overriddenDescriptors,
@NotNull CheckOverrideReportStrategy reportError
) {
for (CallableMemberDescriptor overridden : overriddenDescriptors) {
if (overridden == null) continue;
if (!overridden.getModality().isOverridable()) {
reportError.overridingFinalMember(memberDescriptor, overridden);
}
if (memberDescriptor instanceof PropertyDescriptor &&
!isPropertyTypeOkForOverride((PropertyDescriptor) overridden, (PropertyDescriptor) memberDescriptor)) {
reportError.propertyTypeMismatchOnOverride(memberDescriptor, overridden);
}
else if (!isReturnTypeOkForOverride(overridden, memberDescriptor)) {
reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden);
}
if (checkPropertyKind(overridden, true) && checkPropertyKind(memberDescriptor, false)) {
reportError.varOverriddenByVal(memberDescriptor, overridden);
}
}
}
@@ -855,7 +956,7 @@ public class OverrideResolver {
private boolean overrideConflict = false;
@Override
public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
if (!overrideConflict) {
overrideConflict = true;
trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
@@ -863,7 +964,7 @@ public class OverrideResolver {
}
@Override
public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
if (!overrideConflict) {
overrideConflict = true;
trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
@@ -871,22 +972,22 @@ public class OverrideResolver {
}
@Override
public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
throw new IllegalStateException("Component functions are not properties");
}
@Override
public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
throw new IllegalStateException("Component functions are not properties");
}
@Override
public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
}
@Override
public void nothingToOverride() {
public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
throw new IllegalStateException("Component functions are OK to override nothing");
}
});
@@ -10,9 +10,9 @@ interface Three {
public fun foo(): String
}
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test123<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test132<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test123<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test132<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test312<!>(val v1: One, val v2: Two, val v3: Three) : Three by v3, One by v1, Two by v2 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test321<!>(val v1: One, val v2: Two, val v3: Three) : Three by v3, Two by v2, One by v1 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test231<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test213<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test231<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test213<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { }
@@ -0,0 +1,44 @@
interface IStr {
fun foo(): String
}
class CStr : IStr {
override fun foo(): String = ""
}
interface IInt {
fun foo(): Int
}
class CInt : IInt {
override fun foo(): Int = 42
}
interface IGeneric<T> {
fun foo(): T
}
class CGeneric<T> : IGeneric<T> {
override fun foo(): T {
throw UnsupportedOperationException()
}
}
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test1<!> : IStr by CStr(), IInt
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test2<!> : IStr, IInt by CInt()
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test3<!> : IStr by CStr(), IInt by CInt()
abstract class Test4 : IStr by CStr(), IGeneric<String>
abstract class Test5 : IStr by CStr(), IGeneric<Any>
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test6<!> : IStr by CStr(), IGeneric<Int>
abstract class Test7 : IGeneric<String> by CGeneric<String>(), IStr
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE, RETURN_TYPE_MISMATCH_ON_OVERRIDE_BY_DELEGATION!>class Test8<!> : IGeneric<String> by CGeneric<String>(), IInt
// Can't test right now due to https://youtrack.jetbrains.com/issue/KT-10258
// abstract class Test9 : IGeneric<String> by CGeneric<String>(), IGeneric<Int>
@@ -0,0 +1,110 @@
package
public final class CGeneric</*0*/ T> : IGeneric<T> {
public constructor CGeneric</*0*/ T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun foo(): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class CInt : IInt {
public constructor CInt()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class CStr : IStr {
public constructor CStr()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun foo(): kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IGeneric</*0*/ T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IInt {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IStr {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test1 : IStr, IInt {
public constructor Test1()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test2 : IStr, IInt {
public constructor Test2()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test3 : IStr, IInt {
public constructor Test3()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test4 : IStr, IGeneric<kotlin.String> {
public constructor Test4()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test5 : IStr, IGeneric<kotlin.Any> {
public constructor Test5()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test6 : IStr, IGeneric<kotlin.Int> {
public constructor Test6()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test7 : IGeneric<kotlin.String>, IStr {
public constructor Test7()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Test8 : IGeneric<kotlin.String>, IInt {
public constructor Test8()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -13,7 +13,7 @@ public open class A : AImpl, kotlin.MutableList<kotlin.String!> {
public final override /*2*/ /*fake_override*/ fun contains(/*0*/ element: kotlin.String!): kotlin.Boolean
public final override /*2*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.Collection<kotlin.String!>): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String!
public final override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*2*/ /*fake_override*/ fun indexOf(/*0*/ element: kotlin.String!): kotlin.Int
public final override /*2*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
@@ -25,7 +25,7 @@ public open class A : AImpl, kotlin.MutableList<kotlin.String!> {
public final override /*2*/ /*fake_override*/ fun removeAll(/*0*/ elements: kotlin.Collection<kotlin.String!>): kotlin.Boolean
public final override /*2*/ /*fake_override*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.String
public final override /*2*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.Collection<kotlin.String!>): kotlin.Boolean
public final override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String!
public final override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String): kotlin.String
public final override /*2*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList<kotlin.String!>
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -69,7 +69,7 @@ public final class X : A {
public final override /*1*/ /*fake_override*/ fun contains(/*0*/ element: kotlin.String!): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.Collection<kotlin.String!>): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String!
public final override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun indexOf(/*0*/ element: kotlin.String!): kotlin.Int
public final override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
@@ -81,7 +81,7 @@ public final class X : A {
public final override /*1*/ /*fake_override*/ fun removeAll(/*0*/ elements: kotlin.Collection<kotlin.String!>): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.String
public final override /*1*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.Collection<kotlin.String!>): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String!
public final override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String): kotlin.String
public final override /*1*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList<kotlin.String!>
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -53,7 +53,7 @@ public abstract class B</*0*/ T> : kotlin.MutableList<T>, java.util.AbstractList
public open override /*2*/ /*fake_override*/ fun contains(/*0*/ element: T!): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.Collection<T!>): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): T!
public abstract override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): T
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun indexOf(/*0*/ element: T!): kotlin.Int
public open override /*2*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
@@ -68,7 +68,7 @@ public abstract class B</*0*/ T> : kotlin.MutableList<T>, java.util.AbstractList
public open override /*2*/ fun removeAt(/*0*/ index: kotlin.Int): T
protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit
public open override /*2*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.Collection<T!>): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: T!): T!
public open override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: T): T
public open override /*2*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList<T!>
public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>!
public open override /*1*/ /*fake_override*/ fun </*0*/ T : kotlin.Any!> toArray(/*0*/ p0: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>!
@@ -14,7 +14,7 @@ public abstract class A : B {
public open override /*1*/ /*fake_override*/ fun contains(/*0*/ element: kotlin.Int!): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.Collection<kotlin.Int!>): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Int!
public abstract override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ element: kotlin.Int!): kotlin.Int
public open override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
@@ -29,7 +29,7 @@ public abstract class A : B {
public open override /*1*/ fun removeAt(/*0*/ x: kotlin.Int): kotlin.Int
protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.Collection<kotlin.Int!>): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.Int!): kotlin.Int!
public open override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.Int): kotlin.Int
public open override /*1*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList<kotlin.Int!>
public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>!
public open override /*1*/ /*fake_override*/ fun </*0*/ T : kotlin.Any!> toArray(/*0*/ p0: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>!
@@ -53,7 +53,7 @@ public abstract class B : kotlin.MutableList<kotlin.Int>, java.util.AbstractList
public open override /*2*/ /*fake_override*/ fun contains(/*0*/ element: kotlin.Int!): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.Collection<kotlin.Int!>): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Int!
public abstract override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Int
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun indexOf(/*0*/ element: kotlin.Int!): kotlin.Int
public open override /*2*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
@@ -68,7 +68,7 @@ public abstract class B : kotlin.MutableList<kotlin.Int>, java.util.AbstractList
public open override /*2*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.Int
protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit
public open override /*2*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.Collection<kotlin.Int!>): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.Int!): kotlin.Int!
public open override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.Int): kotlin.Int
public open override /*2*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList<kotlin.Int!>
public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>!
public open override /*1*/ /*fake_override*/ fun </*0*/ T : kotlin.Any!> toArray(/*0*/ p0: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>!
@@ -21,10 +21,7 @@ interface KDerived2a : K2, J
interface KDerived2b : J, K2
interface KDerived12a : K1, K2, J
// public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.String!
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface KDerived12b<!> : K1, J, K2 // TODO
// public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.String?
interface KDerived12b : K1, J, K2
interface KDerived12c : J, K1, K2
// public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.String
interface KDerived12c : J, K1, K2
@@ -25,14 +25,14 @@ public interface K2 {
public interface KDerived12a : K1, K2, J {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.String!
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.String
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface KDerived12b : K1, J, K2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.String?
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.String
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -46,7 +46,7 @@ public interface KDerived12c : J, K1, K2 {
public interface KDerived1a : K1, J {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.String!
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.String
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,63 @@
// FILE: InOut.k
interface In<in T>
interface Out<out T>
interface Inv<T>
// FILE: J1.java
public interface J1 {
In<String> foo();
}
// FILE: J2.java
import org.jetbrains.annotations.*;
public interface J2 {
@NotNull In<String> foo();
}
// FILE: J3.java
import org.jetbrains.annotations.*;
public interface J3 {
@Nullable In<String> foo();
}
// FILE: K.kt
interface K1 {
fun foo(): In<String>
}
interface K2 {
fun foo(): In<String?>
}
// FIXME TestJ1K1 should have foo(): In<String!>, since In<String!> <: In<String>.
interface TestJ1K1 : J1, K1
interface TestK1J1 : K1, J1
interface TestJ1K2 : J1, K2
interface TestK2J1 : K2, J1
interface TestJ2K1 : J2, K1
interface TestK1J2 : K1, J2
interface TestJ2K2 : J2, K2
interface TestK2J2 : K2, J2
interface TestJ3K1 : J3, K1
interface TestK1J3 : K1, J3
interface TestJ3K2 : J3, K2
interface TestK2J3 : K2, J3
interface TestJ1K1K2 : J1, K1, K2
interface TestK1J1K2 : K1, J1, K2
interface TestK1K2J1 : K1, K2, J1
interface TestJ2K1K2 : J2, K1, K2
interface TestK1J2K2 : K1, J2, K2
interface TestK1K2J2 : K1, K2, J2
interface TestJ3K1K2 : J3, K1, K2
interface TestK1J3K2 : K1, J3, K2
interface TestK1K2J3 : K1, K2, J3
@@ -0,0 +1,205 @@
package
public /*synthesized*/ fun J1(/*0*/ function: () -> In<kotlin.String!>!): J1
public /*synthesized*/ fun J2(/*0*/ function: () -> In<kotlin.String!>!): J2
public /*synthesized*/ fun J3(/*0*/ function: () -> In<kotlin.String!>!): J3
public interface In</*0*/ in T> {
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 Inv</*0*/ T> {
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 J1 {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): In<kotlin.String!>!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface J2 {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull() public abstract fun foo(): In<kotlin.String!>
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface J3 {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.Nullable() public abstract fun foo(): In<kotlin.String!>?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface K1 {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): In<kotlin.String>
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface K2 {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): In<kotlin.String?>
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Out</*0*/ out T> {
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 TestJ1K1 : J1, K1 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ1K1K2 : J1, K1, K2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ1K2 : J1, K2 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ2K1 : J2, K1 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ2K1K2 : J2, K1, K2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ2K2 : J2, K2 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ3K1 : J3, K1 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ3K1K2 : J3, K1, K2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestJ3K2 : J3, K2 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1J1 : K1, J1 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1J1K2 : K1, J1, K2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1J2 : K1, J2 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull() public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String!>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1J2K2 : K1, J2, K2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1J3 : K1, J3 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1J3K2 : K1, J3, K2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1K2J1 : K1, K2, J1 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1K2J2 : K1, K2, J2 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull() public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String!>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK1K2J3 : K1, K2, J3 {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK2J1 : K2, J1 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK2J2 : K2, J2 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@org.jetbrains.annotations.NotNull() public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String!>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface TestK2J3 : K2, J3 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): In<kotlin.String?>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,37 @@
// FILE: J.java
public interface J {
java.util.List<String> foo();
}
// FILE: K.kt
interface ILNS {
fun foo(): List<String?>
}
interface IMLS {
fun foo(): MutableList<String>
}
interface IMLNS {
fun foo(): MutableList<String?>
}
interface ILS {
fun foo(): List<String>
}
interface Test1 : ILNS, J
interface Test2 : J, ILNS
interface Test3 : IMLS, J
interface Test4 : J, IMLS
interface Test5 : ILNS, IMLS, J
interface Test6 : ILNS, J, IMLS
interface Test7 : J, ILNS, IMLS
// ILS and IMLNS are incompatible
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface Test8<!> : J, IMLNS, ILS
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface Test9<!> : IMLNS, J, ILS
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface Test10<!> : IMLNS, ILS, J
@@ -0,0 +1,108 @@
package
public /*synthesized*/ fun J(/*0*/ function: () -> kotlin.(Mutable)List<kotlin.String!>!): J
public interface ILNS {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.List<kotlin.String?>
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface ILS {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.List<kotlin.String>
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IMLNS {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.MutableList<kotlin.String?>
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IMLS {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.MutableList<kotlin.String>
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface J {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.(Mutable)List<kotlin.String!>!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test1 : ILNS, J {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.List<kotlin.String?>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test10 : IMLNS, ILS, J {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test2 : J, ILNS {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.List<kotlin.String?>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test3 : IMLS, J {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test4 : J, IMLS {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String>
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test5 : ILNS, IMLS, J {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test6 : ILNS, J, IMLS {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test7 : J, ILNS, IMLS {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test8 : J, IMLNS, ILS {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test9 : IMLNS, J, ILS {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String?>
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,29 @@
open class A {
open var foo: Boolean = true
}
interface IA {
var foo: String
}
interface IAA {
var foo: Int
}
interface IGA<T> {
var foo: T
}
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class B1<!>: A(), IA
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class B2<!>: A(), IA, IAA
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class B3<!>: IA, IAA
class BS1: A(), IGA<Boolean>
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class BS2<!>: A(), IGA<Any>
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class BS3<!>: A(), IGA<String>
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class BG1<!><T>: A(), IGA<T>
@@ -0,0 +1,86 @@
package
public open class A {
public constructor A()
public open var foo: kotlin.Boolean
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 final class B1 : A, IA {
public constructor B1()
public open override /*2*/ /*fake_override*/ var foo: kotlin.Boolean
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 B2 : A, IA, IAA {
public constructor B2()
public open override /*3*/ /*fake_override*/ var foo: kotlin.Boolean
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class B3 : IA, IAA {
public constructor B3()
public abstract override /*2*/ /*fake_override*/ var 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 BG1</*0*/ T> : A, IGA<T> {
public constructor BG1</*0*/ T>()
public open override /*2*/ /*fake_override*/ var foo: kotlin.Boolean
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 BS1 : A, IGA<kotlin.Boolean> {
public constructor BS1()
public open override /*2*/ /*fake_override*/ var foo: kotlin.Boolean
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 BS2 : A, IGA<kotlin.Any> {
public constructor BS2()
public open override /*2*/ /*fake_override*/ var foo: kotlin.Boolean
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 BS3 : A, IGA<kotlin.String> {
public constructor BS3()
public open override /*2*/ /*fake_override*/ var foo: kotlin.Boolean
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 interface IA {
public abstract var 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 IAA {
public abstract var foo: kotlin.Int
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 IGA</*0*/ T> {
public abstract var foo: T
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
}
@@ -24,7 +24,7 @@ fun foo(k: KotlinClass) {
k.setSomething4("")
k.something4 += ""
k.setSomething4(<!NULL_FOR_NONNULL_TYPE!>null<!>)
k.something4 = null
k.something4 = <!NULL_FOR_NONNULL_TYPE!>null<!>
useString(k.getSomething5())
useString(k.something5)
@@ -30,7 +30,7 @@ public abstract class KotlinClass : JavaClass, KotlinInterface, JavaInterface {
public open override /*2*/ fun getSomething1(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun getSomething2(): kotlin.Int
public open override /*1*/ fun getSomething3(): kotlin.String
public abstract override /*2*/ /*fake_override*/ fun getSomething4(): kotlin.String!
public abstract override /*2*/ /*fake_override*/ fun getSomething4(): kotlin.String
public open override /*1*/ fun getSomething5(): kotlin.String
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun setSomething4(/*0*/ value: kotlin.String): kotlin.Unit
@@ -26,7 +26,7 @@ public interface B : A {
public interface C : A, A1 {
public abstract override /*1*/ /*fake_override*/ fun dynamic(/*0*/ p: dynamic): dynamic
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(/*0*/ p: dynamic): dynamic
public abstract override /*2*/ /*fake_override*/ fun foo(/*0*/ p: P): R
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -4754,6 +4754,21 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegation/Delegation_ScopeInitializationOrder.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/diagnostics/tests/delegation/clashes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Clashes extends AbstractDiagnosticsTest {
public void testAllFilesPresentInClashes() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/delegation/clashes"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("returnTypeMismatch.kt")
public void testReturnTypeMismatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegation/clashes/returnTypeMismatch.kt");
doTest(fileName);
}
}
}
@TestMetadata("compiler/testData/diagnostics/tests/deparenthesize")
@@ -11315,9 +11330,15 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("propertyTypeMismatch.kt")
public void testPropertyTypeMismatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/propertyTypeMismatch.kt");
@TestMetadata("flexibleReturnTypeIn.kt")
public void testFlexibleReturnTypeIn() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeIn.kt");
doTest(fileName);
}
@TestMetadata("flexibleReturnTypeList.kt")
public void testFlexibleReturnTypeList() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.kt");
doTest(fileName);
}
@@ -11332,6 +11353,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/unrelatedInherited.kt");
doTest(fileName);
}
@TestMetadata("valTypeMismatch.kt")
public void testValTypeMismatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.kt");
doTest(fileName);
}
@TestMetadata("varTypeMismatch.kt")
public void testVarTypeMismatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/tests/override/parameterNames")
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeCapabilitiesKt;
import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
@@ -320,14 +321,16 @@ public class OverridingUtil {
}
public static boolean isMoreSpecific(@NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) {
KotlinType aReturnType = a.getReturnType();
assert aReturnType != null : "Return type is null for " + a;
// Use upper bound for flexible type.
aReturnType = TypeCapabilitiesKt.getSupertypeRepresentative(aReturnType);
KotlinType bReturnType = b.getReturnType();
assert bReturnType != null : "Return type is null for " + b;
if (a instanceof SimpleFunctionDescriptor) {
assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();
KotlinType aReturnType = a.getReturnType();
assert aReturnType != null;
KotlinType bReturnType = b.getReturnType();
assert bReturnType != null;
return KotlinTypeChecker.DEFAULT.isSubtypeOf(aReturnType, bReturnType);
}
if (a instanceof PropertyDescriptor) {
@@ -336,11 +339,16 @@ public class OverridingUtil {
PropertyDescriptor pa = (PropertyDescriptor) a;
PropertyDescriptor pb = (PropertyDescriptor) b;
if (pa.isVar() && pb.isVar()) {
return KotlinTypeChecker.DEFAULT.equalTypes(pa.getType(), pb.getType());
return KotlinTypeChecker.DEFAULT.equalTypes(aReturnType, bReturnType);
}
else if (!pa.isVar() && pb.isVar()) {
// val can't be more specific than var, regardless of return type.
return false;
}
else {
// both vals or var <? val
return KotlinTypeChecker.DEFAULT.isSubtypeOf(aReturnType, bReturnType);
}
// both vals or var <? val
return KotlinTypeChecker.DEFAULT.isSubtypeOf(pa.getType(), pb.getType());
}
throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
}
@@ -364,6 +372,13 @@ public class OverridingUtil {
boolean allInvisible = visibleOverridables.isEmpty();
Collection<CallableMemberDescriptor> effectiveOverridden = allInvisible ? overridables : visibleOverridables;
// FIXME doesn't work as expected for flexible types: should create a refined signature.
// Current algorithm produces bad results in presence of annotated Java signatures such as:
// J: foo(s: String!): String -- @NotNull String foo(String s);
// K: foo(s: String): String?
// --> 'foo(s: String!): String' as an inherited signature with most specific return type.
// This is bad because it can be overridden by 'foo(s: String?): String', which is not override-equivalent with K::foo above.
// Should be 'foo(s: String): String'.
Modality modality = getMinimalModality(effectiveOverridden);
Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED;
CallableMemberDescriptor mostSpecific = selectMostSpecificMemberFromSuper(effectiveOverridden);