private static void createAndBindFakeOverride( @NotNull Collection<CallableMemberDescriptor> overridables, @NotNull ClassDescriptor current, @NotNull DescriptorSink sink) { Collection<CallableMemberDescriptor> visibleOverridables = filterVisibleFakeOverrides(current, overridables); boolean allInvisible = visibleOverridables.isEmpty(); Collection<CallableMemberDescriptor> effectiveOverridden = allInvisible ? overridables : visibleOverridables; Modality modality = getMinimalModality(effectiveOverridden); Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED; CallableMemberDescriptor mostSpecific = selectMostSpecificMemberFromSuper(effectiveOverridden); CallableMemberDescriptor fakeOverride = mostSpecific.copy( current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false); for (CallableMemberDescriptor descriptor : effectiveOverridden) { fakeOverride.addOverriddenDescriptor(descriptor); } sink.addFakeOverride(fakeOverride); }
private static void createAndBindFakeOverride( @NotNull Collection<CallableMemberDescriptor> overridables, @NotNull ClassDescriptor current, @NotNull OverridingStrategy strategy) { Collection<CallableMemberDescriptor> visibleOverridables = filterVisibleFakeOverrides(current, overridables); boolean allInvisible = visibleOverridables.isEmpty(); Collection<CallableMemberDescriptor> effectiveOverridden = allInvisible ? overridables : visibleOverridables; Modality modality = determineModality(effectiveOverridden); Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED; // FIXME doesn't work as expected for flexible types: should create a refined signature. // Current algorithm produces bad results in presence of annotated Java signatures such as: // J: foo(s: String!): String -- @NotNull String foo(String s); // K: foo(s: String): String? // --> 'foo(s: String!): String' as an inherited signature with most specific return type. // This is bad because it can be overridden by 'foo(s: String?): String', which is not // override-equivalent with K::foo above. // Should be 'foo(s: String): String'. CallableMemberDescriptor mostSpecific = selectMostSpecificMember( effectiveOverridden, new Function1<CallableMemberDescriptor, CallableDescriptor>() { @Override public CallableMemberDescriptor invoke(CallableMemberDescriptor descriptor) { return descriptor; } }); CallableMemberDescriptor fakeOverride = mostSpecific.copy( current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false); strategy.setOverriddenDescriptors(fakeOverride, effectiveOverridden); assert !fakeOverride.getOverriddenDescriptors().isEmpty() : "Overridden descriptors should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE; strategy.addFakeOverride(fakeOverride); }