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