Add 'subClassDescriptor' parameter to ExternalOverridabilityCondition

This commit is contained in:
Denis Zharkov
2015-12-09 08:44:14 +03:00
parent 417ff281ee
commit 45c0bc3610
9 changed files with 35 additions and 17 deletions
@@ -30,7 +30,11 @@ import java.util.List;
public class SamAdapterOverridabilityCondition implements ExternalOverridabilityCondition { public class SamAdapterOverridabilityCondition implements ExternalOverridabilityCondition {
@NotNull @NotNull
@Override @Override
public Result isOverridable(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { public Result isOverridable(
@NotNull CallableDescriptor superDescriptor,
@NotNull CallableDescriptor subDescriptor,
@Nullable ClassDescriptor subClassDescriptor
) {
if (!(subDescriptor instanceof SimpleFunctionDescriptor) || !(superDescriptor instanceof SimpleFunctionDescriptor)) { if (!(subDescriptor instanceof SimpleFunctionDescriptor) || !(superDescriptor instanceof SimpleFunctionDescriptor)) {
return Result.UNKNOWN; return Result.UNKNOWN;
} }
@@ -115,7 +115,7 @@ class DelegationResolver<T : CallableMemberDescriptor> private constructor(
possiblyOverriddenBy.any { isOverridableBy(it, candidate) } possiblyOverriddenBy.any { isOverridableBy(it, candidate) }
private fun isOverridableBy(memberOne: CallableDescriptor, memberTwo: CallableDescriptor): Boolean = private fun isOverridableBy(memberOne: CallableDescriptor, memberTwo: CallableDescriptor): Boolean =
OverridingUtil.DEFAULT.isOverridableBy(memberOne, memberTwo).result == OVERRIDABLE OverridingUtil.DEFAULT.isOverridableBy(memberOne, memberTwo, null).result == OVERRIDABLE
} }
} }
@@ -200,8 +200,8 @@ public class OverrideResolver {
for (D otherD : candidates) { for (D otherD : candidates) {
CallableDescriptor other = transform.fun(otherD); CallableDescriptor other = transform.fun(otherD);
if (me.getOriginal() == other.getOriginal() if (me.getOriginal() == other.getOriginal()
&& OverridingUtil.DEFAULT.isOverridableBy(other, me).getResult() == OVERRIDABLE && OverridingUtil.DEFAULT.isOverridableBy(other, me, null).getResult() == OVERRIDABLE
&& OverridingUtil.DEFAULT.isOverridableBy(me, other).getResult() == OVERRIDABLE) { && OverridingUtil.DEFAULT.isOverridableBy(me, other, null).getResult() == OVERRIDABLE) {
continue outerLoop; continue outerLoop;
} }
} }
@@ -1027,7 +1027,7 @@ public class OverrideResolver {
//noinspection unchecked //noinspection unchecked
all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES)); all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
for (CallableMemberDescriptor fromSuper : all) { for (CallableMemberDescriptor fromSuper : all) {
if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) { if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared, null).getResult() == OVERRIDABLE) {
if (Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSuper, declared)) { if (Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSuper, declared)) {
throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared + throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
" and visible but does not appear in its getOverriddenDescriptors()"); " and visible but does not appear in its getOverriddenDescriptors()");
@@ -156,7 +156,7 @@ public class KotlinOverridingTest extends KotlinLiteFixture {
private void assertOverridabilityRelation(String superFun, String subFun, boolean expectedIsError) { private void assertOverridabilityRelation(String superFun, String subFun, boolean expectedIsError) {
FunctionDescriptor a = makeFunction(superFun); FunctionDescriptor a = makeFunction(superFun);
FunctionDescriptor b = makeFunction(subFun); FunctionDescriptor b = makeFunction(subFun);
OverridingUtil.OverrideCompatibilityInfo overridableWith = OverridingUtil.DEFAULT.isOverridableBy(a, b); OverridingUtil.OverrideCompatibilityInfo overridableWith = OverridingUtil.DEFAULT.isOverridableBy(a, b, null);
assertEquals( assertEquals(
overridableWith.getDebugMessage(), overridableWith.getDebugMessage(),
expectedIsError, expectedIsError,
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.load.java package org.jetbrains.kotlin.load.java
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.lazy.types.RawSubstitution import org.jetbrains.kotlin.load.java.lazy.types.RawSubstitution
@@ -25,7 +26,7 @@ import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
class ErasedOverridabilityCondition : ExternalOverridabilityCondition { class ErasedOverridabilityCondition : ExternalOverridabilityCondition {
override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor): Result { override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor, subClassDescriptor: ClassDescriptor?): Result {
if (subDescriptor !is JavaMethodDescriptor) return Result.UNKNOWN if (subDescriptor !is JavaMethodDescriptor) return Result.UNKNOWN
var erasedSuper = superDescriptor.substitute(RawSubstitution.buildSubstitutor()) ?: return Result.UNKNOWN var erasedSuper = superDescriptor.substitute(RawSubstitution.buildSubstitutor()) ?: return Result.UNKNOWN
@@ -17,13 +17,14 @@
package org.jetbrains.kotlin.load.java package org.jetbrains.kotlin.load.java
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
class FieldOverridabilityCondition : ExternalOverridabilityCondition { class FieldOverridabilityCondition : ExternalOverridabilityCondition {
override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor): Result { override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor, subClassDescriptor: ClassDescriptor?): Result {
if (subDescriptor !is PropertyDescriptor || superDescriptor !is PropertyDescriptor) return Result.UNKNOWN if (subDescriptor !is PropertyDescriptor || superDescriptor !is PropertyDescriptor) return Result.UNKNOWN
if (subDescriptor.name != superDescriptor.name) return Result.UNKNOWN if (subDescriptor.name != superDescriptor.name) return Result.UNKNOWN
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.resolve; package org.jetbrains.kotlin.resolve;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
public interface ExternalOverridabilityCondition { public interface ExternalOverridabilityCondition {
enum Result { enum Result {
@@ -25,5 +27,9 @@ public interface ExternalOverridabilityCondition {
} }
@NotNull @NotNull
Result isOverridable(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor); Result isOverridable(
@NotNull CallableDescriptor superDescriptor,
@NotNull CallableDescriptor subDescriptor,
@Nullable ClassDescriptor subClassDescriptor
);
} }
@@ -62,23 +62,29 @@ public class OverridingUtil {
} }
@NotNull @NotNull
public OverrideCompatibilityInfo isOverridableBy(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { public OverrideCompatibilityInfo isOverridableBy(
return isOverridableBy(superDescriptor, subDescriptor, false); @NotNull CallableDescriptor superDescriptor,
@NotNull CallableDescriptor subDescriptor,
@Nullable ClassDescriptor subClassDescriptor
) {
return isOverridableBy(superDescriptor, subDescriptor, subClassDescriptor, false);
} }
@NotNull @NotNull
public OverrideCompatibilityInfo isOverridableByIncludingReturnType(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { public OverrideCompatibilityInfo isOverridableByIncludingReturnType(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
return isOverridableBy(superDescriptor, subDescriptor, true); return isOverridableBy(superDescriptor, subDescriptor, null, true);
} }
@NotNull @NotNull
private OverrideCompatibilityInfo isOverridableBy( private OverrideCompatibilityInfo isOverridableBy(
@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor superDescriptor,
@NotNull CallableDescriptor subDescriptor, @NotNull CallableDescriptor subDescriptor,
@Nullable ClassDescriptor subClassDescriptor,
boolean checkReturnType boolean checkReturnType
) { ) {
for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) { for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) {
ExternalOverridabilityCondition.Result result = externalCondition.isOverridable(superDescriptor, subDescriptor); ExternalOverridabilityCondition.Result result =
externalCondition.isOverridable(superDescriptor, subDescriptor, subClassDescriptor);
switch (result) { switch (result) {
case OVERRIDABLE: case OVERRIDABLE:
return OverrideCompatibilityInfo.success(); return OverrideCompatibilityInfo.success();
@@ -281,7 +287,7 @@ public class OverridingUtil {
) { ) {
Collection<CallableMemberDescriptor> bound = new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size()); Collection<CallableMemberDescriptor> bound = new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size());
for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) { for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent).getResult(); OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent, current).getResult();
boolean isVisible = Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSupertype, current); boolean isVisible = Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSupertype, current);
switch (result) { switch (result) {
@@ -429,8 +435,8 @@ public class OverridingUtil {
continue; continue;
} }
OverrideCompatibilityInfo.Result result1 = DEFAULT.isOverridableBy(candidate, overrider).getResult(); OverrideCompatibilityInfo.Result result1 = DEFAULT.isOverridableBy(candidate, overrider, null).getResult();
OverrideCompatibilityInfo.Result result2 = DEFAULT.isOverridableBy(overrider, candidate).getResult(); OverrideCompatibilityInfo.Result result2 = DEFAULT.isOverridableBy(overrider, candidate, null).getResult();
if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) { if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) {
overridable.add(candidate); overridable.add(candidate);
iterator.remove(); iterator.remove();
@@ -65,7 +65,7 @@ public fun ClassDescriptor.findCallableMemberBySignature(signature: CallableMemb
.filterIsInstance<CallableMemberDescriptor>() .filterIsInstance<CallableMemberDescriptor>()
.firstOrNull { .firstOrNull {
it.getContainingDeclaration() == this it.getContainingDeclaration() == this
&& OverridingUtil.DEFAULT.isOverridableBy(it as CallableDescriptor, signature).getResult() == OVERRIDABLE && OverridingUtil.DEFAULT.isOverridableBy(it as CallableDescriptor, signature, null).getResult() == OVERRIDABLE
} as? CallableMemberDescriptor } as? CallableMemberDescriptor
} }