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