Move some members from OverrideResolver to OverridingUtil
This commit is contained in:
@@ -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);
|
||||
|
||||
+2
-2
@@ -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) }
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user