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