Move some members from OverrideResolver to OverridingUtil

This commit is contained in:
Alexander Udalov
2016-07-22 13:41:35 +03:00
parent aaf618e035
commit d945c33d5e
9 changed files with 103 additions and 104 deletions
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
fun <Signature> generateBridgesForFunctionDescriptor(
@@ -108,8 +108,8 @@ fun findInterfaceImplementation(descriptor: CallableMemberDescriptor): CallableM
* that should be called when the given fake override is called.
*/
fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
val overridden = OverrideResolver.getOverriddenDeclarations(descriptor)
val filtered = OverrideResolver.filterOutOverridden(overridden)
val overridden = OverridingUtil.getOverriddenDeclarations(descriptor)
val filtered = OverridingUtil.filterOutOverridden(overridden)
val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null
@@ -129,6 +129,6 @@ fun firstSuperMethodFromKotlin(
): CallableMemberDescriptor? {
return descriptor.overriddenDescriptors.firstOrNull { overridden ->
overridden.modality != Modality.ABSTRACT &&
(overridden == implementation || OverrideResolver.overrides(overridden, implementation))
(overridden == implementation || OverridingUtil.overrides(overridden, implementation))
}
}
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsKt;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.utils.FunctionsKt;
import java.util.*;
@@ -95,63 +94,6 @@ public class OverrideResolver {
};
}
/**
* Given a set of descriptors, returns a set containing all the given descriptors except those which _are overridden_ by at least
* one other descriptor from the original set.
*/
@NotNull
@SuppressWarnings("unchecked")
public static <D extends CallableDescriptor> Set<D> filterOutOverridden(@NotNull Set<D> candidateSet) {
return filterOverrides(candidateSet, FunctionsKt.<CallableDescriptor>identity());
}
@NotNull
public static <D> Set<D> filterOverrides(
@NotNull Set<D> candidateSet,
@NotNull Function1<? super D, ? extends CallableDescriptor> transform
) {
if (candidateSet.size() <= 1) return candidateSet;
Set<D> result = new LinkedHashSet<D>();
outerLoop:
for (D meD : candidateSet) {
CallableDescriptor me = transform.invoke(meD);
for (Iterator<D> iterator = result.iterator(); iterator.hasNext(); ) {
D otherD = iterator.next();
CallableDescriptor other = transform.invoke(otherD);
if (overrides(me, other)) {
iterator.remove();
}
else if (overrides(other, me)) {
continue outerLoop;
}
}
result.add(meD);
}
assert !result.isEmpty() : "All candidates filtered out from " + candidateSet;
return result;
}
/**
* @return whether f overrides g
*/
public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) {
// In a multi-module project different "copies" of the same class may be present in different libraries,
// that's why we use structural equivalence for members (DescriptorEquivalenceForOverrides).
// This first check cover the case of duplicate classes in different modules:
// when B is defined in modules m1 and m2, and C (indirectly) inherits from both versions,
// we'll be getting sets of members that do not override each other, but are structurally equivalent.
// As other code relies on no equal descriptors passed here, we guard against f == g, but this may not be necessary
if (!f.equals(g) && DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent(f.getOriginal(), g.getOriginal())) return true;
CallableDescriptor originalG = g.getOriginal();
for (D overriddenFunction : DescriptorUtils.getAllOverriddenDescriptors(f)) {
if (DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent(originalG, overriddenFunction.getOriginal())) return true;
}
return false;
}
private void checkOverrides(@NotNull TopDownAnalysisContext c) {
for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
@@ -399,7 +341,7 @@ public class OverrideResolver {
Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = filterOutOverridden(
Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = OverridingUtil.filterOutOverridden(
Sets.newLinkedHashSet(allOverriddenDeclarations));
Set<CallableMemberDescriptor> relevantDirectlyOverridden =
@@ -623,42 +565,13 @@ public class OverrideResolver {
) {
Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
Set<CallableMemberDescriptor> overriddenDeclarations = getOverriddenDeclarations(descriptor);
Set<CallableMemberDescriptor> filteredOverrides = filterOutOverridden(overriddenDeclarations);
Set<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(descriptor);
Set<CallableMemberDescriptor> filteredOverrides = OverridingUtil.filterOutOverridden(overriddenDeclarations);
overriddenDeclarationsByDirectParent.put(descriptor, new LinkedHashSet<CallableMemberDescriptor>(filteredOverrides));
}
return overriddenDeclarationsByDirectParent;
}
/**
* @return overridden real descriptors (not fake overrides). Note that most usages of this method should be followed by calling
* {@link #filterOutOverridden(Set)}, because some of the declarations can override the other.
* TODO: merge this method with filterOutOverridden
*/
@NotNull
public static Set<CallableMemberDescriptor> getOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) {
Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
getOverriddenDeclarations(descriptor, result);
return result;
}
private static void getOverriddenDeclarations(
@NotNull CallableMemberDescriptor descriptor,
@NotNull Set<CallableMemberDescriptor> result
) {
if (descriptor.getKind().isReal()) {
result.add(descriptor);
}
else {
if (descriptor.getOverriddenDescriptors().isEmpty()) {
throw new IllegalStateException("No overridden descriptors found for (fake override) " + descriptor);
}
for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
getOverriddenDeclarations(overridden, result);
}
}
}
private interface CheckOverrideReportStrategy {
void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorEquivalenceForOverrides;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.OverrideResolver;
import org.jetbrains.kotlin.resolve.OverridingUtil;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext;
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode;
@@ -241,7 +241,7 @@ public class ResolutionResultsHandler {
Set<MutableResolvedCall<D>> noEquivalentCalls = filterOutEquivalentCalls(candidates);
Set<MutableResolvedCall<D>> noOverrides =
OverrideResolver.filterOverrides(noEquivalentCalls, MAP_RESOLVED_CALL_TO_RESULTING_DESCRIPTOR);
OverridingUtil.filterOverrides(noEquivalentCalls, MAP_RESOLVED_CALL_TO_RESULTING_DESCRIPTOR);
if (noOverrides.size() == 1) {
return OverloadResolutionResultsImpl.success(noOverrides.iterator().next());
}
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.checker.KotlinTypeCheckerImpl;
import org.jetbrains.kotlin.utils.FunctionsKt;
import org.jetbrains.kotlin.utils.SmartSet;
import java.util.*;
@@ -64,6 +65,91 @@ public class OverridingUtil {
equalityAxioms = axioms;
}
/**
* Given a set of descriptors, returns a set containing all the given descriptors except those which _are overridden_ by at least
* one other descriptor from the original set.
*/
@NotNull
@SuppressWarnings("unchecked")
public static <D extends CallableDescriptor> Set<D> filterOutOverridden(@NotNull Set<D> candidateSet) {
return filterOverrides(candidateSet, FunctionsKt.<CallableDescriptor>identity());
}
@NotNull
public static <D> Set<D> filterOverrides(
@NotNull Set<D> candidateSet,
@NotNull Function1<? super D, ? extends CallableDescriptor> transform
) {
if (candidateSet.size() <= 1) return candidateSet;
Set<D> result = new LinkedHashSet<D>();
outerLoop:
for (D meD : candidateSet) {
CallableDescriptor me = transform.invoke(meD);
for (Iterator<D> iterator = result.iterator(); iterator.hasNext(); ) {
D otherD = iterator.next();
CallableDescriptor other = transform.invoke(otherD);
if (overrides(me, other)) {
iterator.remove();
}
else if (overrides(other, me)) {
continue outerLoop;
}
}
result.add(meD);
}
assert !result.isEmpty() : "All candidates filtered out from " + candidateSet;
return result;
}
/**
* @return whether f overrides g
*/
public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) {
// In a multi-module project different "copies" of the same class may be present in different libraries,
// that's why we use structural equivalence for members (DescriptorEquivalenceForOverrides).
// This first check cover the case of duplicate classes in different modules:
// when B is defined in modules m1 and m2, and C (indirectly) inherits from both versions,
// we'll be getting sets of members that do not override each other, but are structurally equivalent.
// As other code relies on no equal descriptors passed here, we guard against f == g, but this may not be necessary
if (!f.equals(g) && DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent(f.getOriginal(), g.getOriginal())) return true;
CallableDescriptor originalG = g.getOriginal();
for (D overriddenFunction : DescriptorUtils.getAllOverriddenDescriptors(f)) {
if (DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent(originalG, overriddenFunction.getOriginal())) return true;
}
return false;
}
/**
* @return overridden real descriptors (not fake overrides). Note that most usages of this method should be followed by calling
* {@link #filterOutOverridden(Set)}, because some of the declarations can override the other.
*/
@NotNull
public static Set<CallableMemberDescriptor> getOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) {
Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
collectOverriddenDeclarations(descriptor, result);
return result;
}
private static void collectOverriddenDeclarations(
@NotNull CallableMemberDescriptor descriptor,
@NotNull Set<CallableMemberDescriptor> result
) {
if (descriptor.getKind().isReal()) {
result.add(descriptor);
}
else {
if (descriptor.getOverriddenDescriptors().isEmpty()) {
throw new IllegalStateException("No overridden descriptors found for (fake override) " + descriptor);
}
for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
collectOverriddenDeclarations(overridden, result);
}
}
}
@NotNull
public OverrideCompatibilityInfo isOverridableBy(
@NotNull CallableDescriptor superDescriptor,
@@ -38,7 +38,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.OverridingUtil
val KtDeclaration.descriptor: DeclarationDescriptor?
get() = this.analyze().get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
@@ -227,7 +227,7 @@ fun PsiReference.isCallableOverrideUsage(declaration: KtNamedDeclaration): Boole
when (it) {
is KtDeclaration -> {
val usageDescriptor = toDescriptor(it)
usageDescriptor != null && OverrideResolver.overrides(usageDescriptor, targetDescriptor)
usageDescriptor != null && OverridingUtil.overrides(usageDescriptor, targetDescriptor)
}
is PsiMethod -> {
declaration.toLightMethods().any { superMethod -> MethodSignatureUtil.isSuperMethod(superMethod, it) }
@@ -40,7 +40,7 @@ import java.util.Set;
import static org.jetbrains.kotlin.renderer.DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getAllOverriddenDeclarations;
import static org.jetbrains.kotlin.resolve.OverrideResolver.filterOutOverridden;
import static org.jetbrains.kotlin.resolve.OverridingUtil.filterOutOverridden;
class KotlinStructureElementPresentation implements ColoredItemPresentation, LocationPresentation {
private final TextAttributesKey attributesKey;
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
@@ -142,7 +142,7 @@ fun <D : CallableMemberDescriptor> D.getDirectlyOverriddenDeclarations(): Collec
else -> throw AssertionError("Unexpected callable kind ${overriddenDescriptor.kind}: $overriddenDescriptor")
}
}
return OverrideResolver.filterOutOverridden(result)
return OverridingUtil.filterOutOverridden(result)
}
fun <D : CallableMemberDescriptor> D.getDeepestSuperDeclarations(): Collection<D> {
@@ -20,11 +20,11 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.js.descriptorUtils.DescriptorUtilsKt;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.OverrideResolver;
import org.jetbrains.kotlin.resolve.OverridingUtil;
import java.util.Arrays;
import java.util.List;
@@ -249,7 +249,7 @@ public final class PatternBuilder {
return matches(functionDescriptor);
}
for (CallableMemberDescriptor real : OverrideResolver.getOverriddenDeclarations(functionDescriptor)) {
for (CallableMemberDescriptor real : OverridingUtil.getOverriddenDeclarations(functionDescriptor)) {
if (matches(real)) {
return true;
}