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