Do not force overridden descriptors computation

Currently 'overriddenDescriptors' of substituted function is lazy
and in most cases it's unnecessary to compute it
(it's enough to use the same field from 'original')
This commit is contained in:
Denis Zharkov
2016-02-03 12:05:53 +03:00
parent 9e3d381eb3
commit 18e7272a1e
7 changed files with 17 additions and 9 deletions
@@ -77,7 +77,7 @@ fun getEffectiveVariance(parameterVariance: Variance, projectionKind: Variance):
val CallableDescriptor?.isMethodWithDeclarationSiteWildcards: Boolean
get() {
if (this !is CallableMemberDescriptor) return false
return firstOverridden {
return original.firstOverridden(useOriginal = true) {
METHODS_WITH_DECLARATION_SITE_WILDCARDS.contains(it.propertyIfAccessor.fqNameOrNull())
} != null
}
@@ -117,7 +117,7 @@ public class SamAdapterOverridabilityCondition implements ExternalOverridability
return new SamAdapterInfo(samAdapter, ownerType);
}
for (CallableMemberDescriptor overridden : samAdapter.getOverriddenDescriptors()) {
for (CallableMemberDescriptor overridden : samAdapter.getOriginal().getOverriddenDescriptors()) {
ClassDescriptor containingClass = (ClassDescriptor) overridden.getContainingDeclaration();
for (KotlinType immediateSupertype : TypeUtils.getImmediateSupertypes(ownerType)) {
@@ -99,7 +99,7 @@ private fun deprecationByOverridden(root: CallableMemberDescriptor): Deprecation
visited.add(node)
val deprecatedAnnotation = node.getDeprecationByAnnotation()
val overriddenDescriptors = node.overriddenDescriptors
val overriddenDescriptors = node.original.overriddenDescriptors
when {
deprecatedAnnotation != null -> {
deprecations.add(deprecatedAnnotation)
@@ -142,6 +142,8 @@ object BuiltinMethodsWithSpecialGenericSignature {
@JvmStatic
fun CallableMemberDescriptor.getSpecialSignatureInfo(): SpecialSignatureInfo? {
if (name !in ERASED_VALUE_PARAMETERS_SHORT_NAMES) return null
val builtinFqName = firstOverridden { it is FunctionDescriptor && it.hasErasedValueParametersInJava }?.fqNameOrNull()
?: return null
@@ -35,6 +35,12 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
@Override
FunctionDescriptor substitute(@NotNull TypeSubstitutor substitutor);
/**
* This method should be used with q Wgreat care, because if descriptor is substituted one, calling 'getOverriddenDescriptors'
* may force lazy computation, that's unnecessary in most cases.
* So, if 'getOriginal().getOverriddenDescriptors()' is enough for you, please use it instead.
* @return
*/
@Override
@NotNull
Collection<? extends FunctionDescriptor> getOverriddenDescriptors();
@@ -196,7 +196,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
public boolean isOperator() {
if (isOperator) return true;
for (FunctionDescriptor descriptor : getOverriddenDescriptors()) {
for (FunctionDescriptor descriptor : getOriginal().getOverriddenDescriptors()) {
if (descriptor.isOperator()) return true;
}
@@ -207,7 +207,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
public boolean isInfix() {
if (isInfix) return true;
for (FunctionDescriptor descriptor : getOverriddenDescriptors()) {
for (FunctionDescriptor descriptor : getOriginal().getOverriddenDescriptors()) {
if (descriptor.isInfix()) return true;
}
@@ -210,14 +210,14 @@ val CallableMemberDescriptor.propertyIfAccessor: CallableMemberDescriptor
fun CallableDescriptor.fqNameOrNull(): FqName? = fqNameUnsafe.check { it.isSafe }?.toSafe()
fun CallableMemberDescriptor.firstOverridden(
useOriginal: Boolean = false,
predicate: (CallableMemberDescriptor) -> Boolean
): CallableMemberDescriptor? {
var result: CallableMemberDescriptor? = null
return DFS.dfs(listOf(this),
object : DFS.Neighbors<CallableMemberDescriptor> {
override fun getNeighbors(current: CallableMemberDescriptor?): Iterable<CallableMemberDescriptor> {
return current?.overriddenDescriptors ?: emptyList()
}
{ current ->
val descriptor = if (useOriginal) current?.original else current
descriptor?.overriddenDescriptors ?: emptyList()
},
object : DFS.AbstractNodeHandler<CallableMemberDescriptor, CallableMemberDescriptor?>() {
override fun beforeChildren(current: CallableMemberDescriptor) = result == null