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