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