001    /*
002     * Copyright 2010-2016 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.resolve;
018    
019    import com.google.common.collect.Maps;
020    import com.google.common.collect.Sets;
021    import com.intellij.psi.PsiElement;
022    import com.intellij.util.SmartList;
023    import com.intellij.util.containers.ContainerUtil;
024    import com.intellij.util.containers.SmartHashSet;
025    import kotlin.Unit;
026    import kotlin.collections.CollectionsKt;
027    import kotlin.jvm.functions.Function1;
028    import org.jetbrains.annotations.NotNull;
029    import org.jetbrains.annotations.Nullable;
030    import org.jetbrains.kotlin.descriptors.*;
031    import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2;
032    import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryWithPsiElement;
033    import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
034    import org.jetbrains.kotlin.lexer.KtTokens;
035    import org.jetbrains.kotlin.psi.*;
036    import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
037    import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsKt;
038    import org.jetbrains.kotlin.types.*;
039    import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
040    
041    import java.util.*;
042    
043    import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION;
044    import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
045    import static org.jetbrains.kotlin.diagnostics.Errors.*;
046    import static org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers;
047    import static org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
048    
049    public class OverrideResolver {
050        private final BindingTrace trace;
051    
052        public OverrideResolver(@NotNull BindingTrace trace) {
053            this.trace = trace;
054        }
055    
056        public void check(@NotNull TopDownAnalysisContext c) {
057            checkVisibility(c);
058            checkOverrides(c);
059            checkParameterOverridesForAllClasses(c);
060        }
061    
062        public static void resolveUnknownVisibilities(
063                @NotNull Collection<? extends CallableMemberDescriptor> descriptors,
064                @NotNull BindingTrace trace
065        ) {
066            for (CallableMemberDescriptor descriptor : descriptors) {
067                OverridingUtil.resolveUnknownVisibilityForMember(descriptor, createCannotInferVisibilityReporter(trace));
068            }
069        }
070    
071        @NotNull
072        public static Function1<CallableMemberDescriptor, Unit> createCannotInferVisibilityReporter(@NotNull final BindingTrace trace) {
073            return new Function1<CallableMemberDescriptor, Unit>() {
074                @Override
075                public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
076                    DeclarationDescriptor reportOn;
077                    if (descriptor.getKind() == FAKE_OVERRIDE || descriptor.getKind() == DELEGATION) {
078                        reportOn = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class);
079                    }
080                    else if (descriptor instanceof PropertyAccessorDescriptor && ((PropertyAccessorDescriptor) descriptor).isDefault()) {
081                        reportOn = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
082                    }
083                    else {
084                        reportOn = descriptor;
085                    }
086                    //noinspection ConstantConditions
087                    PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(reportOn);
088                    if (element instanceof KtDeclaration) {
089                        trace.report(CANNOT_INFER_VISIBILITY.on((KtDeclaration) element, descriptor));
090                    }
091                    return Unit.INSTANCE;
092                }
093            };
094        }
095    
096    
097        private void checkOverrides(@NotNull TopDownAnalysisContext c) {
098            for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
099                checkOverridesInAClass(entry.getValue(), entry.getKey());
100            }
101        }
102    
103        private void checkOverridesInAClass(@NotNull ClassDescriptorWithResolutionScopes classDescriptor, @NotNull KtClassOrObject klass) {
104            // Check overrides for internal consistency
105            for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
106                checkOverrideForMember(member);
107            }
108    
109            CollectErrorInformationForInheritedMembersStrategy inheritedMemberErrors =
110                    new CollectErrorInformationForInheritedMembersStrategy(klass, classDescriptor);
111    
112            checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors);
113            inheritedMemberErrors.doReportErrors();
114        }
115    
116        @NotNull
117        public static Set<CallableMemberDescriptor> getMissingImplementations(@NotNull ClassDescriptor classDescriptor) {
118            CollectMissingImplementationsStrategy collector = new CollectMissingImplementationsStrategy();
119            checkInheritedAndDelegatedSignatures(classDescriptor, collector, null);
120            return collector.shouldImplement;
121        }
122    
123        private interface CheckInheritedSignaturesReportStrategy {
124            void abstractMemberNotImplemented(CallableMemberDescriptor descriptor);
125            void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor);
126            void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor);
127            void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor);
128            void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
129            void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2);
130        }
131    
132        private static class CollectMissingImplementationsStrategy implements CheckInheritedSignaturesReportStrategy {
133            private final Set<CallableMemberDescriptor> shouldImplement = new LinkedHashSet<CallableMemberDescriptor>();
134    
135            @Override
136            public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
137                shouldImplement.add(descriptor);
138            }
139    
140            @Override
141            public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
142                // don't care
143            }
144    
145            @Override
146            public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
147                shouldImplement.add(descriptor);
148            }
149    
150            @Override
151            public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
152                if (descriptor.getModality() == Modality.ABSTRACT) {
153                    shouldImplement.add(descriptor);
154                }
155            }
156    
157            @Override
158            public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
159                // don't care
160            }
161    
162            @Override
163            public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
164                // don't care
165            }
166        }
167    
168        private class CollectErrorInformationForInheritedMembersStrategy
169                implements CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy {
170            private final KtClassOrObject klass;
171            private final ClassDescriptor classDescriptor;
172    
173            private final Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
174            private final Set<CallableMemberDescriptor> multipleImplementations = Sets.newLinkedHashSet();
175            private final Set<CallableMemberDescriptor> abstractInBaseClassNoImpl = Sets.newLinkedHashSet();
176            private final Set<CallableMemberDescriptor> conflictingInterfaceMembers = Sets.newLinkedHashSet();
177            private final Set<CallableMemberDescriptor> conflictingReturnTypes = Sets.newHashSet();
178    
179            private final Set<DiagnosticFactoryWithPsiElement> onceErrorsReported = new SmartHashSet<DiagnosticFactoryWithPsiElement>();
180    
181            public CollectErrorInformationForInheritedMembersStrategy(
182                    @NotNull KtClassOrObject klass,
183                    @NotNull ClassDescriptor classDescriptor
184            ) {
185                this.klass = klass;
186                this.classDescriptor = classDescriptor;
187            }
188    
189            @Override
190            public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
191                abstractNoImpl.add(descriptor);
192            }
193    
194            @Override
195            public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
196                abstractInBaseClassNoImpl.add(descriptor);
197            }
198    
199            @Override
200            public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
201                multipleImplementations.add(descriptor);
202            }
203    
204            @Override
205            public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
206                conflictingInterfaceMembers.add(descriptor);
207            }
208    
209            @Override
210            public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
211                conflictingReturnTypes.add(descriptor1);
212                conflictingReturnTypes.add(descriptor2);
213    
214                reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
215            }
216    
217            @Override
218            public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
219                conflictingReturnTypes.add(descriptor1);
220                conflictingReturnTypes.add(descriptor2);
221    
222                if (descriptor1.isVar() || descriptor2.isVar()) {
223                    reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
224                }
225                else {
226                    reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
227                }
228            }
229    
230            private void reportInheritanceConflictIfRequired(
231                    @NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
232                    @NotNull CallableMemberDescriptor descriptor1,
233                    @NotNull CallableMemberDescriptor descriptor2
234            ) {
235                if (!onceErrorsReported.contains(diagnosticFactory)) {
236                    onceErrorsReported.add(diagnosticFactory);
237                    trace.report(diagnosticFactory.on(klass, descriptor1, descriptor2));
238                }
239            }
240    
241            @Override
242            public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
243                reportDelegationProblemIfRequired(OVERRIDING_FINAL_MEMBER_BY_DELEGATION, null, overriding, overridden);
244            }
245    
246            @Override
247            public void returnTypeMismatchOnOverride(
248                    @NotNull CallableMemberDescriptor overriding,
249                    @NotNull CallableMemberDescriptor overridden
250            ) {
251                reportDelegationProblemIfRequired(
252                        RETURN_TYPE_MISMATCH_BY_DELEGATION, RETURN_TYPE_MISMATCH_ON_INHERITANCE, overriding, overridden);
253            }
254    
255            @Override
256            public void propertyTypeMismatchOnOverride(
257                    @NotNull PropertyDescriptor overriding,
258                    @NotNull PropertyDescriptor overridden
259            ) {
260                reportDelegationProblemIfRequired(
261                        PROPERTY_TYPE_MISMATCH_BY_DELEGATION, PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, overriding, overridden);
262            }
263    
264            @Override
265            public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
266                reportDelegationProblemIfRequired(VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, null, overriding, overridden);
267            }
268    
269            private void reportDelegationProblemIfRequired(
270                    @NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
271                    @Nullable DiagnosticFactoryWithPsiElement<?, ?> relevantDiagnosticFromInheritance,
272                    @NotNull CallableMemberDescriptor delegate,
273                    @NotNull CallableMemberDescriptor overridden
274            ) {
275                assert delegate.getKind() == DELEGATION : "Delegate expected, got " + delegate + " of kind " + delegate.getKind();
276    
277                if (!onceErrorsReported.contains(diagnosticFactory) &&
278                        (relevantDiagnosticFromInheritance == null || !onceErrorsReported.contains(relevantDiagnosticFromInheritance))) {
279                    onceErrorsReported.add(diagnosticFactory);
280                    trace.report(diagnosticFactory.on(klass, delegate, overridden));
281                }
282            }
283    
284            void doReportErrors() {
285                if (!classCanHaveAbstractMembers(classDescriptor)) {
286                    if (!abstractInBaseClassNoImpl.isEmpty()) {
287                        trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.iterator().next()));
288                    }
289                    else if (!abstractNoImpl.isEmpty()) {
290                        trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()));
291                    }
292                }
293    
294                conflictingInterfaceMembers.removeAll(conflictingReturnTypes);
295                multipleImplementations.removeAll(conflictingReturnTypes);
296                if (!conflictingInterfaceMembers.isEmpty()) {
297                    trace.report(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED.on(klass, klass, conflictingInterfaceMembers.iterator().next()));
298                }
299                else if (!multipleImplementations.isEmpty()) {
300                    trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, multipleImplementations.iterator().next()));
301                }
302            }
303        }
304    
305        private static void checkInheritedAndDelegatedSignatures(
306                @NotNull ClassDescriptor classDescriptor,
307                @NotNull CheckInheritedSignaturesReportStrategy inheritedReportStrategy,
308                @Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
309        ) {
310            for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
311                if (member instanceof CallableMemberDescriptor) {
312                    checkInheritedAndDelegatedSignatures((CallableMemberDescriptor) member, inheritedReportStrategy, overrideReportStrategyForDelegates);
313                }
314            }
315        }
316    
317        private static void checkInheritedAndDelegatedSignatures(
318                @NotNull CallableMemberDescriptor descriptor,
319                @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy,
320                @Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
321        ) {
322            CallableMemberDescriptor.Kind kind = descriptor.getKind();
323            if (kind != FAKE_OVERRIDE && kind != DELEGATION) return;
324            if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
325    
326            Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
327            assert !directOverridden.isEmpty() : kind + " " + descriptor.getName().asString() + " must override something";
328    
329            // collects map from the directly overridden descriptor to the set of declarations:
330            // -- if directly overridden is not fake, the set consists of one element: this directly overridden
331            // -- if it's fake, overridden declarations (non-fake) of this descriptor are collected
332            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
333    
334            List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
335            Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = OverridingUtil.filterOutOverridden(
336                    Sets.newLinkedHashSet(allOverriddenDeclarations));
337    
338            Set<CallableMemberDescriptor> relevantDirectlyOverridden =
339                    getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
340    
341            checkInheritedDescriptorsGroup(relevantDirectlyOverridden, descriptor, reportingStrategy);
342    
343            if (kind == DELEGATION && overrideReportStrategyForDelegates != null) {
344                checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates);
345            }
346    
347            if (kind != DELEGATION) {
348                checkMissingOverridesByJava8Restrictions(relevantDirectlyOverridden, reportingStrategy);
349            }
350    
351            List<CallableMemberDescriptor> implementations = collectImplementations(relevantDirectlyOverridden);
352    
353            int numImplementations = implementations.size();
354    
355            // The most common case: there's one implementation in the supertypes with the matching return type
356            if (numImplementations == 1 && isReturnTypeOkForOverride(descriptor, implementations.get(0))) return;
357    
358            List<CallableMemberDescriptor> abstractOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
359            List<CallableMemberDescriptor> concreteOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
360            filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden);
361    
362            if (numImplementations == 0) {
363                if (kind != DELEGATION) {
364                    for (CallableMemberDescriptor member : abstractOverridden) {
365                        reportingStrategy.abstractMemberNotImplemented(member);
366                    }
367                }
368            }
369            else if (numImplementations > 1) {
370                for (CallableMemberDescriptor member : concreteOverridden) {
371                    reportingStrategy.multipleImplementationsMemberNotImplemented(member);
372                }
373            }
374            else {
375                if (kind != DELEGATION) {
376                    List<CallableMemberDescriptor> membersWithMoreSpecificReturnType =
377                            collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations.get(0));
378                    for (CallableMemberDescriptor member : membersWithMoreSpecificReturnType) {
379                        reportingStrategy.abstractMemberNotImplemented(member);
380                    }
381                }
382            }
383        }
384    
385        private static void checkMissingOverridesByJava8Restrictions(
386                @NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden,
387                @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
388        ) {
389            // Java 8:
390            // -- class should implement an abstract member of a super-class,
391            //    even if relevant default implementation is provided in one of the super-interfaces;
392            // -- inheriting multiple override equivalent methods from an interface is a conflict
393            //    regardless of 'default' vs 'abstract'.
394    
395            boolean overridesClassMember = false;
396            boolean overridesNonAbstractInterfaceMember = false;
397            CallableMemberDescriptor overridesAbstractInBaseClass = null;
398            List<CallableMemberDescriptor> overriddenInterfaceMembers = new SmartList<CallableMemberDescriptor>();
399            for (CallableMemberDescriptor overridden : relevantDirectlyOverridden) {
400                DeclarationDescriptor containingDeclaration = overridden.getContainingDeclaration();
401                if (containingDeclaration instanceof ClassDescriptor) {
402                    ClassDescriptor baseClassOrInterface = (ClassDescriptor) containingDeclaration;
403                    if (baseClassOrInterface.getKind() == ClassKind.CLASS) {
404                        overridesClassMember = true;
405                        if (overridden.getModality() == Modality.ABSTRACT) {
406                            overridesAbstractInBaseClass = overridden;
407                        }
408                    }
409                    else if (baseClassOrInterface.getKind() == ClassKind.INTERFACE) {
410                        overriddenInterfaceMembers.add(overridden);
411                        if (overridden.getModality() != Modality.ABSTRACT) {
412                            overridesNonAbstractInterfaceMember = true;
413                        }
414                    }
415                }
416            }
417    
418            if (overridesAbstractInBaseClass != null) {
419                reportingStrategy.abstractBaseClassMemberNotImplemented(overridesAbstractInBaseClass);
420            }
421            if (!overridesClassMember && overridesNonAbstractInterfaceMember && overriddenInterfaceMembers.size() > 1) {
422                for (CallableMemberDescriptor member : overriddenInterfaceMembers) {
423                    reportingStrategy.conflictingInterfaceMemberNotImplemented(member);
424                }
425            }
426        }
427    
428        @NotNull
429        private static List<CallableMemberDescriptor> collectImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
430            List<CallableMemberDescriptor> result = new ArrayList<CallableMemberDescriptor>(relevantDirectlyOverridden.size());
431            for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
432                if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
433                    result.add(overriddenDescriptor);
434                }
435            }
436            return result;
437        }
438    
439        private static void filterNotSynthesizedDescriptorsByModality(
440                @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
441                @NotNull List<CallableMemberDescriptor> abstractOverridden,
442                @NotNull List<CallableMemberDescriptor> concreteOverridden
443        ) {
444            for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
445                if (!CallResolverUtilKt.isOrOverridesSynthesized(overridden)) {
446                    if (overridden.getModality() == Modality.ABSTRACT) {
447                        abstractOverridden.add(overridden);
448                    }
449                    else {
450                        concreteOverridden.add(overridden);
451                    }
452                }
453            }
454        }
455    
456        @NotNull
457        private static List<CallableMemberDescriptor> collectAbstractMethodsWithMoreSpecificReturnType(
458                @NotNull List<CallableMemberDescriptor> abstractOverridden,
459                @NotNull final CallableMemberDescriptor implementation
460        ) {
461            return CollectionsKt.filter(abstractOverridden, new Function1<CallableMemberDescriptor, Boolean>() {
462                @Override
463                public Boolean invoke(@NotNull CallableMemberDescriptor abstractMember) {
464                    return !isReturnTypeOkForOverride(abstractMember, implementation);
465                }
466            });
467        }
468    
469        @NotNull
470        private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
471                @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
472                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
473        ) {
474            /* Let the following class hierarchy is declared:
475    
476            trait A { fun foo() = 1 }
477            trait B : A
478            trait C : A
479            trait D : A { override fun foo() = 2 }
480            trait E : B, C, D {}
481    
482            Traits B and C have fake descriptors for function foo.
483            The map 'overriddenByParent' is:
484            { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
485            This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
486            that are overridden by this descriptor.
487    
488            The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
489            In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
490            So only 'foo in D' is relevant.
491    
492            Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
493            More precisely directly overridden descriptor is not relevant if:
494            - it's declaration set is a subset of declaration set for other directly overridden descriptor
495            ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
496            - each member of it's declaration set is overridden by a member of other declaration set
497            ('foo in C' is not relevant, because 'foo in A' is overridden by 'foo in D', so 'foo in A' is not appropriate non-fake declaration for 'foo')
498    
499            For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
500            is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
501            are overridden by some other function and corresponding directly overridden descriptor is not relevant.
502            */
503    
504            for (Iterator<Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>>> iterator =
505                         overriddenByParent.entrySet().iterator(); iterator.hasNext(); ) {
506                if (!isRelevant(iterator.next().getValue(), overriddenByParent.values(), allFilteredOverriddenDeclarations)) {
507                    iterator.remove();
508                }
509            }
510            return overriddenByParent.keySet();
511        }
512    
513        private static boolean isRelevant(
514                @NotNull Set<CallableMemberDescriptor> declarationSet,
515                @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
516                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
517        ) {
518            for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
519                if (otherSet == declarationSet) continue;
520                if (otherSet.containsAll(declarationSet)) return false;
521                if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
522            }
523            return true;
524        }
525    
526        @NotNull
527        private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
528                @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
529        ) {
530            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
531            for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
532                Set<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(descriptor);
533                Set<CallableMemberDescriptor> filteredOverrides = OverridingUtil.filterOutOverridden(overriddenDeclarations);
534                overriddenDeclarationsByDirectParent.put(descriptor, new LinkedHashSet<CallableMemberDescriptor>(filteredOverrides));
535            }
536            return overriddenDeclarationsByDirectParent;
537        }
538    
539        private interface CheckOverrideReportStrategy {
540            void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
541            void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
542            void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden);
543            void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
544        }
545    
546        private interface CheckOverrideReportForDeclaredMemberStrategy extends CheckOverrideReportStrategy {
547            void nothingToOverride(@NotNull CallableMemberDescriptor overriding);
548            void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden);
549        }
550    
551        private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
552            if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
553                if (DataClassUtilsKt.isComponentLike(declared.getName())) {
554                    checkOverrideForComponentFunction(declared);
555                }
556                return;
557            }
558    
559            if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
560                return;
561            }
562    
563            final KtNamedDeclaration member = (KtNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(declared);
564            if (member == null) {
565                throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
566            }
567    
568            KtModifierList modifierList = member.getModifierList();
569            boolean hasOverrideNode = modifierList != null && modifierList.hasModifier(KtTokens.OVERRIDE_KEYWORD);
570            Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
571    
572            if (hasOverrideNode) {
573                checkOverridesForMemberMarkedOverride(declared, new CheckOverrideReportForDeclaredMemberStrategy() {
574                    private boolean finalOverriddenError = false;
575                    private boolean typeMismatchError = false;
576                    private boolean kindMismatchError = false;
577    
578                    @Override
579                    public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
580                        if (!finalOverriddenError) {
581                            finalOverriddenError = true;
582                            trace.report(OVERRIDING_FINAL_MEMBER.on(member, overridden, overridden.getContainingDeclaration()));
583                        }
584                    }
585    
586                    @Override
587                    public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
588                        if (!typeMismatchError) {
589                            typeMismatchError = true;
590                            trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
591                        }
592                    }
593    
594                    @Override
595                    public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
596                        if (!typeMismatchError) {
597                            typeMismatchError = true;
598                            if (overridden.isVar()) {
599                                trace.report(VAR_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
600                            }
601                            else {
602                                trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
603                            }
604                        }
605                    }
606    
607                    @Override
608                    public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
609                        if (!kindMismatchError) {
610                            kindMismatchError = true;
611                            trace.report(VAR_OVERRIDDEN_BY_VAL.on(member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
612                        }
613                    }
614    
615                    @Override
616                    public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
617                        trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden));
618                    }
619    
620                    @Override
621                    public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
622                        trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
623                    }
624                });
625            }
626            else if (!overriddenDescriptors.isEmpty()) {
627                CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
628                trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
629            }
630        }
631    
632        private static void checkInheritedDescriptorsGroup(
633                @NotNull Collection<CallableMemberDescriptor> inheritedDescriptors,
634                @NotNull CallableMemberDescriptor mostSpecific,
635                @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
636        ) {
637            if (inheritedDescriptors.size() > 1) {
638                PropertyDescriptor mostSpecificProperty = mostSpecific instanceof PropertyDescriptor ? (PropertyDescriptor) mostSpecific : null;
639    
640                for (CallableMemberDescriptor inheritedDescriptor : inheritedDescriptors) {
641                    if (mostSpecificProperty != null) {
642                        assert inheritedDescriptor instanceof PropertyDescriptor
643                                : inheritedDescriptor + " inherited from " + mostSpecificProperty + " is not a property";
644                        PropertyDescriptor inheritedPropertyDescriptor = (PropertyDescriptor) inheritedDescriptor;
645    
646                        if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) {
647                            reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificProperty, inheritedPropertyDescriptor);
648                        }
649                    }
650                    else if (!isReturnTypeOkForOverride(inheritedDescriptor, mostSpecific)) {
651                        reportingStrategy.returnTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor);
652                    }
653                }
654            }
655        }
656    
657        private static void checkOverridesForMemberMarkedOverride(
658                @NotNull CallableMemberDescriptor declared,
659                @NotNull CheckOverrideReportForDeclaredMemberStrategy reportError
660        ) {
661            Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
662    
663            checkOverridesForMember(declared, overriddenDescriptors, reportError);
664    
665            if (overriddenDescriptors.isEmpty()) {
666                DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
667                assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
668                ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
669    
670                CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
671                if (invisibleOverriddenDescriptor != null) {
672                    reportError.cannotOverrideInvisibleMember(declared, invisibleOverriddenDescriptor);
673                }
674                else {
675                    reportError.nothingToOverride(declared);
676                }
677            }
678        }
679    
680        private static void checkOverridesForMember(
681                @NotNull CallableMemberDescriptor memberDescriptor,
682                @NotNull Collection<? extends CallableMemberDescriptor> overriddenDescriptors,
683                @NotNull CheckOverrideReportStrategy reportError
684        ) {
685            PropertyDescriptor propertyMemberDescriptor =
686                    memberDescriptor instanceof PropertyDescriptor ? (PropertyDescriptor) memberDescriptor : null;
687    
688            for (CallableMemberDescriptor overridden : overriddenDescriptors) {
689                if (overridden == null) continue;
690    
691                if (!ModalityKt.isOverridable(overridden)) {
692                    reportError.overridingFinalMember(memberDescriptor, overridden);
693                }
694    
695                if (propertyMemberDescriptor != null) {
696                    assert overridden instanceof PropertyDescriptor : overridden + " is overridden by property " + propertyMemberDescriptor;
697                    PropertyDescriptor overriddenProperty = (PropertyDescriptor) overridden;
698                    if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) {
699                        reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty);
700                    }
701                }
702                else if (!isReturnTypeOkForOverride(overridden, memberDescriptor)) {
703                    reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden);
704                }
705    
706                if (checkPropertyKind(overridden, true) && checkPropertyKind(memberDescriptor, false)) {
707                    reportError.varOverriddenByVal(memberDescriptor, overridden);
708                }
709            }
710        }
711    
712        private static boolean isReturnTypeOkForOverride(
713                @NotNull CallableDescriptor superDescriptor,
714                @NotNull CallableDescriptor subDescriptor
715        ) {
716            TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
717            if (typeSubstitutor == null) return false;
718    
719            KotlinType superReturnType = superDescriptor.getReturnType();
720            assert superReturnType != null;
721    
722            KotlinType subReturnType = subDescriptor.getReturnType();
723            assert subReturnType != null;
724    
725            KotlinType substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE);
726            assert substitutedSuperReturnType != null;
727    
728            return KotlinTypeChecker.DEFAULT.isSubtypeOf(subReturnType, substitutedSuperReturnType);
729        }
730    
731        @Nullable
732        private static TypeSubstitutor prepareTypeSubstitutor(
733                @NotNull CallableDescriptor superDescriptor,
734                @NotNull CallableDescriptor subDescriptor
735        ) {
736            List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
737            List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
738            if (subTypeParameters.size() != superTypeParameters.size()) return null;
739    
740            ArrayList<TypeProjection> arguments = new ArrayList<TypeProjection>(subTypeParameters.size());
741            for (int i = 0; i < superTypeParameters.size(); i++) {
742                arguments.add(new TypeProjectionImpl(subTypeParameters.get(i).getDefaultType()));
743            }
744    
745            return new IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor();
746        }
747    
748        private static boolean isPropertyTypeOkForOverride(
749                @NotNull PropertyDescriptor superDescriptor,
750                @NotNull PropertyDescriptor subDescriptor
751        ) {
752            TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
753            if (typeSubstitutor == null) return false;
754    
755            KotlinType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getType(), Variance.OUT_VARIANCE);
756            assert substitutedSuperReturnType != null;
757    
758            if (superDescriptor.isVar()) {
759                return KotlinTypeChecker.DEFAULT.equalTypes(subDescriptor.getType(), substitutedSuperReturnType);
760            }
761            else {
762                return KotlinTypeChecker.DEFAULT.isSubtypeOf(subDescriptor.getType(), substitutedSuperReturnType);
763            }
764        }
765    
766        private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
767            final PsiElement dataModifier = findDataModifierForDataClass(componentFunction.getContainingDeclaration());
768    
769            checkOverridesForMember(componentFunction, componentFunction.getOverriddenDescriptors(), new CheckOverrideReportStrategy() {
770                private boolean overrideConflict = false;
771    
772                @Override
773                public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
774                    if (!overrideConflict) {
775                        overrideConflict = true;
776                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
777                    }
778                }
779    
780                @Override
781                public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
782                    if (!overrideConflict) {
783                        overrideConflict = true;
784                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
785                    }
786                }
787    
788                @Override
789                public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
790                    throw new IllegalStateException("Component functions are not properties");
791                }
792    
793                @Override
794                public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
795                    throw new IllegalStateException("Component functions are not properties");
796                }
797            });
798        }
799    
800        @NotNull
801        private static PsiElement findDataModifierForDataClass(@NotNull DeclarationDescriptor dataClass) {
802            KtClassOrObject classDeclaration = (KtClassOrObject) DescriptorToSourceUtils.getSourceFromDescriptor(dataClass);
803            if (classDeclaration != null && classDeclaration.getModifierList() != null) {
804                PsiElement modifier = classDeclaration.getModifierList().getModifier(KtTokens.DATA_KEYWORD);
805                if (modifier != null) {
806                    return modifier;
807                }
808            }
809    
810            throw new IllegalStateException("No data modifier is found for data class " + dataClass);
811        }
812    
813        @Nullable
814        private static CallableMemberDescriptor findInvisibleOverriddenDescriptor(
815                @NotNull CallableMemberDescriptor declared,
816                @NotNull ClassDescriptor declaringClass
817        ) {
818            for (KotlinType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
819                Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
820                all.addAll(supertype.getMemberScope().getContributedFunctions(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
821                //noinspection unchecked
822                all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
823                for (CallableMemberDescriptor fromSuper : all) {
824                    if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared, null).getResult() == OVERRIDABLE) {
825                        if (Visibilities.isVisibleIgnoringReceiver(fromSuper, declared)) {
826                            throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
827                                                            " and visible but does not appear in its getOverriddenDescriptors()");
828                        }
829                        return fromSuper;
830                    }
831                }
832            }
833            return null;
834        }
835    
836        private void checkParameterOverridesForAllClasses(@NotNull TopDownAnalysisContext c) {
837            for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) {
838                for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
839                    if (member instanceof CallableMemberDescriptor) {
840                        checkOverridesForParameters((CallableMemberDescriptor) member);
841                    }
842                }
843            }
844        }
845    
846        private void checkOverridesForParameters(@NotNull CallableMemberDescriptor declared) {
847            boolean isDeclaration = declared.getKind() == CallableMemberDescriptor.Kind.DECLARATION;
848            if (isDeclaration) {
849                // No check if the function is not marked as 'override'
850                KtModifierListOwner declaration = (KtModifierListOwner) DescriptorToSourceUtils.descriptorToDeclaration(declared);
851                if (declaration != null && !declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) {
852                    return;
853                }
854            }
855    
856            // Let p1 be a parameter of the overriding function
857            // Let p2 be a parameter of the function being overridden
858            // Then
859            //  a) p1 is not allowed to have a default value declared
860            //  b) p1 must have the same name as p2
861            for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
862                int defaultsInSuper = 0;
863                for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
864                    if (parameterFromSuperclass.declaresDefaultValue()) {
865                        defaultsInSuper++;
866                    }
867                }
868                boolean multipleDefaultsInSuper = defaultsInSuper > 1;
869    
870                if (isDeclaration) {
871                    checkNameAndDefaultForDeclaredParameter(parameterFromSubclass, multipleDefaultsInSuper);
872                }
873                else {
874                    checkNameAndDefaultForFakeOverrideParameter(declared, parameterFromSubclass, multipleDefaultsInSuper);
875                }
876            }
877        }
878    
879        private void checkNameAndDefaultForDeclaredParameter(@NotNull ValueParameterDescriptor descriptor, boolean multipleDefaultsInSuper) {
880            KtParameter parameter = (KtParameter) DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
881            assert parameter != null : "Declaration not found for parameter: " + descriptor;
882    
883            if (descriptor.declaresDefaultValue()) {
884                trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
885            }
886    
887            if (multipleDefaultsInSuper) {
888                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, descriptor));
889            }
890    
891            for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
892                if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
893                    //noinspection ConstantConditions
894                    trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(
895                            parameter,
896                            (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(),
897                            parameterFromSuperclass)
898                    );
899                }
900            }
901        }
902    
903        private void checkNameAndDefaultForFakeOverrideParameter(
904                @NotNull CallableMemberDescriptor containingFunction,
905                @NotNull ValueParameterDescriptor descriptor,
906                boolean multipleDefaultsInSuper
907        ) {
908            DeclarationDescriptor containingClass = containingFunction.getContainingDeclaration();
909            KtClassOrObject classElement = (KtClassOrObject) DescriptorToSourceUtils.descriptorToDeclaration(containingClass);
910            assert classElement != null : "Declaration not found for class: " + containingClass;
911    
912            if (multipleDefaultsInSuper) {
913                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, descriptor));
914            }
915    
916            for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
917                if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
918                    trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(
919                            classElement,
920                            containingFunction.getOverriddenDescriptors(),
921                            parameterFromSuperclass.getIndex() + 1)
922                    );
923                }
924            }
925        }
926    
927        public static boolean shouldReportParameterNameOverrideWarning(
928                @NotNull ValueParameterDescriptor parameterFromSubclass,
929                @NotNull ValueParameterDescriptor parameterFromSuperclass
930        ) {
931            return parameterFromSubclass.getContainingDeclaration().hasStableParameterNames() &&
932                   parameterFromSuperclass.getContainingDeclaration().hasStableParameterNames() &&
933                   !parameterFromSuperclass.getName().equals(parameterFromSubclass.getName());
934        }
935    
936        private static boolean checkPropertyKind(@NotNull CallableMemberDescriptor descriptor, boolean isVar) {
937            return descriptor instanceof PropertyDescriptor && ((PropertyDescriptor) descriptor).isVar() == isVar;
938        }
939    
940        private void checkVisibility(@NotNull TopDownAnalysisContext c) {
941            for (Map.Entry<KtCallableDeclaration, CallableMemberDescriptor> entry : c.getMembers().entrySet()) {
942                checkVisibilityForMember(entry.getKey(), entry.getValue());
943                if (entry.getKey() instanceof KtProperty && entry.getValue() instanceof PropertyDescriptor) {
944                    KtPropertyAccessor setter = ((KtProperty) entry.getKey()).getSetter();
945                    PropertySetterDescriptor setterDescriptor = ((PropertyDescriptor) entry.getValue()).getSetter();
946                    if (setter != null && setterDescriptor != null) {
947                        checkVisibilityForMember(setter, setterDescriptor);
948                    }
949                }
950            }
951        }
952    
953        private void checkVisibilityForMember(@NotNull KtDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
954            Visibility visibility = memberDescriptor.getVisibility();
955            for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
956                Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
957                if (compare == null) {
958                    trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
959                    return;
960                }
961                else if (compare < 0) {
962                    trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
963                    return;
964                }
965            }
966        }
967    }