Perform computation of overridden descriptors lazy
It's makes sense in cases when descriptors are being substituted, because in many cases their overridden are not needed.
This commit is contained in:
+34
-8
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.impl;
|
package org.jetbrains.kotlin.descriptors.impl;
|
||||||
|
|
||||||
|
import kotlin.jvm.functions.Function0;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
@@ -48,6 +49,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
|||||||
private boolean hasStableParameterNames = true;
|
private boolean hasStableParameterNames = true;
|
||||||
private boolean hasSynthesizedParameterNames = false;
|
private boolean hasSynthesizedParameterNames = false;
|
||||||
private Collection<? extends FunctionDescriptor> overriddenFunctions = null;
|
private Collection<? extends FunctionDescriptor> overriddenFunctions = null;
|
||||||
|
private volatile Function0<Set<FunctionDescriptor>> lazyOverriddenFunctionsTask = null;
|
||||||
private final FunctionDescriptor original;
|
private final FunctionDescriptor original;
|
||||||
private final Kind kind;
|
private final Kind kind;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -162,9 +164,22 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||||
|
performOverriddenLazyCalculationIfNeeded();
|
||||||
return overriddenFunctions != null ? overriddenFunctions : Collections.<FunctionDescriptor>emptyList();
|
return overriddenFunctions != null ? overriddenFunctions : Collections.<FunctionDescriptor>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void performOverriddenLazyCalculationIfNeeded() {
|
||||||
|
Function0<Set<FunctionDescriptor>> overriddenTask = lazyOverriddenFunctionsTask;
|
||||||
|
if (overriddenTask != null) {
|
||||||
|
overriddenFunctions = overriddenTask.invoke();
|
||||||
|
// Here it's important that this assignment is strictly after previous one
|
||||||
|
// `lazyOverriddenFunctionsTask` is volatile, so when someone will see that it's null,
|
||||||
|
// he can read consistent collection from `overriddenFunctions`,
|
||||||
|
// because it's assignment happens-before of "lazyOverriddenFunctionsTask = null"
|
||||||
|
lazyOverriddenFunctionsTask = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Modality getModality() {
|
public Modality getModality() {
|
||||||
@@ -443,7 +458,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
|||||||
configuration.preserveSourceElement);
|
configuration.preserveSourceElement);
|
||||||
|
|
||||||
List<TypeParameterDescriptor> substitutedTypeParameters;
|
List<TypeParameterDescriptor> substitutedTypeParameters;
|
||||||
TypeSubstitutor substitutor;
|
final TypeSubstitutor substitutor;
|
||||||
|
|
||||||
if (configuration.newTypeParameters == null) {
|
if (configuration.newTypeParameters == null) {
|
||||||
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
||||||
@@ -520,16 +535,27 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
|||||||
substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
|
substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.copyOverrides && !getOverriddenDescriptors().isEmpty()) {
|
if (configuration.copyOverrides && !getOriginal().getOverriddenDescriptors().isEmpty()) {
|
||||||
if (configuration.originalSubstitutor.isEmpty()) {
|
if (configuration.originalSubstitutor.isEmpty()) {
|
||||||
substitutedDescriptor.setOverriddenDescriptors(getOverriddenDescriptors());
|
Function0<Set<FunctionDescriptor>> overriddenFunctionsTask = lazyOverriddenFunctionsTask;
|
||||||
|
if (overriddenFunctionsTask != null) {
|
||||||
|
substitutedDescriptor.lazyOverriddenFunctionsTask = overriddenFunctionsTask;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
substitutedDescriptor.setOverriddenDescriptors(getOverriddenDescriptors());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Collection<CallableMemberDescriptor> substitutedOverridden = SmartSet.create();
|
substitutedDescriptor.lazyOverriddenFunctionsTask = new Function0<Set<FunctionDescriptor>>() {
|
||||||
for (FunctionDescriptor overriddenFunction : getOverriddenDescriptors()) {
|
@Override
|
||||||
substitutedOverridden.add(overriddenFunction.substitute(substitutor));
|
public Set<FunctionDescriptor> invoke() {
|
||||||
}
|
SmartSet<FunctionDescriptor> result = SmartSet.create();
|
||||||
substitutedDescriptor.setOverriddenDescriptors(substitutedOverridden);
|
for (FunctionDescriptor overriddenFunction : getOverriddenDescriptors()) {
|
||||||
|
result.add(overriddenFunction.substitute(substitutor));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user