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