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