KT-9550: distinguish signature conflict on override from signature conflict of inherited members.

Add a common OverridingStrategy class for cases where we don't care (yet) about precise diagnostics.
This commit is contained in:
Dmitry Petrov
2016-02-19 13:04:17 +03:00
parent 883e2e4d2b
commit 30c2abba3c
13 changed files with 86 additions and 13 deletions
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.isBuiltinWithSpecialDescriptorInJvm import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.isBuiltinWithSpecialDescriptorInJvm
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverrideResolver import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.OverridingStrategy import org.jetbrains.kotlin.resolve.OverridingStrategy
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
@@ -191,7 +192,7 @@ class CollectionStubMethodGenerator(
): List<FunctionDescriptor> { ): List<FunctionDescriptor> {
val result = ArrayList<FunctionDescriptor>() val result = ArrayList<FunctionDescriptor>()
OverrideResolver.generateOverridesInAClass(klass, listOf(), object : OverridingStrategy() { OverrideResolver.generateOverridesInAClass(klass, listOf(), object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) { override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
if (fakeOverride !is FunctionDescriptor) return if (fakeOverride !is FunctionDescriptor) return
if (fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionClass)?.kind == DECLARATION) { if (fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionClass)?.kind == DECLARATION) {
@@ -345,6 +345,8 @@ public interface Errors {
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION = DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME); DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, ClassDescriptor, Collection<CallableMemberDescriptor>> CONFLICTING_INHERITED_MEMBERS =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, KtClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED = DiagnosticFactory2<KtClassOrObject, KtClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED =
DiagnosticFactory2.create(ERROR, DECLARATION_NAME); DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
DiagnosticFactory2<KtClassOrObject, KtClassOrObject, CallableMemberDescriptor> ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED = DiagnosticFactory2<KtClassOrObject, KtClassOrObject, CallableMemberDescriptor> ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED =
@@ -601,6 +601,7 @@ public class DefaultErrorMessages {
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(VAR_OVERRIDDEN_BY_VAL, "Var-property {0} cannot be overridden by val-property {1}", FQ_NAMES_IN_TYPES, FQ_NAMES_IN_TYPES);
MAP.put(CONFLICTING_INHERITED_MEMBERS, "{0} inherits conflicting members: {1}", NAME, commaSeparated(FQ_NAMES_IN_TYPES));
MAP.put(ABSTRACT_MEMBER_NOT_IMPLEMENTED, "{0} must be declared abstract or implement abstract member {1}", RENDER_CLASS_OR_OBJECT, MAP.put(ABSTRACT_MEMBER_NOT_IMPLEMENTED, "{0} must be declared abstract or implement abstract member {1}", RENDER_CLASS_OR_OBJECT,
FQ_NAMES_IN_TYPES); FQ_NAMES_IN_TYPES);
MAP.put(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, "{0} must be declared abstract or implement abstract base class member {1}", MAP.put(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, "{0} must be declared abstract or implement abstract base class member {1}",
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeReference import org.jetbrains.kotlin.psi.KtTypeReference
@@ -106,10 +107,15 @@ open class LazyClassMemberScope(
result.add(fakeOverride as D) result.add(fakeOverride as D)
} }
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) { override fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as? KtDeclaration ?: error("fromCurrent can not be a fake override") val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as? KtDeclaration ?: error("fromCurrent can not be a fake override")
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromSuper.containingDeclaration)) trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromSuper.containingDeclaration))
} }
override fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) {
val thisClassDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(thisDescriptor) as? KtClassOrObject ?: error("No class declaration")
trace.report(Errors.CONFLICTING_INHERITED_MEMBERS.on(thisClassDeclaration, thisDescriptor, listOf(first, second)))
}
}) })
OverrideResolver.resolveUnknownVisibilities(result, trace) OverrideResolver.resolveUnknownVisibilities(result, trace)
} }
@@ -0,0 +1,13 @@
interface A {
fun <T> foo()
fun <T> bar()
}
interface B {
fun foo()
fun bar()
}
<!CONFLICTING_INHERITED_MEMBERS!>interface C1<!> : A, B {
<!CONFLICTING_OVERLOADS!>override fun bar()<!>
}
@@ -0,0 +1,25 @@
package
public interface A {
public abstract fun </*0*/ T> bar(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun </*0*/ T> foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B {
public abstract fun bar(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface C1 : A, B {
public abstract override /*1*/ fun bar(): kotlin.Unit
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun </*0*/ T> foo(): kotlin.Unit
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -12146,6 +12146,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt9550.kt")
public void testKt9550() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt");
doTest(fileName);
}
@TestMetadata("returnTypeMismatch.kt") @TestMetadata("returnTypeMismatch.kt")
public void testReturnTypeMismatch() throws Exception { public void testReturnTypeMismatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.kt");
@@ -27,11 +27,14 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.load.java.structure.*; import org.jetbrains.kotlin.load.java.structure.*;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.OverridingStrategy; import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy;
import org.jetbrains.kotlin.resolve.OverridingUtil; import org.jetbrains.kotlin.resolve.OverridingUtil;
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter; import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter;
import java.util.*; import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public final class DescriptorResolverUtils { public final class DescriptorResolverUtils {
private DescriptorResolverUtils() { private DescriptorResolverUtils() {
@@ -66,7 +69,7 @@ public final class DescriptorResolverUtils {
OverridingUtil.generateOverridesInFunctionGroup( OverridingUtil.generateOverridesInFunctionGroup(
name, membersFromSupertypes, membersFromCurrent, classDescriptor, name, membersFromSupertypes, membersFromCurrent, classDescriptor,
new OverridingStrategy() { new NonReportingOverrideStrategy() {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride) { public void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride) {
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverridingStrategy import org.jetbrains.kotlin.resolve.OverridingStrategy
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
@@ -67,7 +68,7 @@ class FunctionClassScope(
/* membersFromSupertypes = */ descriptors, /* membersFromSupertypes = */ descriptors,
/* membersFromCurrent = */ if (isFunction && name == invoke?.name) listOf(invoke) else listOf(), /* membersFromCurrent = */ if (isFunction && name == invoke?.name) listOf(invoke) else listOf(),
functionClass, functionClass,
object : OverridingStrategy() { object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) { override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null) OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)
result.add(fakeOverride) result.add(fakeOverride)
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorFactory; import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.OverridingStrategy; import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy;
import org.jetbrains.kotlin.resolve.OverridingUtil; import org.jetbrains.kotlin.resolve.OverridingUtil;
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.MemberScope;
@@ -246,7 +246,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
OverridingUtil.generateOverridesInFunctionGroup( OverridingUtil.generateOverridesInFunctionGroup(
name, fromSupertypes, Collections.<D>emptySet(), EnumEntrySyntheticClassDescriptor.this, name, fromSupertypes, Collections.<D>emptySet(), EnumEntrySyntheticClassDescriptor.this,
new OverridingStrategy() { new NonReportingOverrideStrategy() {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride) { public void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride) {
@@ -255,7 +255,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
} }
@Override @Override
public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) { protected void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
// Do nothing // Do nothing
} }
} }
@@ -21,9 +21,23 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
abstract class OverridingStrategy { abstract class OverridingStrategy {
abstract fun addFakeOverride(fakeOverride: CallableMemberDescriptor) abstract fun addFakeOverride(fakeOverride: CallableMemberDescriptor)
abstract fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) abstract fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor)
abstract fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor)
open fun setOverriddenDescriptors(member: CallableMemberDescriptor, overridden: Collection<CallableMemberDescriptor>) { open fun setOverriddenDescriptors(member: CallableMemberDescriptor, overridden: Collection<CallableMemberDescriptor>) {
member.overriddenDescriptors = overridden member.overriddenDescriptors = overridden
} }
}
abstract class NonReportingOverrideStrategy : OverridingStrategy() {
override fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
conflict(fromSuper, fromCurrent)
}
override fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) {
conflict(first, second)
}
protected abstract fun conflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor)
} }
@@ -347,7 +347,7 @@ public class OverridingUtil {
break; break;
case CONFLICT: case CONFLICT:
if (isVisible) { if (isVisible) {
strategy.conflict(fromSupertype, fromCurrent); strategy.overrideConflict(fromSupertype, fromCurrent);
} }
bound.add(fromSupertype); bound.add(fromSupertype);
break; break;
@@ -638,7 +638,7 @@ public class OverridingUtil {
new Function1<CallableMemberDescriptor, Unit>() { new Function1<CallableMemberDescriptor, Unit>() {
@Override @Override
public Unit invoke(CallableMemberDescriptor descriptor) { public Unit invoke(CallableMemberDescriptor descriptor) {
strategy.conflict(overrider, descriptor); strategy.inheritanceConflict(overrider, descriptor);
return Unit.INSTANCE; return Unit.INSTANCE;
} }
}); });
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverridingStrategy import org.jetbrains.kotlin.resolve.OverridingStrategy
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -220,7 +221,7 @@ class DeserializedClassDescriptor(
private fun <D : CallableMemberDescriptor> generateFakeOverrides(name: Name, fromSupertypes: Collection<D>, result: MutableCollection<D>) { private fun <D : CallableMemberDescriptor> generateFakeOverrides(name: Name, fromSupertypes: Collection<D>, result: MutableCollection<D>) {
val fromCurrent = ArrayList<CallableMemberDescriptor>(result) val fromCurrent = ArrayList<CallableMemberDescriptor>(result)
OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, fromCurrent, classDescriptor, object : OverridingStrategy() { OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, fromCurrent, classDescriptor, object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) { override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
// TODO: report "cannot infer visibility" // TODO: report "cannot infer visibility"
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null) OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)