@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; }
@NotNull private static Collection<CallableMemberDescriptor> extractMembersOverridableInBothWays( @NotNull CallableMemberDescriptor overrider, @NotNull Queue<CallableMemberDescriptor> extractFrom, @NotNull DescriptorSink sink) { Collection<CallableMemberDescriptor> overridable = new ArrayList<CallableMemberDescriptor>(); overridable.add(overrider); for (Iterator<CallableMemberDescriptor> iterator = extractFrom.iterator(); iterator.hasNext(); ) { CallableMemberDescriptor candidate = iterator.next(); if (overrider == candidate) { iterator.remove(); continue; } OverrideCompatibilityInfo.Result result1 = DEFAULT.isOverridableBy(candidate, overrider).getResult(); OverrideCompatibilityInfo.Result result2 = DEFAULT.isOverridableBy(overrider, candidate).getResult(); if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) { overridable.add(candidate); iterator.remove(); } else if (result1 == CONFLICT || result2 == CONFLICT) { sink.conflict(overrider, candidate); iterator.remove(); } } return overridable; }
/** * @param <H> is something that handles CallableDescriptor inside * @return */ @NotNull public static <H> Collection<H> extractMembersOverridableInBothWays( @NotNull H overrider, @NotNull @Mutable Collection<H> extractFrom, @NotNull Function1<H, CallableDescriptor> descriptorByHandle, @NotNull Function1<H, Unit> onConflict) { Collection<H> overridable = new ArrayList<H>(); overridable.add(overrider); CallableDescriptor overriderDescriptor = descriptorByHandle.invoke(overrider); for (Iterator<H> iterator = extractFrom.iterator(); iterator.hasNext(); ) { H candidate = iterator.next(); CallableDescriptor candidateDescriptor = descriptorByHandle.invoke(candidate); if (overrider == candidate) { iterator.remove(); continue; } OverrideCompatibilityInfo.Result finalResult = getBothWaysOverridability(overriderDescriptor, candidateDescriptor); if (finalResult == OVERRIDABLE) { overridable.add(candidate); iterator.remove(); } else if (finalResult == CONFLICT) { onConflict.invoke(candidate); iterator.remove(); } } return overridable; }