/** * @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; }
/** * Given a fake override, finds any declaration of it in the overridden descriptors. Keep in mind * that there may be many declarations of the fake override in the supertypes, this method finds * just the only one. TODO: probably all call-sites of this method are wrong, they should handle * all super-declarations */ @NotNull @SuppressWarnings("unchecked") public static <D extends CallableMemberDescriptor> D unwrapFakeOverride(@NotNull D descriptor) { while (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { Collection<? extends CallableMemberDescriptor> overridden = descriptor.getOverriddenDescriptors(); if (overridden.isEmpty()) { throw new IllegalStateException( "Fake override should have at least one overridden descriptor: " + descriptor); } descriptor = (D) overridden.iterator().next(); } return descriptor; }
private static boolean allHasSameContainingDeclaration( @NotNull Collection<CallableMemberDescriptor> notOverridden) { if (notOverridden.size() < 2) return true; final DeclarationDescriptor containingDeclaration = notOverridden.iterator().next().getContainingDeclaration(); return CollectionsKt.all( notOverridden, new Function1<CallableMemberDescriptor, Boolean>() { @Override public Boolean invoke(CallableMemberDescriptor descriptor) { return descriptor.getContainingDeclaration() == containingDeclaration; } }); }