001    /*
002     * Copyright 2010-2015 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.Lists;
020    import com.google.common.collect.Maps;
021    import com.google.common.collect.Sets;
022    import com.intellij.psi.PsiElement;
023    import com.intellij.util.Function;
024    import com.intellij.util.SmartList;
025    import com.intellij.util.containers.ContainerUtil;
026    import com.intellij.util.containers.LinkedMultiMap;
027    import com.intellij.util.containers.MultiMap;
028    import com.intellij.util.containers.SmartHashSet;
029    import com.intellij.util.containers.hash.EqualityPolicy;
030    import kotlin.Unit;
031    import kotlin.jvm.functions.Function1;
032    import org.jetbrains.annotations.NotNull;
033    import org.jetbrains.annotations.Nullable;
034    import org.jetbrains.annotations.ReadOnly;
035    import org.jetbrains.kotlin.descriptors.*;
036    import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2;
037    import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryWithPsiElement;
038    import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
039    import org.jetbrains.kotlin.lexer.KtTokens;
040    import org.jetbrains.kotlin.name.Name;
041    import org.jetbrains.kotlin.psi.*;
042    import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
043    import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsKt;
044    import org.jetbrains.kotlin.types.*;
045    import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
046    import org.jetbrains.kotlin.utils.HashSetUtil;
047    
048    import java.util.*;
049    
050    import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*;
051    import static org.jetbrains.kotlin.diagnostics.Errors.*;
052    import static org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers;
053    import static org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
054    
055    public class OverrideResolver {
056    
057        @NotNull private final BindingTrace trace;
058    
059        public OverrideResolver(@NotNull BindingTrace trace) {
060            this.trace = trace;
061        }
062    
063        public void check(@NotNull TopDownAnalysisContext c) {
064            checkVisibility(c);
065            checkOverrides(c);
066            checkParameterOverridesForAllClasses(c);
067        }
068    
069        public static void generateOverridesInAClass(
070                @NotNull ClassDescriptor classDescriptor,
071                @NotNull Collection<CallableMemberDescriptor> membersFromCurrent,
072                @NotNull OverridingUtil.DescriptorSink sink
073        ) {
074            List<CallableMemberDescriptor> membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor);
075            MultiMap<Name, CallableMemberDescriptor> membersFromCurrentByName = groupDescriptorsByName(membersFromCurrent);
076            MultiMap<Name, CallableMemberDescriptor> membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes);
077    
078            Set<Name> memberNames = new LinkedHashSet<Name>();
079            memberNames.addAll(membersFromSupertypesByName.keySet());
080            memberNames.addAll(membersFromCurrentByName.keySet());
081    
082            for (Name memberName : memberNames) {
083                Collection<CallableMemberDescriptor> fromSupertypes = membersFromSupertypesByName.get(memberName);
084                Collection<CallableMemberDescriptor> fromCurrent = membersFromCurrentByName.get(memberName);
085    
086                OverridingUtil.generateOverridesInFunctionGroup(memberName, fromSupertypes, fromCurrent, classDescriptor, sink);
087            }
088        }
089    
090        public static void resolveUnknownVisibilities(
091                @NotNull Collection<? extends CallableMemberDescriptor> descriptors,
092                @NotNull BindingTrace trace
093        ) {
094            for (CallableMemberDescriptor descriptor : descriptors) {
095                OverridingUtil.resolveUnknownVisibilityForMember(descriptor, createCannotInferVisibilityReporter(trace));
096            }
097        }
098    
099        @NotNull
100        public static Function1<CallableMemberDescriptor, Unit> createCannotInferVisibilityReporter(@NotNull final BindingTrace trace) {
101            return new Function1<CallableMemberDescriptor, Unit>() {
102                @Override
103                public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
104                    DeclarationDescriptor reportOn;
105                    if (descriptor.getKind() == FAKE_OVERRIDE || descriptor.getKind() == DELEGATION) {
106                        reportOn = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class);
107                    }
108                    else if (descriptor instanceof PropertyAccessorDescriptor && ((PropertyAccessorDescriptor) descriptor).isDefault()) {
109                        reportOn = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
110                    }
111                    else {
112                        reportOn = descriptor;
113                    }
114                    //noinspection ConstantConditions
115                    PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(reportOn);
116                    if (element instanceof KtDeclaration) {
117                        trace.report(CANNOT_INFER_VISIBILITY.on((KtDeclaration) element, descriptor));
118                    }
119                    return Unit.INSTANCE$;
120                }
121            };
122        }
123    
124        private static enum Filtering {
125            RETAIN_OVERRIDING,
126            RETAIN_OVERRIDDEN
127        }
128    
129        @NotNull
130        public static <D extends CallableDescriptor> Set<D> filterOutOverridden(@NotNull Set<D> candidateSet) {
131            //noinspection unchecked
132            return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDING);
133        }
134    
135        @NotNull
136        public static <D> Set<D> filterOutOverriding(@NotNull Set<D> candidateSet) {
137            //noinspection unchecked
138            return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDDEN);
139        }
140    
141        @NotNull
142        public static <D> Set<D> filterOutOverridden(
143                @NotNull Set<D> candidateSet,
144                @NotNull Function<? super D, ? extends CallableDescriptor> transform
145        ) {
146            return filterOverrides(candidateSet, transform, Filtering.RETAIN_OVERRIDING);
147        }
148    
149        @NotNull
150        private static <D> Set<D> filterOverrides(
151                @NotNull Set<D> candidateSet,
152                @NotNull final Function<? super D, ? extends CallableDescriptor> transform,
153                @NotNull Filtering filtering
154        ) {
155            if (candidateSet.size() <= 1) return candidateSet;
156    
157            // In a multi-module project different "copies" of the same class may be present in different libraries,
158            // that's why we use structural equivalence for members (DescriptorEquivalenceForOverrides).
159            // Here we filter out structurally equivalent descriptors before processing overrides, because such descriptors
160            // "override" each other (overrides(f, g) = overrides(g, f) = true) and the code below removes them all from the
161            // candidates, unless we first compute noDuplicates
162            Set<D> noDuplicates = HashSetUtil.linkedHashSet(
163                    candidateSet,
164                    new EqualityPolicy<D>() {
165                        @Override
166                        public int getHashCode(D d) {
167                            return DescriptorUtils.getFqName(transform.fun(d).getContainingDeclaration()).hashCode();
168                        }
169    
170                        @Override
171                        public boolean isEqual(D d1, D d2) {
172                            CallableDescriptor f = transform.fun(d1);
173                            CallableDescriptor g = transform.fun(d2);
174                            return DescriptorEquivalenceForOverrides.INSTANCE$.areEquivalent(f.getOriginal(), g.getOriginal());
175                        }
176                    });
177    
178            Set<D> candidates = Sets.newLinkedHashSet();
179            outerLoop:
180            for (D meD : noDuplicates) {
181                CallableDescriptor me = transform.fun(meD);
182                for (D otherD : noDuplicates) {
183                    CallableDescriptor other = transform.fun(otherD);
184                    if (me == other) continue;
185                    if (filtering == Filtering.RETAIN_OVERRIDING) {
186                        if (overrides(other, me)) {
187                            continue outerLoop;
188                        }
189                    }
190                    else if (filtering == Filtering.RETAIN_OVERRIDDEN) {
191                        if (overrides(me, other)) {
192                            continue outerLoop;
193                        }
194                    }
195                    else {
196                        throw new AssertionError("Unexpected Filtering object: " + filtering);
197                    }
198                }
199                for (D otherD : candidates) {
200                    CallableDescriptor other = transform.fun(otherD);
201                    if (me.getOriginal() == other.getOriginal()
202                        && OverridingUtil.DEFAULT.isOverridableBy(other, me, null).getResult() == OVERRIDABLE
203                        && OverridingUtil.DEFAULT.isOverridableBy(me, other, null).getResult() == OVERRIDABLE) {
204                        continue outerLoop;
205                    }
206                }
207                candidates.add(meD);
208            }
209    
210            assert !candidates.isEmpty() : "All candidates filtered out from " + candidateSet;
211    
212            return candidates;
213        }
214    
215        // check whether f overrides g
216        public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) {
217            // This first check cover the case of duplicate classes in different modules:
218            // when B is defined in modules m1 and m2, and C (indirectly) inherits from both versions,
219            // we'll be getting sets of members that do not override each other, but are structurally equivalent.
220            // As other code relies on no equal descriptors passed here, we guard against f == g, but this may not be necessary
221            if (!f.equals(g) && DescriptorEquivalenceForOverrides.INSTANCE$.areEquivalent(f.getOriginal(), g.getOriginal())) return true;
222            CallableDescriptor originalG = g.getOriginal();
223            for (D overriddenFunction : DescriptorUtils.getAllOverriddenDescriptors(f)) {
224                if (DescriptorEquivalenceForOverrides.INSTANCE$.areEquivalent(originalG, overriddenFunction.getOriginal())) return true;
225            }
226            return false;
227        }
228    
229        private static <T extends DeclarationDescriptor> MultiMap<Name, T> groupDescriptorsByName(Collection<T> properties) {
230            MultiMap<Name, T> r = new LinkedMultiMap<Name, T>();
231            for (T property : properties) {
232                r.putValue(property.getName(), property);
233            }
234            return r;
235        }
236    
237    
238        private static List<CallableMemberDescriptor> getCallableMembersFromSupertypes(ClassDescriptor classDescriptor) {
239            Set<CallableMemberDescriptor> r = Sets.newLinkedHashSet();
240            for (KotlinType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
241                r.addAll(getCallableMembersFromType(supertype));
242            }
243            return new ArrayList<CallableMemberDescriptor>(r);
244        }
245    
246        private static List<CallableMemberDescriptor> getCallableMembersFromType(KotlinType type) {
247            List<CallableMemberDescriptor> r = Lists.newArrayList();
248            for (DeclarationDescriptor decl : DescriptorUtils.getAllDescriptors(type.getMemberScope())) {
249                if (decl instanceof PropertyDescriptor || decl instanceof SimpleFunctionDescriptor) {
250                    r.add((CallableMemberDescriptor) decl);
251                }
252            }
253            return r;
254        }
255    
256        private void checkOverrides(@NotNull TopDownAnalysisContext c) {
257            for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
258                checkOverridesInAClass(entry.getValue(), entry.getKey());
259            }
260        }
261    
262        private void checkOverridesInAClass(@NotNull ClassDescriptorWithResolutionScopes classDescriptor, @NotNull final KtClassOrObject klass) {
263            // Check overrides for internal consistency
264            for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
265                checkOverrideForMember(member);
266            }
267    
268            CollectErrorInformationForInheritedMembersStrategy inheritedMemberErrors =
269                    new CollectErrorInformationForInheritedMembersStrategy(klass, classDescriptor);
270    
271            checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors);
272            inheritedMemberErrors.doReportErrors();
273        }
274    
275        @NotNull
276        public static Set<CallableMemberDescriptor> getMissingImplementations(@NotNull ClassDescriptor classDescriptor) {
277            CollectMissingImplementationsStrategy collector = new CollectMissingImplementationsStrategy();
278            checkInheritedAndDelegatedSignatures(classDescriptor, collector, null);
279            return collector.shouldImplement;
280        }
281    
282        private interface CheckInheritedSignaturesReportStrategy {
283            void abstractMemberNotImplemented(CallableMemberDescriptor descriptor);
284            void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor);
285            void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor);
286            void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor);
287            void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
288            void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2);
289        }
290    
291        private static class CollectMissingImplementationsStrategy implements CheckInheritedSignaturesReportStrategy {
292            private final Set<CallableMemberDescriptor> shouldImplement = new LinkedHashSet<CallableMemberDescriptor>();
293    
294            @Override
295            public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
296                shouldImplement.add(descriptor);
297            }
298    
299            @Override
300            public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
301                // don't care
302            }
303    
304            @Override
305            public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
306                shouldImplement.add(descriptor);
307            }
308    
309            @Override
310            public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
311                // don't care
312            }
313    
314            @Override
315            public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
316                // don't care
317            }
318    
319            @Override
320            public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
321                // don't care
322            }
323        }
324    
325        private class CollectErrorInformationForInheritedMembersStrategy
326                implements CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy {
327            private final KtClassOrObject klass;
328            private final ClassDescriptor classDescriptor;
329    
330            private final Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
331            private final Set<CallableMemberDescriptor> multipleImplementations = Sets.newLinkedHashSet();
332            private final Set<CallableMemberDescriptor> abstractInBaseClassNoImpl = Sets.newLinkedHashSet();
333            private final Set<CallableMemberDescriptor> conflictingInterfaceMembers = Sets.newLinkedHashSet();
334            private final Set<CallableMemberDescriptor> conflictingReturnTypes = Sets.newHashSet();
335    
336            private final Set<DiagnosticFactoryWithPsiElement> onceErrorsReported = new SmartHashSet<DiagnosticFactoryWithPsiElement>();
337    
338            public CollectErrorInformationForInheritedMembersStrategy(
339                    @NotNull KtClassOrObject klass,
340                    @NotNull ClassDescriptor classDescriptor
341            ) {
342                this.klass = klass;
343                this.classDescriptor = classDescriptor;
344            }
345    
346            @Override
347            public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
348                abstractNoImpl.add(descriptor);
349            }
350    
351            @Override
352            public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
353                abstractInBaseClassNoImpl.add(descriptor);
354            }
355    
356            @Override
357            public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
358                multipleImplementations.add(descriptor);
359            }
360    
361            @Override
362            public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
363                conflictingInterfaceMembers.add(descriptor);
364            }
365    
366            @Override
367            public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
368                conflictingReturnTypes.add(descriptor1);
369                conflictingReturnTypes.add(descriptor2);
370    
371                reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
372            }
373    
374            @Override
375            public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
376                conflictingReturnTypes.add(descriptor1);
377                conflictingReturnTypes.add(descriptor2);
378    
379                if (descriptor1.isVar() || descriptor2.isVar()) {
380                    reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
381                }
382                else {
383                    reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
384                }
385            }
386    
387            private void reportInheritanceConflictIfRequired(
388                    @NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
389                    @NotNull CallableMemberDescriptor descriptor1,
390                    @NotNull CallableMemberDescriptor descriptor2
391            ) {
392                if (!onceErrorsReported.contains(diagnosticFactory)) {
393                    onceErrorsReported.add(diagnosticFactory);
394                    trace.report(diagnosticFactory.on(klass, descriptor1, descriptor2));
395                }
396            }
397    
398            @Override
399            public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
400                reportDelegationProblemIfRequired(OVERRIDING_FINAL_MEMBER_BY_DELEGATION, overriding, overridden);
401            }
402    
403            @Override
404            public void returnTypeMismatchOnOverride(
405                    @NotNull CallableMemberDescriptor overriding,
406                    @NotNull CallableMemberDescriptor overridden
407            ) {
408                // Always reported as RETURN_TYPE_MISMATCH_ON_INHERITANCE
409            }
410    
411            @Override
412            public void propertyTypeMismatchOnOverride(
413                    @NotNull PropertyDescriptor overriding,
414                    @NotNull PropertyDescriptor overridden
415            ) {
416                // Always reported as PROPERTY_TYPE_MISMATCH_ON_INHERITANCE
417            }
418    
419            @Override
420            public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
421                reportDelegationProblemIfRequired(VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, overriding, overridden);
422            }
423    
424            private void reportDelegationProblemIfRequired(
425                    @NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
426                    @NotNull CallableMemberDescriptor delegate,
427                    @NotNull CallableMemberDescriptor overridden
428            ) {
429                assert delegate.getKind() == DELEGATION : "Delegate expected, got " + delegate + " of kind " + delegate.getKind();
430    
431                if (!onceErrorsReported.contains(diagnosticFactory)) {
432                    onceErrorsReported.add(diagnosticFactory);
433                    trace.report(diagnosticFactory.on(klass, delegate, overridden));
434                }
435            }
436    
437            @Override
438            public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
439                assert overriding.getKind() == DELEGATION : "Delegate expected, got " + overriding + " of kind " + overriding.getKind();
440                assert overriding.getKind() != DELEGATION : "Delegated member can't override an invisible member; " + invisibleOverridden;
441            }
442    
443            @Override
444            public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
445                assert overriding.getKind() == DELEGATION : "Delegate expected, got " + overriding + " of kind " + overriding.getKind();
446                assert overriding.getKind() != DELEGATION : "Delegated member can't override nothing; " + overriding;
447            }
448    
449            void doReportErrors() {
450                if (!classCanHaveAbstractMembers(classDescriptor)) {
451                    if (!abstractInBaseClassNoImpl.isEmpty()) {
452                        trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.iterator().next()));
453                    }
454                    else if (!abstractNoImpl.isEmpty()) {
455                        trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()));
456                    }
457                }
458    
459                conflictingInterfaceMembers.removeAll(conflictingReturnTypes);
460                multipleImplementations.removeAll(conflictingReturnTypes);
461                if (!conflictingInterfaceMembers.isEmpty()) {
462                    trace.report(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED.on(klass, klass, conflictingInterfaceMembers.iterator().next()));
463                }
464                else if (!multipleImplementations.isEmpty()) {
465                    trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, multipleImplementations.iterator().next()));
466                }
467            }
468        }
469    
470        private static void checkInheritedAndDelegatedSignatures(
471                @NotNull ClassDescriptor classDescriptor,
472                @NotNull CheckInheritedSignaturesReportStrategy inheritedReportStrategy,
473                @Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
474        ) {
475            for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
476                if (member instanceof CallableMemberDescriptor) {
477                    checkInheritedAndDelegatedSignatures((CallableMemberDescriptor) member, inheritedReportStrategy, overrideReportStrategyForDelegates);
478                }
479            }
480        }
481    
482        private static void checkInheritedAndDelegatedSignatures(
483                @NotNull CallableMemberDescriptor descriptor,
484                @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy,
485                @Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
486        ) {
487            CallableMemberDescriptor.Kind kind = descriptor.getKind();
488            if (kind != FAKE_OVERRIDE && kind != DELEGATION) return;
489            if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
490    
491            Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
492            assert !directOverridden.isEmpty() : kind + " " + descriptor.getName().asString() + " must override something";
493    
494            // collects map from the directly overridden descriptor to the set of declarations:
495            // -- if directly overridden is not fake, the set consists of one element: this directly overridden
496            // -- if it's fake, overridden declarations (non-fake) of this descriptor are collected
497            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
498    
499            List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
500            Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = filterOutOverridden(
501                    Sets.newLinkedHashSet(allOverriddenDeclarations));
502    
503            Set<CallableMemberDescriptor> relevantDirectlyOverridden =
504                    getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
505    
506            checkInheritedDescriptorsGroup(relevantDirectlyOverridden, descriptor, reportingStrategy);
507    
508            if (kind == DELEGATION && overrideReportStrategyForDelegates != null) {
509                checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates);
510            }
511    
512            if (kind != DELEGATION) {
513                checkMissingOverridesByJava8Restrictions(relevantDirectlyOverridden, reportingStrategy);
514            }
515    
516            List<CallableMemberDescriptor> implementations = collectImplementations(relevantDirectlyOverridden);
517    
518            int numImplementations = implementations.size();
519    
520            if (numImplementations == 1 && isReturnTypeOkForOverride(descriptor, implementations.get(0))) return;
521    
522            List<CallableMemberDescriptor> abstractOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
523            List<CallableMemberDescriptor> concreteOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
524            filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden);
525    
526            if (numImplementations == 0) {
527                if (kind != DELEGATION) {
528                    for (CallableMemberDescriptor member : abstractOverridden) {
529                        reportingStrategy.abstractMemberNotImplemented(member);
530                    }
531                }
532            }
533            else if (numImplementations > 1) {
534                for (CallableMemberDescriptor member : concreteOverridden) {
535                    reportingStrategy.multipleImplementationsMemberNotImplemented(member);
536                }
537            }
538            else {
539                if (kind != DELEGATION) {
540                    List<CallableMemberDescriptor> membersWithMoreSpecificReturnType =
541                            collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations.get(0));
542                    for (CallableMemberDescriptor member : membersWithMoreSpecificReturnType) {
543                        reportingStrategy.abstractMemberNotImplemented(member);
544                    }
545                }
546            }
547        }
548    
549        private static void checkMissingOverridesByJava8Restrictions(
550                @NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden,
551                @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
552        ) {
553            // Java 8:
554            // -- class should implement an abstract member of a super-class,
555            //    even if relevant default implementation is provided in one of the super-interfaces;
556            // -- inheriting multiple override equivalent methods from an interface is a conflict
557            //    regardless of 'default' vs 'abstract'.
558    
559            boolean overridesClassMember = false;
560            boolean overridesNonAbstractInterfaceMember = false;
561            CallableMemberDescriptor overridesAbstractInBaseClass = null;
562            List<CallableMemberDescriptor> overriddenInterfaceMembers = new SmartList<CallableMemberDescriptor>();
563            for (CallableMemberDescriptor overridden : relevantDirectlyOverridden) {
564                DeclarationDescriptor containingDeclaration = overridden.getContainingDeclaration();
565                if (containingDeclaration instanceof ClassDescriptor) {
566                    ClassDescriptor baseClassOrInterface = (ClassDescriptor) containingDeclaration;
567                    if (baseClassOrInterface.getKind() == ClassKind.CLASS) {
568                        overridesClassMember = true;
569                        if (overridden.getModality() == Modality.ABSTRACT) {
570                            overridesAbstractInBaseClass = overridden;
571                        }
572                    }
573                    else if (baseClassOrInterface.getKind() == ClassKind.INTERFACE) {
574                        overriddenInterfaceMembers.add(overridden);
575                        if (overridden.getModality() != Modality.ABSTRACT) {
576                            overridesNonAbstractInterfaceMember = true;
577                        }
578                    }
579                }
580            }
581    
582            if (overridesAbstractInBaseClass != null) {
583                reportingStrategy.abstractBaseClassMemberNotImplemented(overridesAbstractInBaseClass);
584            }
585            if (!overridesClassMember && overridesNonAbstractInterfaceMember && overriddenInterfaceMembers.size() > 1) {
586                for (CallableMemberDescriptor member : overriddenInterfaceMembers) {
587                    reportingStrategy.conflictingInterfaceMemberNotImplemented(member);
588                }
589            }
590        }
591    
592        @NotNull
593        private static List<CallableMemberDescriptor> collectImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
594            List<CallableMemberDescriptor> result = new ArrayList<CallableMemberDescriptor>(relevantDirectlyOverridden.size());
595            for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
596                if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
597                    result.add(overriddenDescriptor);
598                }
599            }
600            return result;
601        }
602    
603        private static void filterNotSynthesizedDescriptorsByModality(
604                @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
605                @NotNull List<CallableMemberDescriptor> abstractOverridden,
606                @NotNull List<CallableMemberDescriptor> concreteOverridden
607        ) {
608            for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
609                if (!CallResolverUtilKt.isOrOverridesSynthesized(overridden)) {
610                    if (overridden.getModality() == Modality.ABSTRACT) {
611                        abstractOverridden.add(overridden);
612                    }
613                    else {
614                        concreteOverridden.add(overridden);
615                    }
616                }
617            }
618        }
619    
620        @NotNull
621        private static List<CallableMemberDescriptor> collectAbstractMethodsWithMoreSpecificReturnType(
622                @NotNull List<CallableMemberDescriptor> abstractOverridden,
623                @NotNull CallableMemberDescriptor implementation
624        ) {
625            List<CallableMemberDescriptor> result = new ArrayList<CallableMemberDescriptor>(abstractOverridden.size());
626            for (CallableMemberDescriptor abstractMember : abstractOverridden) {
627                if (!isReturnTypeOkForOverride(abstractMember, implementation)) {
628                    result.add(abstractMember);
629                }
630            }
631            assert !result.isEmpty() : "Implementation (" + implementation + ") doesn't have the most specific type, " +
632                                       "but none of the other overridden methods does either: " + abstractOverridden;
633            return result;
634        }
635    
636        @NotNull
637        private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
638                @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
639                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
640        ) {
641            /* Let the following class hierarchy is declared:
642    
643            trait A { fun foo() = 1 }
644            trait B : A
645            trait C : A
646            trait D : A { override fun foo() = 2 }
647            trait E : B, C, D {}
648    
649            Traits B and C have fake descriptors for function foo.
650            The map 'overriddenByParent' is:
651            { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
652            This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
653            that are overridden by this descriptor.
654    
655            The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
656            In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
657            So only 'foo in D' is relevant.
658    
659            Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
660            More precisely directly overridden descriptor is not relevant if:
661            - it's declaration set is a subset of declaration set for other directly overridden descriptor
662            ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
663            - each member of it's declaration set is overridden by a member of other declaration set
664            ('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')
665    
666            For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
667            is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
668            are overridden by some other function and corresponding directly overridden descriptor is not relevant.
669            */
670    
671            for (Iterator<Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>>> iterator =
672                         overriddenByParent.entrySet().iterator(); iterator.hasNext(); ) {
673                if (!isRelevant(iterator.next().getValue(), overriddenByParent.values(), allFilteredOverriddenDeclarations)) {
674                    iterator.remove();
675                }
676            }
677            return overriddenByParent.keySet();
678        }
679    
680        private static boolean isRelevant(
681                @NotNull Set<CallableMemberDescriptor> declarationSet,
682                @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
683                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
684        ) {
685            for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
686                if (otherSet == declarationSet) continue;
687                if (otherSet.containsAll(declarationSet)) return false;
688                if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
689            }
690            return true;
691        }
692    
693        @NotNull
694        private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
695                @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
696        ) {
697            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
698            for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
699                Set<CallableMemberDescriptor> overriddenDeclarations = getOverriddenDeclarations(descriptor);
700                Set<CallableMemberDescriptor> filteredOverrides = filterOutOverridden(overriddenDeclarations);
701                overriddenDeclarationsByDirectParent.put(descriptor, new LinkedHashSet<CallableMemberDescriptor>(filteredOverrides));
702            }
703            return overriddenDeclarationsByDirectParent;
704        }
705    
706        /**
707         * @return overridden real descriptors (not fake overrides). Note that all usages of this method should be followed by calling
708         * {@link #filterOutOverridden(java.util.Set)} or {@link #filterOutOverriding(java.util.Set)}, because some of the declarations
709         * can override the other
710         * TODO: merge this method with filterOutOverridden
711         */
712        @NotNull
713        public static Set<CallableMemberDescriptor> getOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) {
714            Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
715            getOverriddenDeclarations(descriptor, result);
716            return result;
717        }
718    
719        private static void getOverriddenDeclarations(
720                @NotNull CallableMemberDescriptor descriptor,
721                @NotNull Set<CallableMemberDescriptor> result
722        ) {
723            if (descriptor.getKind().isReal()) {
724                result.add(descriptor);
725            }
726            else {
727                if (descriptor.getOverriddenDescriptors().isEmpty()) {
728                    throw new IllegalStateException("No overridden descriptors found for (fake override) " + descriptor);
729                }
730                for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
731                    getOverriddenDeclarations(overridden, result);
732                }
733            }
734        }
735    
736        private interface CheckOverrideReportStrategy {
737            void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
738            void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
739            void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden);
740            void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
741            void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden);
742            void nothingToOverride(@NotNull CallableMemberDescriptor overriding);
743        }
744    
745        private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
746            if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
747                if (DataClassUtilsKt.isComponentLike(declared.getName())) {
748                    checkOverrideForComponentFunction(declared);
749                }
750                return;
751            }
752    
753            if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
754                return;
755            }
756    
757            final KtNamedDeclaration member = (KtNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(declared);
758            if (member == null) {
759                throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
760            }
761    
762            KtModifierList modifierList = member.getModifierList();
763            boolean hasOverrideNode = modifierList != null && modifierList.hasModifier(KtTokens.OVERRIDE_KEYWORD);
764            Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
765    
766            if (hasOverrideNode) {
767                checkOverridesForMemberMarkedOverride(declared, true, new CheckOverrideReportStrategy() {
768                    private boolean finalOverriddenError = false;
769                    private boolean typeMismatchError = false;
770                    private boolean kindMismatchError = false;
771    
772                    @Override
773                    public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
774                        if (!finalOverriddenError) {
775                            finalOverriddenError = true;
776                            trace.report(OVERRIDING_FINAL_MEMBER.on(member, overridden, overridden.getContainingDeclaration()));
777                        }
778                    }
779    
780                    @Override
781                    public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
782                        if (!typeMismatchError) {
783                            typeMismatchError = true;
784                            trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
785                        }
786                    }
787    
788                    @Override
789                    public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
790                        if (!typeMismatchError) {
791                            typeMismatchError = true;
792                            if (overridden.isVar()) {
793                                trace.report(VAR_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
794                            }
795                            else {
796                                trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
797                            }
798                        }
799                    }
800    
801                    @Override
802                    public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
803                        if (!kindMismatchError) {
804                            kindMismatchError = true;
805                            trace.report(VAR_OVERRIDDEN_BY_VAL.on(member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
806                        }
807                    }
808    
809                    @Override
810                    public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
811                        trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden));
812                    }
813    
814                    @Override
815                    public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
816                        trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
817                    }
818                });
819            }
820            else if (!overriddenDescriptors.isEmpty()) {
821                CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
822                trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
823            }
824        }
825    
826        private static void checkInheritedDescriptorsGroup(
827                @NotNull Collection<CallableMemberDescriptor> inheritedDescriptors,
828                @NotNull CallableMemberDescriptor mostSpecific,
829                @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
830        ) {
831            if (inheritedDescriptors.size() > 1) {
832                PropertyDescriptor mostSpecificProperty = mostSpecific instanceof PropertyDescriptor ? (PropertyDescriptor) mostSpecific : null;
833    
834                for (CallableMemberDescriptor inheritedDescriptor : inheritedDescriptors) {
835                    if (mostSpecificProperty != null) {
836                        assert inheritedDescriptor instanceof PropertyDescriptor
837                                : inheritedDescriptor + " inherited from " + mostSpecificProperty + " is not a property";
838                        PropertyDescriptor inheritedPropertyDescriptor = (PropertyDescriptor) inheritedDescriptor;
839    
840                        if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) {
841                            reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificProperty, inheritedPropertyDescriptor);
842                        }
843                    }
844                    else if (!isReturnTypeOkForOverride(inheritedDescriptor, mostSpecific)) {
845                        reportingStrategy.returnTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor);
846                    }
847                }
848            }
849        }
850    
851        private static void checkOverridesForMemberMarkedOverride(
852                @NotNull CallableMemberDescriptor declared,
853                boolean checkIfOverridesNothing,
854                @NotNull CheckOverrideReportStrategy reportError
855        ) {
856            Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
857    
858            checkOverridesForMember(declared, overriddenDescriptors, reportError);
859    
860            if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
861                DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
862                assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
863                ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
864    
865                CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
866                if (invisibleOverriddenDescriptor != null) {
867                    reportError.cannotOverrideInvisibleMember(declared, invisibleOverriddenDescriptor);
868                }
869                else {
870                    reportError.nothingToOverride(declared);
871                }
872            }
873        }
874    
875        private static void checkOverridesForMember(
876                @NotNull CallableMemberDescriptor memberDescriptor,
877                @NotNull Collection<? extends CallableMemberDescriptor> overriddenDescriptors,
878                @NotNull CheckOverrideReportStrategy reportError
879        ) {
880            PropertyDescriptor propertyMemberDescriptor =
881                    memberDescriptor instanceof PropertyDescriptor ? (PropertyDescriptor) memberDescriptor : null;
882    
883            for (CallableMemberDescriptor overridden : overriddenDescriptors) {
884                if (overridden == null) continue;
885    
886                if (!ModalityKt.isOverridable(overridden)) {
887                    reportError.overridingFinalMember(memberDescriptor, overridden);
888                }
889    
890                if (propertyMemberDescriptor != null) {
891                    assert overridden instanceof PropertyDescriptor : overridden + " is overridden by property " + propertyMemberDescriptor;
892                    PropertyDescriptor overriddenProperty = (PropertyDescriptor) overridden;
893                    if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) {
894                        reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty);
895                    }
896                }
897                else if (!isReturnTypeOkForOverride(overridden, memberDescriptor)) {
898                    reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden);
899                }
900    
901                if (checkPropertyKind(overridden, true) && checkPropertyKind(memberDescriptor, false)) {
902                    reportError.varOverriddenByVal(memberDescriptor, overridden);
903                }
904            }
905        }
906    
907        public static boolean isReturnTypeOkForOverride(
908                @NotNull CallableDescriptor superDescriptor,
909                @NotNull CallableDescriptor subDescriptor
910        ) {
911            TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
912            if (typeSubstitutor == null) return false;
913    
914            KotlinType superReturnType = superDescriptor.getReturnType();
915            assert superReturnType != null;
916    
917            KotlinType subReturnType = subDescriptor.getReturnType();
918            assert subReturnType != null;
919    
920            KotlinType substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE);
921            assert substitutedSuperReturnType != null;
922    
923            return KotlinTypeChecker.DEFAULT.isSubtypeOf(subReturnType, substitutedSuperReturnType);
924        }
925    
926        @Nullable
927        private static TypeSubstitutor prepareTypeSubstitutor(
928                @NotNull CallableDescriptor superDescriptor,
929                @NotNull CallableDescriptor subDescriptor
930        ) {
931            List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
932            List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
933            if (subTypeParameters.size() != superTypeParameters.size()) return null;
934    
935            ArrayList<TypeProjection> arguments = new ArrayList<TypeProjection>(subTypeParameters.size());
936            for (int i = 0; i < superTypeParameters.size(); i++) {
937                arguments.add(new TypeProjectionImpl(subTypeParameters.get(i).getDefaultType()));
938            }
939    
940            return new IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor();
941        }
942    
943        public static boolean isPropertyTypeOkForOverride(
944                @NotNull PropertyDescriptor superDescriptor,
945                @NotNull PropertyDescriptor subDescriptor
946        ) {
947            TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
948            if (typeSubstitutor == null) return false;
949    
950            KotlinType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getType(), Variance.OUT_VARIANCE);
951            assert substitutedSuperReturnType != null;
952    
953            if (superDescriptor.isVar()) {
954                return KotlinTypeChecker.DEFAULT.equalTypes(subDescriptor.getType(), substitutedSuperReturnType);
955            }
956            else {
957                return KotlinTypeChecker.DEFAULT.isSubtypeOf(subDescriptor.getType(), substitutedSuperReturnType);
958            }
959        }
960    
961        private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
962            final PsiElement dataModifier = findDataModifierForDataClass(componentFunction.getContainingDeclaration());
963    
964            checkOverridesForMemberMarkedOverride(componentFunction, false, new CheckOverrideReportStrategy() {
965                private boolean overrideConflict = false;
966    
967                @Override
968                public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
969                    if (!overrideConflict) {
970                        overrideConflict = true;
971                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
972                    }
973                }
974    
975                @Override
976                public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
977                    if (!overrideConflict) {
978                        overrideConflict = true;
979                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
980                    }
981                }
982    
983                @Override
984                public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
985                    throw new IllegalStateException("Component functions are not properties");
986                }
987    
988                @Override
989                public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
990                    throw new IllegalStateException("Component functions are not properties");
991                }
992    
993                @Override
994                public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
995                    throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
996                }
997    
998                @Override
999                public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
1000                    throw new IllegalStateException("Component functions are OK to override nothing");
1001                }
1002            });
1003        }
1004    
1005        @NotNull
1006        private static PsiElement findDataModifierForDataClass(@NotNull DeclarationDescriptor dataClass) {
1007            KtClass classDeclaration = (KtClass) DescriptorToSourceUtils.getSourceFromDescriptor(dataClass);
1008            if (classDeclaration != null && classDeclaration.getModifierList() != null) {
1009                PsiElement modifier = classDeclaration.getModifierList().getModifier(KtTokens.DATA_KEYWORD);
1010                if (modifier != null) {
1011                    return modifier;
1012                }
1013            }
1014    
1015            throw new IllegalStateException("No data modifier is found for data class " + dataClass);
1016        }
1017    
1018        @Nullable
1019        private static CallableMemberDescriptor findInvisibleOverriddenDescriptor(
1020                @NotNull CallableMemberDescriptor declared,
1021                @NotNull ClassDescriptor declaringClass
1022        ) {
1023            for (KotlinType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
1024                Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
1025                all.addAll(supertype.getMemberScope().getContributedFunctions(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
1026                //noinspection unchecked
1027                all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
1028                for (CallableMemberDescriptor fromSuper : all) {
1029                    if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared, null).getResult() == OVERRIDABLE) {
1030                        if (Visibilities.isVisibleWithIrrelevantReceiver(fromSuper, declared)) {
1031                            throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
1032                                                            " and visible but does not appear in its getOverriddenDescriptors()");
1033                        }
1034                        return fromSuper;
1035                    }
1036                }
1037            }
1038            return null;
1039        }
1040    
1041        private void checkParameterOverridesForAllClasses(@NotNull TopDownAnalysisContext c) {
1042            for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) {
1043                for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
1044                    if (member instanceof CallableMemberDescriptor) {
1045                        checkOverridesForParameters((CallableMemberDescriptor) member);
1046                    }
1047                }
1048            }
1049        }
1050    
1051        private void checkOverridesForParameters(@NotNull CallableMemberDescriptor declared) {
1052            boolean isDeclaration = declared.getKind() == CallableMemberDescriptor.Kind.DECLARATION;
1053            if (isDeclaration) {
1054                // No check if the function is not marked as 'override'
1055                KtModifierListOwner declaration = (KtModifierListOwner) DescriptorToSourceUtils.descriptorToDeclaration(declared);
1056                if (declaration != null && !declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) {
1057                    return;
1058                }
1059            }
1060    
1061            // Let p1 be a parameter of the overriding function
1062            // Let p2 be a parameter of the function being overridden
1063            // Then
1064            //  a) p1 is not allowed to have a default value declared
1065            //  b) p1 must have the same name as p2
1066            for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
1067                int defaultsInSuper = 0;
1068                for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
1069                    if (parameterFromSuperclass.declaresDefaultValue()) {
1070                        defaultsInSuper++;
1071                    }
1072                }
1073                boolean multipleDefaultsInSuper = defaultsInSuper > 1;
1074    
1075                if (isDeclaration) {
1076                    checkNameAndDefaultForDeclaredParameter(parameterFromSubclass, multipleDefaultsInSuper);
1077                }
1078                else {
1079                    checkNameAndDefaultForFakeOverrideParameter(declared, parameterFromSubclass, multipleDefaultsInSuper);
1080                }
1081            }
1082        }
1083    
1084        private void checkNameAndDefaultForDeclaredParameter(@NotNull ValueParameterDescriptor descriptor, boolean multipleDefaultsInSuper) {
1085            KtParameter parameter = (KtParameter) DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
1086            assert parameter != null : "Declaration not found for parameter: " + descriptor;
1087    
1088            if (descriptor.declaresDefaultValue()) {
1089                trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
1090            }
1091    
1092            if (multipleDefaultsInSuper) {
1093                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, descriptor));
1094            }
1095    
1096            for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
1097                if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
1098                    //noinspection ConstantConditions
1099                    trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(
1100                            parameter,
1101                            (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(),
1102                            parameterFromSuperclass)
1103                    );
1104                }
1105            }
1106        }
1107    
1108        private void checkNameAndDefaultForFakeOverrideParameter(
1109                @NotNull CallableMemberDescriptor containingFunction,
1110                @NotNull ValueParameterDescriptor descriptor,
1111                boolean multipleDefaultsInSuper
1112        ) {
1113            DeclarationDescriptor containingClass = containingFunction.getContainingDeclaration();
1114            KtClassOrObject classElement = (KtClassOrObject) DescriptorToSourceUtils.descriptorToDeclaration(containingClass);
1115            assert classElement != null : "Declaration not found for class: " + containingClass;
1116    
1117            if (multipleDefaultsInSuper) {
1118                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, descriptor));
1119            }
1120    
1121            for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
1122                if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
1123                    trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(
1124                            classElement,
1125                            containingFunction.getOverriddenDescriptors(),
1126                            parameterFromSuperclass.getIndex() + 1)
1127                    );
1128                }
1129            }
1130        }
1131    
1132        public static boolean shouldReportParameterNameOverrideWarning(
1133                @NotNull ValueParameterDescriptor parameterFromSubclass,
1134                @NotNull ValueParameterDescriptor parameterFromSuperclass
1135        ) {
1136            return parameterFromSubclass.getContainingDeclaration().hasStableParameterNames() &&
1137                   parameterFromSuperclass.getContainingDeclaration().hasStableParameterNames() &&
1138                   !parameterFromSuperclass.getName().equals(parameterFromSubclass.getName());
1139        }
1140    
1141        private static boolean checkPropertyKind(@NotNull CallableMemberDescriptor descriptor, boolean isVar) {
1142            return descriptor instanceof PropertyDescriptor && ((PropertyDescriptor) descriptor).isVar() == isVar;
1143        }
1144    
1145        private void checkVisibility(@NotNull TopDownAnalysisContext c) {
1146            for (Map.Entry<KtCallableDeclaration, CallableMemberDescriptor> entry : c.getMembers().entrySet()) {
1147                checkVisibilityForMember(entry.getKey(), entry.getValue());
1148                if (entry.getKey() instanceof KtProperty && entry.getValue() instanceof PropertyDescriptor) {
1149                    KtPropertyAccessor setter = ((KtProperty) entry.getKey()).getSetter();
1150                    PropertySetterDescriptor setterDescriptor = ((PropertyDescriptor) entry.getValue()).getSetter();
1151                    if (setter != null && setterDescriptor != null) {
1152                        checkVisibilityForMember(setter, setterDescriptor);
1153                    }
1154                }
1155            }
1156        }
1157    
1158        private void checkVisibilityForMember(@NotNull KtDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
1159            Visibility visibility = memberDescriptor.getVisibility();
1160            for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
1161                Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
1162                if (compare == null) {
1163                    trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
1164                    return;
1165                }
1166                else if (compare < 0) {
1167                    trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
1168                    return;
1169                }
1170            }
1171        }
1172    
1173        @NotNull
1174        public static <D extends CallableMemberDescriptor> Collection<D> getDirectlyOverriddenDeclarations(@NotNull D descriptor) {
1175            Set<D> result = new LinkedHashSet<D>();
1176            //noinspection unchecked
1177            for (D overriddenDescriptor : (Collection<D>) descriptor.getOverriddenDescriptors()) {
1178                CallableMemberDescriptor.Kind kind = overriddenDescriptor.getKind();
1179                if (kind == DECLARATION) {
1180                    result.add(overriddenDescriptor);
1181                }
1182                else if (kind == FAKE_OVERRIDE || kind == DELEGATION) {
1183                    result.addAll(getDirectlyOverriddenDeclarations(overriddenDescriptor));
1184                }
1185                else if (kind == SYNTHESIZED) {
1186                    //do nothing
1187                }
1188                else {
1189                    throw new AssertionError("Unexpected callable kind " + kind);
1190                }
1191            }
1192            return filterOutOverridden(result);
1193        }
1194    
1195        @NotNull
1196        @ReadOnly
1197        public static <D extends CallableMemberDescriptor> Set<D> getDeepestSuperDeclarations(@NotNull D functionDescriptor) {
1198            Set<D> overriddenDeclarations = DescriptorUtils.getAllOverriddenDeclarations(functionDescriptor);
1199            if (overriddenDeclarations.isEmpty()) {
1200                return Collections.singleton(functionDescriptor);
1201            }
1202    
1203            return filterOutOverriding(overriddenDeclarations);
1204        }
1205    }