001    /*
002     * Copyright 2010-2013 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.jet.lang.resolve;
018    
019    import com.google.common.collect.Lists;
020    import com.google.common.collect.Maps;
021    import com.google.common.collect.Sets;
022    import com.intellij.lang.ASTNode;
023    import com.intellij.psi.PsiElement;
024    import com.intellij.util.containers.ContainerUtil;
025    import com.intellij.util.containers.LinkedMultiMap;
026    import com.intellij.util.containers.MultiMap;
027    import kotlin.KotlinPackage;
028    import org.jetbrains.annotations.NotNull;
029    import org.jetbrains.jet.lang.descriptors.*;
030    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
031    import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
032    import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite;
033    import org.jetbrains.jet.lang.diagnostics.Errors;
034    import org.jetbrains.jet.lang.psi.*;
035    import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
036    import org.jetbrains.jet.lang.resolve.name.Name;
037    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
038    import org.jetbrains.jet.lang.types.JetType;
039    import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
040    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
041    import org.jetbrains.jet.lexer.JetTokens;
042    
043    import javax.inject.Inject;
044    import java.util.*;
045    
046    import static org.jetbrains.jet.lang.diagnostics.Errors.*;
047    import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
048    
049    public class OverrideResolver {
050    
051        private BindingTrace trace;
052    
053        @Inject
054        public void setTrace(BindingTrace trace) {
055            this.trace = trace;
056        }
057    
058    
059    
060        public void process(@NotNull TopDownAnalysisContext c) {
061            //all created fake descriptors are stored to resolve visibility on them later
062            generateOverridesAndDelegation(c);
063    
064            checkVisibility(c);
065            checkOverrides(c);
066            checkParameterOverridesForAllClasses(c);
067        }
068    
069        /**
070         * Generate fake overrides and add overridden descriptors to existing descriptors.
071         */
072        private void generateOverridesAndDelegation(@NotNull TopDownAnalysisContext c) {
073            Set<ClassDescriptorWithResolutionScopes> ourClasses = new HashSet<ClassDescriptorWithResolutionScopes>(c.getClasses().values());
074            Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>();
075    
076            for (MutableClassDescriptorLite klass : ContainerUtil.reverse(c.getClassesTopologicalOrder())) {
077                if (klass instanceof MutableClassDescriptor && ourClasses.contains(klass)) {
078                    generateOverridesAndDelegationInAClass((MutableClassDescriptor) klass, processed, ourClasses);
079    
080                    MutableClassDescriptorLite classObject = klass.getClassObjectDescriptor();
081                    if (classObject instanceof MutableClassDescriptor) {
082                        generateOverridesAndDelegationInAClass((MutableClassDescriptor) classObject, processed, ourClasses);
083                    }
084                }
085            }
086        }
087    
088        private void generateOverridesAndDelegationInAClass(
089                @NotNull MutableClassDescriptor classDescriptor,
090                @NotNull Set<ClassifierDescriptor> processed,
091                @NotNull Set<ClassDescriptorWithResolutionScopes> classesBeingAnalyzed
092                // to filter out classes such as stdlib and others that come from dependencies
093        ) {
094            if (!processed.add(classDescriptor)) {
095                return;
096            }
097    
098            for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
099                ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
100                if (superclass instanceof MutableClassDescriptor && classesBeingAnalyzed.contains(superclass)) {
101                    generateOverridesAndDelegationInAClass((MutableClassDescriptor) superclass, processed, classesBeingAnalyzed);
102                }
103            }
104    
105            JetClassOrObject classOrObject = (JetClassOrObject) BindingContextUtils
106                    .classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
107            if (classOrObject != null) {
108                DelegationResolver.generateDelegatesInAClass(classDescriptor, trace, classOrObject);
109            }
110    
111            generateOverridesInAClass(classDescriptor);
112        }
113    
114        private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor) {
115            List<CallableMemberDescriptor> membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor);
116    
117            MultiMap<Name, CallableMemberDescriptor> membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes);
118    
119            MultiMap<Name, CallableMemberDescriptor> membersFromCurrentByName = groupDescriptorsByName(classDescriptor.getDeclaredCallableMembers());
120    
121            Set<Name> memberNames = new LinkedHashSet<Name>();
122            memberNames.addAll(membersFromSupertypesByName.keySet());
123            memberNames.addAll(membersFromCurrentByName.keySet());
124    
125            for (Name memberName : memberNames) {
126                Collection<CallableMemberDescriptor> fromSupertypes = membersFromSupertypesByName.get(memberName);
127                Collection<CallableMemberDescriptor> fromCurrent = membersFromCurrentByName.get(memberName);
128    
129                OverridingUtil.generateOverridesInFunctionGroup(
130                        memberName,
131                        fromSupertypes,
132                        fromCurrent,
133                        classDescriptor,
134                        new OverridingUtil.DescriptorSink() {
135                            @Override
136                            public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
137                                if (fakeOverride instanceof PropertyDescriptor) {
138                                    classDescriptor.getBuilder().addPropertyDescriptor((PropertyDescriptor) fakeOverride);
139                                }
140                                else if (fakeOverride instanceof SimpleFunctionDescriptor) {
141                                    classDescriptor.getBuilder().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
142                                }
143                                else {
144                                    throw new IllegalStateException(fakeOverride.getClass().getName());
145                                }
146                            }
147    
148                            @Override
149                            public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
150                                JetDeclaration declaration = (JetDeclaration) BindingContextUtils
151                                        .descriptorToDeclaration(trace.getBindingContext(), fromCurrent);
152                                trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString()));
153                            }
154                        });
155            }
156            resolveUnknownVisibilities(classDescriptor.getAllCallableMembers(), trace);
157        }
158    
159        public static void resolveUnknownVisibilities(
160                @NotNull Collection<? extends CallableMemberDescriptor> descriptors,
161                @NotNull BindingTrace trace) {
162            for (CallableMemberDescriptor descriptor : descriptors) {
163                resolveUnknownVisibilityForMember(descriptor, trace);
164            }
165        }
166    
167        public static void resolveUnknownVisibilityForMember(@NotNull CallableMemberDescriptor descriptor, @NotNull final BindingTrace trace) {
168            OverridingUtil.resolveUnknownVisibilityForMember(descriptor, new OverridingUtil.NotInferredVisibilitySink() {
169                @Override
170                public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
171                    PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor);
172                    if (element instanceof JetDeclaration) {
173                        trace.report(CANNOT_INFER_VISIBILITY.on((JetDeclaration) element));
174                    }
175                }
176            });
177        }
178    
179        private static <T extends DeclarationDescriptor> MultiMap<Name, T> groupDescriptorsByName(Collection<T> properties) {
180            MultiMap<Name, T> r = new LinkedMultiMap<Name, T>();
181            for (T property : properties) {
182                r.putValue(property.getName(), property);
183            }
184            return r;
185        }
186    
187    
188        private static List<CallableMemberDescriptor> getCallableMembersFromSupertypes(ClassDescriptor classDescriptor) {
189            Set<CallableMemberDescriptor> r = Sets.newLinkedHashSet();
190            for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
191                r.addAll(getCallableMembersFromType(supertype.getMemberScope()));
192            }
193            return new ArrayList<CallableMemberDescriptor>(r);
194        }
195    
196        private static List<CallableMemberDescriptor> getCallableMembersFromType(JetScope scope) {
197            List<CallableMemberDescriptor> r = Lists.newArrayList();
198            for (DeclarationDescriptor decl : scope.getAllDescriptors()) {
199                if (decl instanceof PropertyDescriptor || decl instanceof SimpleFunctionDescriptor) {
200                    r.add((CallableMemberDescriptor) decl);
201                }
202            }
203            return r;
204        }
205    
206        private void checkOverrides(@NotNull TopDownAnalysisContext c) {
207            for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getClasses().entrySet()) {
208                checkOverridesInAClass(c, (MutableClassDescriptor) entry.getValue(), entry.getKey());
209            }
210        }
211    
212        private void checkOverridesInAClass(@NotNull TopDownAnalysisContext c, @NotNull MutableClassDescriptor classDescriptor, @NotNull JetClassOrObject klass) {
213            if (c.getTopDownAnalysisParameters().isAnalyzingBootstrapLibrary()) return;
214    
215            // Check overrides for internal consistency
216            for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
217                checkOverrideForMember(member);
218            }
219    
220            // Check if everything that must be overridden, actually is
221            // More than one implementation or no implementations at all
222            Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
223            Set<CallableMemberDescriptor> manyImpl = Sets.newLinkedHashSet();
224            collectMissingImplementations(classDescriptor, abstractNoImpl, manyImpl);
225    
226            PsiElement nameIdentifier = null;
227            if (klass instanceof JetClass) {
228                nameIdentifier = klass.getNameIdentifier();
229            }
230            else if (klass instanceof JetObjectDeclaration) {
231                nameIdentifier = klass.getNameIdentifier();
232                if (nameIdentifier == null) {
233                    nameIdentifier = ((JetObjectDeclaration) klass).getObjectKeyword();
234                }
235            }
236            if (nameIdentifier == null) return;
237    
238            for (CallableMemberDescriptor memberDescriptor : manyImpl) {
239                trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor));
240                break;
241            }
242    
243    
244            if (classDescriptor.getModality() == Modality.ABSTRACT) {
245                return;
246            }
247    
248            for (CallableMemberDescriptor memberDescriptor : abstractNoImpl) {
249                trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor));
250                break;
251            }
252        }
253    
254        public static void collectMissingImplementations(
255                MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl
256        ) {
257            for (CallableMemberDescriptor descriptor : classDescriptor.getAllCallableMembers()) {
258                collectMissingImplementations(descriptor, abstractNoImpl, manyImpl);
259            }
260        }
261    
262        public static void collectMissingImplementations(
263                ClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl
264        ) {
265            Iterator<CallableMemberDescriptor> callableMembers = KotlinPackage.filterIsInstance(
266                    classDescriptor.getDefaultType().getMemberScope().getAllDescriptors().iterator(), CallableMemberDescriptor.class
267            );
268            while (callableMembers.hasNext()) {
269                collectMissingImplementations(callableMembers.next(), abstractNoImpl, manyImpl);
270            }
271        }
272    
273        private static void collectMissingImplementations(
274                @NotNull CallableMemberDescriptor descriptor,
275                @NotNull Set<CallableMemberDescriptor> abstractNoImpl,
276                @NotNull Set<CallableMemberDescriptor> manyImpl
277        ) {
278            if (descriptor.getKind().isReal()) return;
279            if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
280    
281            Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
282            if (directOverridden.size() == 0) {
283                throw new IllegalStateException("A 'fake override' must override something");
284            }
285    
286            // collects map from the directly overridden descriptor to the set of declarations:
287            // -- if directly overridden is not fake, the set consists of one element: this directly overridden
288            // -- if it's fake, overridden declarations (non-fake) of this descriptor are collected
289            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
290    
291            List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
292            Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = OverridingUtil.filterOutOverridden(
293                    Sets.newLinkedHashSet(allOverriddenDeclarations));
294    
295            Set<CallableMemberDescriptor> relevantDirectlyOverridden =
296                    getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
297    
298            int implCount = countImplementations(relevantDirectlyOverridden);
299            if (implCount == 0) {
300                collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractNoImpl, Modality.ABSTRACT);
301            }
302            else if (implCount > 1) {
303                collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, manyImpl, Modality.OPEN, Modality.FINAL);
304            }
305        }
306    
307        private static int countImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
308            int implCount = 0;
309            for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
310                if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
311                    implCount++;
312                }
313            }
314            return implCount;
315        }
316    
317        private static void collectNotSynthesizedDescriptorsByModality(
318                @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
319                @NotNull Set<CallableMemberDescriptor> result,
320                Modality... modalities
321        ) {
322            Set<Modality> modalitySet = Sets.newHashSet(modalities);
323            for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
324                if (modalitySet.contains(overridden.getModality())) {
325                    if (!CallResolverUtil.isOrOverridesSynthesized(overridden)) {
326                        result.add(overridden);
327                    }
328                }
329            }
330        }
331    
332        @NotNull
333        private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
334                @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
335                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
336        ) {
337            /* Let the following class hierarchy is declared:
338    
339            trait A { fun foo() = 1 }
340            trait B : A
341            trait C : A
342            trait D : A { override fun foo() = 2 }
343            trait E : B, C, D {}
344    
345            Traits B and C have fake descriptors for function foo.
346            The map 'overriddenByParent' is:
347            { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
348            This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
349            that are overridden by this descriptor.
350    
351            The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
352            In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
353            So only 'foo in D' is relevant.
354    
355            Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
356            More precisely directly overridden descriptor is not relevant if:
357            - it's declaration set is a subset of declaration set for other directly overridden descriptor
358            ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
359            - each member of it's declaration set is overridden by a member of other declaration set
360            ('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')
361    
362            For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
363            is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
364            are overridden by some other function and corresponding directly overridden descriptor is not relevant.
365            */
366    
367            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> relevantOverriddenByParent = Maps.newLinkedHashMap(overriddenByParent);
368    
369            for (Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>> entry : overriddenByParent.entrySet()) {
370                CallableMemberDescriptor directlyOverridden = entry.getKey();
371                Set<CallableMemberDescriptor> declarationSet = entry.getValue();
372                if (!isRelevant(declarationSet, relevantOverriddenByParent.values(), allFilteredOverriddenDeclarations)) {
373                    relevantOverriddenByParent.remove(directlyOverridden);
374                }
375            }
376            return relevantOverriddenByParent.keySet();
377        }
378    
379        private static boolean isRelevant(
380                @NotNull Set<CallableMemberDescriptor> declarationSet,
381                @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
382                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
383        ) {
384            for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
385                if (otherSet == declarationSet) continue;
386                if (otherSet.containsAll(declarationSet)) return false;
387                if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
388            }
389            return true;
390        }
391    
392        @NotNull
393        private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
394                @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
395        ) {
396            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
397            for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
398                Collection<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(descriptor);
399                Set<CallableMemberDescriptor> filteredOverrides = OverridingUtil.filterOutOverridden(
400                        Sets.newLinkedHashSet(overriddenDeclarations));
401                Set<CallableMemberDescriptor> overridden = Sets.newLinkedHashSet();
402                for (CallableMemberDescriptor memberDescriptor : filteredOverrides) {
403                    overridden.add(memberDescriptor);
404                }
405                overriddenDeclarationsByDirectParent.put(descriptor, overridden);
406            }
407            return overriddenDeclarationsByDirectParent;
408        }
409    
410        private interface CheckOverrideReportStrategy {
411            void overridingFinalMember(@NotNull CallableMemberDescriptor overridden);
412    
413            void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
414    
415            void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
416    
417            void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden);
418    
419            void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden);
420    
421            void nothingToOverride();
422        }
423    
424        private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
425            if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
426                // TODO: this should be replaced soon by a framework of synthesized member generation tools
427                if (declared.getName().asString().startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX)) {
428                    checkOverrideForComponentFunction(declared);
429                }
430                return;
431            }
432    
433            if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
434                return;
435            }
436    
437            final JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
438            if (member == null) {
439                throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
440            }
441    
442            JetModifierList modifierList = member.getModifierList();
443            final ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
444            Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
445    
446            if (overrideNode != null) {
447                checkOverridesForMemberMarkedOverride(declared, true, new CheckOverrideReportStrategy() {
448                    private boolean finalOverriddenError = false;
449                    private boolean typeMismatchError = false;
450                    private boolean kindMismatchError = false;
451    
452                    @Override
453                    public void overridingFinalMember( @NotNull CallableMemberDescriptor overridden) {
454                        if (!finalOverriddenError) {
455                            finalOverriddenError = true;
456                            trace.report(OVERRIDING_FINAL_MEMBER.on(overrideNode.getPsi(), overridden, overridden.getContainingDeclaration()));
457                        }
458                    }
459    
460                    @Override
461                    public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
462                        if (!typeMismatchError) {
463                            typeMismatchError = true;
464                            trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
465                        }
466                    }
467    
468                    @Override
469                    public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
470                        if (!typeMismatchError) {
471                            typeMismatchError = true;
472                            trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
473                        }
474                    }
475    
476                    @Override
477                    public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
478                        if (!kindMismatchError) {
479                            kindMismatchError = true;
480                            trace.report(VAR_OVERRIDDEN_BY_VAL.on((JetProperty) member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
481                        }
482                    }
483    
484                    @Override
485                    public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
486                        trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden, invisibleOverridden.getContainingDeclaration()));
487                    }
488    
489                    @Override
490                    public void nothingToOverride() {
491                        trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
492                    }
493                });
494            }
495            else if (!overriddenDescriptors.isEmpty()) {
496                CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
497                trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
498            }
499        }
500    
501        private void checkOverridesForMemberMarkedOverride(
502                @NotNull CallableMemberDescriptor declared,
503                boolean checkIfOverridesNothing,
504                @NotNull CheckOverrideReportStrategy reportError
505        ) {
506            Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
507    
508            for (CallableMemberDescriptor overridden : overriddenDescriptors) {
509                if (overridden != null) {
510                    if (!overridden.getModality().isOverridable()) {
511                        reportError.overridingFinalMember(overridden);
512                    }
513    
514                    if (declared instanceof PropertyDescriptor && !OverridingUtil.isPropertyTypeOkForOverride(
515                            JetTypeChecker.INSTANCE, (PropertyDescriptor) overridden, (PropertyDescriptor) declared)) {
516                        reportError.propertyTypeMismatchOnOverride(overridden);
517                    }
518                    else if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, overridden, declared)) {
519                        reportError.returnTypeMismatchOnOverride(overridden);
520                    }
521    
522                    if (checkPropertyKind(overridden, true) && checkPropertyKind(declared, false)) {
523                        reportError.varOverriddenByVal(overridden);
524                    }
525                }
526            }
527    
528            if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
529                DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
530                assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
531                ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
532    
533                CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
534                if (invisibleOverriddenDescriptor != null) {
535                    reportError.cannotOverrideInvisibleMember(invisibleOverriddenDescriptor);
536                }
537                else {
538                    reportError.nothingToOverride();
539                }
540            }
541        }
542    
543        private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
544            final JetAnnotationEntry dataAnnotation = findDataAnnotationForDataClass(componentFunction.getContainingDeclaration());
545    
546            checkOverridesForMemberMarkedOverride(componentFunction, false, new CheckOverrideReportStrategy() {
547                private boolean overrideConflict = false;
548    
549                @Override
550                public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
551                    if (!overrideConflict) {
552                        overrideConflict = true;
553                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
554                    }
555                }
556    
557                @Override
558                public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
559                    if (!overrideConflict) {
560                        overrideConflict = true;
561                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
562                    }
563                }
564    
565                @Override
566                public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
567                    throw new IllegalStateException("Component functions are not properties");
568                }
569    
570                @Override
571                public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
572                    throw new IllegalStateException("Component functions are not properties");
573                }
574    
575                @Override
576                public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
577                    throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
578                }
579    
580                @Override
581                public void nothingToOverride() {
582                    throw new IllegalStateException("Component functions are OK to override nothing");
583                }
584            });
585        }
586    
587        @NotNull
588        private JetAnnotationEntry findDataAnnotationForDataClass(@NotNull DeclarationDescriptor dataClass) {
589            ClassDescriptor stdDataClassAnnotation = KotlinBuiltIns.getInstance().getDataClassAnnotation();
590            AnnotationDescriptor annotation = dataClass.getAnnotations().findAnnotation(DescriptorUtils.getFqNameSafe(stdDataClassAnnotation));
591            if (annotation == null) {
592                throw new IllegalStateException("No data annotation is found for data class " + dataClass);
593            }
594            return BindingContextUtils.getNotNull(trace.getBindingContext(),
595                                                  BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT,
596                                                  annotation);
597        }
598    
599        private CallableMemberDescriptor findInvisibleOverriddenDescriptor(CallableMemberDescriptor declared, ClassDescriptor declaringClass) {
600            CallableMemberDescriptor invisibleOverride = null;
601            outer:
602            for (JetType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
603                Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
604                all.addAll(supertype.getMemberScope().getFunctions(declared.getName()));
605                all.addAll((Collection) supertype.getMemberScope().getProperties(declared.getName()));
606                for (CallableMemberDescriptor fromSuper : all) {
607                    if (OverridingUtil.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) {
608                        invisibleOverride = fromSuper;
609                        if (Visibilities.isVisible(fromSuper, declared)) {
610                            throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared + " and visible but does not appear in its getOverriddenDescriptors()");
611                        }
612                        break outer;
613                    }
614                }
615            }
616            return invisibleOverride;
617        }
618    
619        private void checkParameterOverridesForAllClasses(@NotNull TopDownAnalysisContext c) {
620            for (ClassDescriptorWithResolutionScopes classDescriptor : c.getClasses().values()) {
621                for (DeclarationDescriptor member : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
622                    if (member instanceof CallableMemberDescriptor) {
623                        checkOverridesForParameters((CallableMemberDescriptor) member);
624                    }
625                }
626            }
627        }
628    
629        private void checkOverridesForParameters(@NotNull CallableMemberDescriptor declared) {
630            boolean noDeclaration = declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION;
631            if (!noDeclaration) {
632                // No check if the function is not marked as 'override'
633                JetModifierListOwner declaration =
634                        (JetModifierListOwner) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
635                if (!declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
636                    return;
637                }
638            }
639    
640            // Let p1 be a parameter of the overriding function
641            // Let p2 be a parameter of the function being overridden
642            // Then
643            //  a) p1 is not allowed to have a default value declared
644            //  b) p1 must have the same name as p2
645            for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
646                JetParameter parameter =
647                        noDeclaration ? null :
648                                (JetParameter) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), parameterFromSubclass);
649    
650                JetClassOrObject classElement = noDeclaration ? (JetClassOrObject) BindingContextUtils
651                        .descriptorToDeclaration(trace.getBindingContext(), declared.getContainingDeclaration()) : null;
652    
653                if (parameterFromSubclass.declaresDefaultValue() && !noDeclaration) {
654                    trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
655                }
656    
657                boolean superWithDefault = false;
658                for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
659                    if (parameterFromSuperclass.declaresDefaultValue()) {
660                        if (!superWithDefault) {
661                            superWithDefault = true;
662                        }
663                        else {
664                            if (noDeclaration) {
665                                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, parameterFromSubclass));
666                            }
667                            else {
668                                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, parameterFromSubclass));
669                            }
670                            break;
671                        }
672                    }
673    
674                    if (!parameterFromSuperclass.getName().equals(parameterFromSubclass.getName())) {
675                        if (noDeclaration) {
676                            trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(classElement, declared.getOverriddenDescriptors(), parameterFromSuperclass.getIndex() + 1));
677                        }
678                        else {
679                            trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(parameter, (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(), parameterFromSuperclass));
680                        }
681                    }
682                }
683            }
684        }
685    
686        private boolean checkPropertyKind(CallableMemberDescriptor descriptor, boolean isVar) {
687            if (descriptor instanceof PropertyDescriptor) {
688                PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
689                return propertyDescriptor.isVar() == isVar;
690            }
691            return false;
692        }
693    
694        private void checkVisibility(@NotNull TopDownAnalysisContext c) {
695            for (Map.Entry<JetDeclaration, CallableMemberDescriptor> entry : c.getMembers().entrySet()) {
696                checkVisibilityForMember(entry.getKey(), entry.getValue());
697            }
698        }
699    
700        private void checkVisibilityForMember(@NotNull JetDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
701            Visibility visibility = memberDescriptor.getVisibility();
702            for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
703                Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
704                if (compare == null) {
705                    trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
706                    return;
707                }
708                else if (compare < 0) {
709                    trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
710                    return;
711                }
712            }
713        }
714    }