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