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.filterOutOverridden(
292                    Sets.newLinkedHashSet(allOverriddenDeclarations));
293    
294            Set<CallableMemberDescriptor> relevantDirectlyOverridden =
295                    getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
296    
297            int implCount = countImplementations(relevantDirectlyOverridden);
298            if (implCount == 0) {
299                collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractNoImpl, Modality.ABSTRACT);
300            }
301            else if (implCount > 1) {
302                collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, manyImpl, Modality.OPEN, Modality.FINAL);
303            }
304        }
305    
306        private static int countImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
307            int implCount = 0;
308            for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
309                if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
310                    implCount++;
311                }
312            }
313            return implCount;
314        }
315    
316        private static void collectNotSynthesizedDescriptorsByModality(
317                @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
318                @NotNull Set<CallableMemberDescriptor> result,
319                Modality... modalities
320        ) {
321            Set<Modality> modalitySet = Sets.newHashSet(modalities);
322            for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
323                if (modalitySet.contains(overridden.getModality())) {
324                    if (!CallResolverUtil.isOrOverridesSynthesized(overridden)) {
325                        result.add(overridden);
326                    }
327                }
328            }
329        }
330    
331        @NotNull
332        private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
333                @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
334                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
335        ) {
336            /* Let the following class hierarchy is declared:
337    
338            trait A { fun foo() = 1 }
339            trait B : A
340            trait C : A
341            trait D : A { override fun foo() = 2 }
342            trait E : B, C, D {}
343    
344            Traits B and C have fake descriptors for function foo.
345            The map 'overriddenByParent' is:
346            { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
347            This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
348            that are overridden by this descriptor.
349    
350            The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
351            In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
352            So only 'foo in D' is relevant.
353    
354            Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
355            More precisely directly overridden descriptor is not relevant if:
356            - it's declaration set is a subset of declaration set for other directly overridden descriptor
357            ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
358            - each member of it's declaration set is overridden by a member of other declaration set
359            ('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')
360    
361            For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
362            is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
363            are overridden by some other function and corresponding directly overridden descriptor is not relevant.
364            */
365    
366            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> relevantOverriddenByParent = Maps.newLinkedHashMap(overriddenByParent);
367    
368            for (Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>> entry : overriddenByParent.entrySet()) {
369                CallableMemberDescriptor directlyOverridden = entry.getKey();
370                Set<CallableMemberDescriptor> declarationSet = entry.getValue();
371                if (!isRelevant(declarationSet, relevantOverriddenByParent.values(), allFilteredOverriddenDeclarations)) {
372                    relevantOverriddenByParent.remove(directlyOverridden);
373                }
374            }
375            return relevantOverriddenByParent.keySet();
376        }
377    
378        private static boolean isRelevant(
379                @NotNull Set<CallableMemberDescriptor> declarationSet,
380                @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
381                @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
382        ) {
383            for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
384                if (otherSet == declarationSet) continue;
385                if (otherSet.containsAll(declarationSet)) return false;
386                if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
387            }
388            return true;
389        }
390    
391        @NotNull
392        private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
393                @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
394        ) {
395            Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
396            for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
397                Collection<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(descriptor);
398                Set<CallableMemberDescriptor> filteredOverrides = OverridingUtil.filterOutOverridden(
399                        Sets.newLinkedHashSet(overriddenDeclarations));
400                Set<CallableMemberDescriptor> overridden = Sets.newLinkedHashSet();
401                for (CallableMemberDescriptor memberDescriptor : filteredOverrides) {
402                    overridden.add(memberDescriptor);
403                }
404                overriddenDeclarationsByDirectParent.put(descriptor, overridden);
405            }
406            return overriddenDeclarationsByDirectParent;
407        }
408    
409        public static Multimap<CallableMemberDescriptor, CallableMemberDescriptor> collectSuperMethods(MutableClassDescriptor classDescriptor) {
410            Set<CallableMemberDescriptor> inheritedFunctions = Sets.newLinkedHashSet();
411            for (JetType supertype : classDescriptor.getSupertypes()) {
412                for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
413                    if (descriptor instanceof CallableMemberDescriptor) {
414                        CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
415                        inheritedFunctions.add(memberDescriptor);
416                    }
417                }
418            }
419    
420            // Only those actually inherited
421            Set<CallableMemberDescriptor> filteredMembers = OverridingUtil.filterOutOverridden(inheritedFunctions);
422    
423            // Group members with "the same" signature
424            Multimap<CallableMemberDescriptor, CallableMemberDescriptor> factoredMembers = CommonSuppliers.newLinkedHashSetHashSetMultimap();
425            for (CallableMemberDescriptor one : filteredMembers) {
426                if (factoredMembers.values().contains(one)) continue;
427                for (CallableMemberDescriptor another : filteredMembers) {
428    //                if (one == another) continue;
429                    factoredMembers.put(one, one);
430                    if (OverridingUtil.isOverridableBy(one, another).getResult() == OVERRIDABLE
431                            || OverridingUtil.isOverridableBy(another, one).getResult() == OVERRIDABLE) {
432                        factoredMembers.put(one, another);
433                    }
434                }
435            }
436            return factoredMembers;
437        }
438    
439        private interface CheckOverrideReportStrategy {
440            void overridingFinalMember(@NotNull CallableMemberDescriptor overridden);
441    
442            void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
443    
444            void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
445    
446            void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden);
447    
448            void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden);
449    
450            void nothingToOverride();
451        }
452    
453        private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
454            if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
455                // TODO: this should be replaced soon by a framework of synthesized member generation tools
456                if (declared.getName().asString().startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX)) {
457                    checkOverrideForComponentFunction(declared);
458                }
459                return;
460            }
461    
462            if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
463                return;
464            }
465    
466            final JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
467            if (member == null) {
468                throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
469            }
470    
471            JetModifierList modifierList = member.getModifierList();
472            final ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
473            Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
474    
475            if (overrideNode != null) {
476                checkOverridesForMemberMarkedOverride(declared, true, new CheckOverrideReportStrategy() {
477                    private boolean finalOverriddenError = false;
478                    private boolean typeMismatchError = false;
479                    private boolean kindMismatchError = false;
480    
481                    @Override
482                    public void overridingFinalMember( @NotNull CallableMemberDescriptor overridden) {
483                        if (!finalOverriddenError) {
484                            finalOverriddenError = true;
485                            trace.report(OVERRIDING_FINAL_MEMBER.on(overrideNode.getPsi(), overridden, overridden.getContainingDeclaration()));
486                        }
487                    }
488    
489                    @Override
490                    public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
491                        if (!typeMismatchError) {
492                            typeMismatchError = true;
493                            trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
494                        }
495                    }
496    
497                    @Override
498                    public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
499                        if (!typeMismatchError) {
500                            typeMismatchError = true;
501                            trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
502                        }
503                    }
504    
505                    @Override
506                    public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
507                        if (!kindMismatchError) {
508                            kindMismatchError = true;
509                            trace.report(VAR_OVERRIDDEN_BY_VAL.on((JetProperty) member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
510                        }
511                    }
512    
513                    @Override
514                    public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
515                        trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden, invisibleOverridden.getContainingDeclaration()));
516                    }
517    
518                    @Override
519                    public void nothingToOverride() {
520                        trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
521                    }
522                });
523            }
524            else if (!overriddenDescriptors.isEmpty()) {
525                CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
526                trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
527            }
528        }
529    
530        private void checkOverridesForMemberMarkedOverride(
531                @NotNull CallableMemberDescriptor declared,
532                boolean checkIfOverridesNothing,
533                @NotNull CheckOverrideReportStrategy reportError
534        ) {
535            Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
536    
537            for (CallableMemberDescriptor overridden : overriddenDescriptors) {
538                if (overridden != null) {
539                    if (!overridden.getModality().isOverridable()) {
540                        reportError.overridingFinalMember(overridden);
541                    }
542    
543                    if (declared instanceof PropertyDescriptor && !OverridingUtil.isPropertyTypeOkForOverride(
544                            JetTypeChecker.INSTANCE, (PropertyDescriptor) overridden, (PropertyDescriptor) declared)) {
545                        reportError.propertyTypeMismatchOnOverride(overridden);
546                    }
547                    else if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, overridden, declared)) {
548                        reportError.returnTypeMismatchOnOverride(overridden);
549                    }
550    
551                    if (checkPropertyKind(overridden, true) && checkPropertyKind(declared, false)) {
552                        reportError.varOverriddenByVal(overridden);
553                    }
554                }
555            }
556    
557            if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
558                DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
559                assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
560                ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
561    
562                CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
563                if (invisibleOverriddenDescriptor != null) {
564                    reportError.cannotOverrideInvisibleMember(invisibleOverriddenDescriptor);
565                }
566                else {
567                    reportError.nothingToOverride();
568                }
569            }
570        }
571    
572        private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
573            final JetAnnotationEntry dataAnnotation = findDataAnnotationForDataClass(componentFunction.getContainingDeclaration());
574    
575            checkOverridesForMemberMarkedOverride(componentFunction, false, new CheckOverrideReportStrategy() {
576                private boolean overrideConflict = false;
577    
578                @Override
579                public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
580                    if (!overrideConflict) {
581                        overrideConflict = true;
582                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
583                    }
584                }
585    
586                @Override
587                public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
588                    if (!overrideConflict) {
589                        overrideConflict = true;
590                        trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
591                    }
592                }
593    
594                @Override
595                public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
596                    throw new IllegalStateException("Component functions are not properties");
597                }
598    
599                @Override
600                public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
601                    throw new IllegalStateException("Component functions are not properties");
602                }
603    
604                @Override
605                public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
606                    throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
607                }
608    
609                @Override
610                public void nothingToOverride() {
611                    throw new IllegalStateException("Component functions are OK to override nothing");
612                }
613            });
614        }
615    
616        @NotNull
617        private JetAnnotationEntry findDataAnnotationForDataClass(@NotNull DeclarationDescriptor dataClass) {
618            ClassDescriptor stdDataClassAnnotation = KotlinBuiltIns.getInstance().getDataClassAnnotation();
619            for (AnnotationDescriptor annotation : dataClass.getAnnotations()) {
620                if (stdDataClassAnnotation.equals(annotation.getType().getConstructor().getDeclarationDescriptor())) {
621                    return BindingContextUtils.getNotNull(trace.getBindingContext(),
622                                                          BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT,
623                                                          annotation);
624                }
625            }
626            throw new IllegalStateException("No data annotation is found for data class");
627        }
628    
629        private CallableMemberDescriptor findInvisibleOverriddenDescriptor(CallableMemberDescriptor declared, ClassDescriptor declaringClass) {
630            CallableMemberDescriptor invisibleOverride = null;
631            outer:
632            for (JetType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
633                Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
634                all.addAll(supertype.getMemberScope().getFunctions(declared.getName()));
635                all.addAll((Collection) supertype.getMemberScope().getProperties(declared.getName()));
636                for (CallableMemberDescriptor fromSuper : all) {
637                    if (OverridingUtil.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) {
638                        invisibleOverride = fromSuper;
639                        if (Visibilities.isVisible(fromSuper, declared)) {
640                            throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared + " and visible but does not appear in its getOverriddenDescriptors()");
641                        }
642                        break outer;
643                    }
644                }
645            }
646            return invisibleOverride;
647        }
648    
649        private void checkParameterOverridesForAllClasses() {
650            List<MutableClassDescriptor> allClasses = Lists.newArrayList(context.getClasses().values());
651            allClasses.addAll(context.getObjects().values());
652            for (MutableClassDescriptor classDescriptor : allClasses) {
653                Collection<CallableMemberDescriptor> members = classDescriptor.getAllCallableMembers();
654                for (CallableMemberDescriptor member : members) {
655                    checkOverridesForParameters(member);
656                }
657            }
658        }
659    
660        private void checkOverridesForParameters(CallableMemberDescriptor declared) {
661            boolean noDeclaration = declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION;
662            if (!noDeclaration) {
663                // No check if the function is not marked as 'override'
664                JetModifierListOwner declaration =
665                        (JetModifierListOwner) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
666                if (!declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
667                    return;
668                }
669            }
670    
671            // Let p1 be a parameter of the overriding function
672            // Let p2 be a parameter of the function being overridden
673            // Then
674            //  a) p1 is not allowed to have a default value declared
675            //  b) p1 must have the same name as p2
676            for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
677                JetParameter parameter =
678                        noDeclaration ? null :
679                                (JetParameter) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), parameterFromSubclass);
680    
681                JetClassOrObject classElement = noDeclaration ? (JetClassOrObject) BindingContextUtils
682                        .descriptorToDeclaration(trace.getBindingContext(), declared.getContainingDeclaration()) : null;
683    
684                if (parameterFromSubclass.declaresDefaultValue() && !noDeclaration) {
685                    trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
686                }
687    
688                boolean superWithDefault = false;
689                for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
690                    if (parameterFromSuperclass.declaresDefaultValue()) {
691                        if (!superWithDefault) {
692                            superWithDefault = true;
693                        }
694                        else {
695                            if (noDeclaration) {
696                                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, parameterFromSubclass));
697                            }
698                            else {
699                                trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, parameterFromSubclass));
700                            }
701                            break;
702                        }
703                    }
704    
705                    if (!parameterFromSuperclass.getName().equals(parameterFromSubclass.getName())) {
706                        if (noDeclaration) {
707                            trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(classElement, declared.getOverriddenDescriptors(), parameterFromSuperclass.getIndex() + 1));
708                        }
709                        else {
710                            trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(parameter, (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(), parameterFromSuperclass));
711                        }
712                    }
713                }
714            }
715        }
716    
717        private boolean checkPropertyKind(CallableMemberDescriptor descriptor, boolean isVar) {
718            if (descriptor instanceof PropertyDescriptor) {
719                PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
720                return propertyDescriptor.isVar() == isVar;
721            }
722            return false;
723        }
724    
725        private void checkVisibility() {
726            for (Map.Entry<JetDeclaration, CallableMemberDescriptor> entry : context.getMembers().entrySet()) {
727                checkVisibilityForMember(entry.getKey(), entry.getValue());
728            }
729        }
730    
731        private void checkVisibilityForMember(@NotNull JetDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
732            Visibility visibility = memberDescriptor.getVisibility();
733            for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
734                Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
735                if (compare == null) {
736                    trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
737                    return;
738                }
739                else if (compare < 0) {
740                    trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
741                    return;
742                }
743            }
744        }
745    }