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