Optimize ErasedOverridabilityCondition

Do not start substitution if some basic conditions are failed
This commit is contained in:
Denis Zharkov
2016-02-12 15:53:27 +03:00
parent 44148107ae
commit 42d451f2d1
2 changed files with 42 additions and 19 deletions
@@ -21,13 +21,25 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
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.RawTypeTag
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.types.getCapability
import org.jetbrains.kotlin.utils.singletonOrEmptyList
class ErasedOverridabilityCondition : ExternalOverridabilityCondition {
override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor, subClassDescriptor: ClassDescriptor?): Result {
if (subDescriptor !is JavaMethodDescriptor) return Result.UNKNOWN
if (subDescriptor !is JavaMethodDescriptor || subDescriptor.typeParameters.isNotEmpty()) return Result.UNKNOWN
val basicOverridability = OverridingUtil.getBasicOverridabilityProblem(superDescriptor, subDescriptor)?.result
if (basicOverridability != null) return Result.UNKNOWN
val signatureTypes = subDescriptor.valueParameters.asSequence().map { it.type } +
subDescriptor.returnType!! +
subDescriptor.extensionReceiverParameter?.type.singletonOrEmptyList()
if (signatureTypes.any { it.arguments.isNotEmpty() && it.getCapability<RawTypeTag>() == null }) return Result.UNKNOWN
var erasedSuper = superDescriptor.substitute(RawSubstitution.buildSubstitutor()) ?: return Result.UNKNOWN
@@ -143,24 +143,8 @@ public class OverridingUtil {
@NotNull CallableDescriptor subDescriptor,
boolean checkReturnType
) {
if (superDescriptor instanceof FunctionDescriptor && !(subDescriptor instanceof FunctionDescriptor) ||
superDescriptor instanceof PropertyDescriptor && !(subDescriptor instanceof PropertyDescriptor)) {
return OverrideCompatibilityInfo.incompatible("Member kind mismatch");
}
if (!(superDescriptor instanceof FunctionDescriptor) && !(superDescriptor instanceof PropertyDescriptor)) {
throw new IllegalArgumentException("This type of CallableDescriptor cannot be checked for overridability: " + superDescriptor);
}
// TODO: check outside of this method
if (!superDescriptor.getName().equals(subDescriptor.getName())) {
return OverrideCompatibilityInfo.incompatible("Name mismatch");
}
OverrideCompatibilityInfo receiverAndParameterResult = checkReceiverAndParameterCount(superDescriptor, subDescriptor);
if (receiverAndParameterResult != null) {
return receiverAndParameterResult;
}
OverrideCompatibilityInfo basicOverridability = getBasicOverridabilityProblem(superDescriptor, subDescriptor);
if (basicOverridability != null) return basicOverridability;
List<KotlinType> superValueParameters = compiledValueParameters(superDescriptor);
List<KotlinType> subValueParameters = compiledValueParameters(subDescriptor);
@@ -207,6 +191,33 @@ public class OverridingUtil {
return OverrideCompatibilityInfo.success();
}
@Nullable
public static OverrideCompatibilityInfo getBasicOverridabilityProblem(
@NotNull CallableDescriptor superDescriptor,
@NotNull CallableDescriptor subDescriptor
) {
if (superDescriptor instanceof FunctionDescriptor && !(subDescriptor instanceof FunctionDescriptor) ||
superDescriptor instanceof PropertyDescriptor && !(subDescriptor instanceof PropertyDescriptor)) {
return OverrideCompatibilityInfo.incompatible("Member kind mismatch");
}
if (!(superDescriptor instanceof FunctionDescriptor) && !(superDescriptor instanceof PropertyDescriptor)) {
throw new IllegalArgumentException("This type of CallableDescriptor cannot be checked for overridability: " + superDescriptor);
}
// TODO: check outside of this method
if (!superDescriptor.getName().equals(subDescriptor.getName())) {
return OverrideCompatibilityInfo.incompatible("Name mismatch");
}
OverrideCompatibilityInfo receiverAndParameterResult = checkReceiverAndParameterCount(superDescriptor, subDescriptor);
if (receiverAndParameterResult != null) {
return receiverAndParameterResult;
}
return null;
}
@NotNull
private KotlinTypeChecker createTypeChecker(
@NotNull List<TypeParameterDescriptor> firstParameters,