@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; }
private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember( @NotNull CallableMemberDescriptor fromCurrent, @NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper, @NotNull ClassDescriptor current, @NotNull DescriptorSink sink) { Collection<CallableMemberDescriptor> bound = new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size()); for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) { OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent).getResult(); boolean isVisible = Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSupertype, current); switch (result) { case OVERRIDABLE: if (isVisible) { fromCurrent.addOverriddenDescriptor(fromSupertype); } bound.add(fromSupertype); break; case CONFLICT: if (isVisible) { sink.conflict(fromSupertype, fromCurrent); } bound.add(fromSupertype); break; case INCOMPATIBLE: break; } } return bound; }
/** * @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; }
@NotNull public static <H> H selectMostSpecificMember( @NotNull Collection<H> overridables, @NotNull Function1<H, CallableDescriptor> descriptorByHandle) { assert !overridables.isEmpty() : "Should have at least one overridable descriptor"; if (overridables.size() == 1) { return CollectionsKt.first(overridables); } Collection<H> candidates = new ArrayList<H>(2); List<CallableDescriptor> callableMemberDescriptors = CollectionsKt.map(overridables, descriptorByHandle); H transitivelyMostSpecific = CollectionsKt.first(overridables); CallableDescriptor transitivelyMostSpecificDescriptor = descriptorByHandle.invoke(transitivelyMostSpecific); for (H overridable : overridables) { CallableDescriptor descriptor = descriptorByHandle.invoke(overridable); if (isMoreSpecificThenAllOf(descriptor, callableMemberDescriptors)) { candidates.add(overridable); } if (isMoreSpecific(descriptor, transitivelyMostSpecificDescriptor) && !isMoreSpecific(transitivelyMostSpecificDescriptor, descriptor)) { transitivelyMostSpecific = overridable; } } if (candidates.isEmpty()) { return transitivelyMostSpecific; } else if (candidates.size() == 1) { return CollectionsKt.first(candidates); } H firstNonFlexible = null; for (H candidate : candidates) { //noinspection ConstantConditions if (!FlexibleTypesKt.isFlexible(descriptorByHandle.invoke(candidate).getReturnType())) { firstNonFlexible = candidate; break; } } if (firstNonFlexible != null) { return firstNonFlexible; } return CollectionsKt.first(candidates); }
private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember( @NotNull CallableMemberDescriptor fromCurrent, @NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper, @NotNull ClassDescriptor current, @NotNull OverridingStrategy strategy) { Collection<CallableMemberDescriptor> bound = new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size()); Collection<CallableMemberDescriptor> overridden = SmartSet.create(); for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) { OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent, current).getResult(); boolean isVisibleForOverride = isVisibleForOverride(fromCurrent, fromSupertype); switch (result) { case OVERRIDABLE: if (isVisibleForOverride) { overridden.add(fromSupertype); } bound.add(fromSupertype); break; case CONFLICT: if (isVisibleForOverride) { strategy.overrideConflict(fromSupertype, fromCurrent); } bound.add(fromSupertype); break; case INCOMPATIBLE: break; } } strategy.setOverriddenDescriptors(fromCurrent, overridden); return bound; }