001 /*
002 * Copyright 2010-2015 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.kotlin.resolve;
018
019 import com.google.common.collect.Lists;
020 import com.google.common.collect.Maps;
021 import com.google.common.collect.Sets;
022 import com.intellij.psi.PsiElement;
023 import com.intellij.util.Function;
024 import com.intellij.util.SmartList;
025 import com.intellij.util.containers.ContainerUtil;
026 import com.intellij.util.containers.LinkedMultiMap;
027 import com.intellij.util.containers.MultiMap;
028 import com.intellij.util.containers.SmartHashSet;
029 import com.intellij.util.containers.hash.EqualityPolicy;
030 import kotlin.Unit;
031 import kotlin.jvm.functions.Function1;
032 import org.jetbrains.annotations.NotNull;
033 import org.jetbrains.annotations.Nullable;
034 import org.jetbrains.annotations.ReadOnly;
035 import org.jetbrains.kotlin.descriptors.*;
036 import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2;
037 import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryWithPsiElement;
038 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
039 import org.jetbrains.kotlin.lexer.KtTokens;
040 import org.jetbrains.kotlin.name.Name;
041 import org.jetbrains.kotlin.psi.*;
042 import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
043 import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsKt;
044 import org.jetbrains.kotlin.types.*;
045 import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
046 import org.jetbrains.kotlin.utils.HashSetUtil;
047
048 import java.util.*;
049
050 import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*;
051 import static org.jetbrains.kotlin.diagnostics.Errors.*;
052 import static org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers;
053 import static org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
054
055 public class OverrideResolver {
056
057 @NotNull private final BindingTrace trace;
058
059 public OverrideResolver(@NotNull BindingTrace trace) {
060 this.trace = trace;
061 }
062
063 public void check(@NotNull TopDownAnalysisContext c) {
064 checkVisibility(c);
065 checkOverrides(c);
066 checkParameterOverridesForAllClasses(c);
067 }
068
069 public static void generateOverridesInAClass(
070 @NotNull ClassDescriptor classDescriptor,
071 @NotNull Collection<CallableMemberDescriptor> membersFromCurrent,
072 @NotNull OverridingUtil.DescriptorSink sink
073 ) {
074 List<CallableMemberDescriptor> membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor);
075 MultiMap<Name, CallableMemberDescriptor> membersFromCurrentByName = groupDescriptorsByName(membersFromCurrent);
076 MultiMap<Name, CallableMemberDescriptor> membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes);
077
078 Set<Name> memberNames = new LinkedHashSet<Name>();
079 memberNames.addAll(membersFromSupertypesByName.keySet());
080 memberNames.addAll(membersFromCurrentByName.keySet());
081
082 for (Name memberName : memberNames) {
083 Collection<CallableMemberDescriptor> fromSupertypes = membersFromSupertypesByName.get(memberName);
084 Collection<CallableMemberDescriptor> fromCurrent = membersFromCurrentByName.get(memberName);
085
086 OverridingUtil.generateOverridesInFunctionGroup(memberName, fromSupertypes, fromCurrent, classDescriptor, sink);
087 }
088 }
089
090 public static void resolveUnknownVisibilities(
091 @NotNull Collection<? extends CallableMemberDescriptor> descriptors,
092 @NotNull BindingTrace trace
093 ) {
094 for (CallableMemberDescriptor descriptor : descriptors) {
095 OverridingUtil.resolveUnknownVisibilityForMember(descriptor, createCannotInferVisibilityReporter(trace));
096 }
097 }
098
099 @NotNull
100 public static Function1<CallableMemberDescriptor, Unit> createCannotInferVisibilityReporter(@NotNull final BindingTrace trace) {
101 return new Function1<CallableMemberDescriptor, Unit>() {
102 @Override
103 public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
104 DeclarationDescriptor reportOn;
105 if (descriptor.getKind() == FAKE_OVERRIDE || descriptor.getKind() == DELEGATION) {
106 reportOn = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class);
107 }
108 else if (descriptor instanceof PropertyAccessorDescriptor && ((PropertyAccessorDescriptor) descriptor).isDefault()) {
109 reportOn = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
110 }
111 else {
112 reportOn = descriptor;
113 }
114 //noinspection ConstantConditions
115 PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(reportOn);
116 if (element instanceof KtDeclaration) {
117 trace.report(CANNOT_INFER_VISIBILITY.on((KtDeclaration) element, descriptor));
118 }
119 return Unit.INSTANCE$;
120 }
121 };
122 }
123
124 private static enum Filtering {
125 RETAIN_OVERRIDING,
126 RETAIN_OVERRIDDEN
127 }
128
129 @NotNull
130 public static <D extends CallableDescriptor> Set<D> filterOutOverridden(@NotNull Set<D> candidateSet) {
131 //noinspection unchecked
132 return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDING);
133 }
134
135 @NotNull
136 public static <D> Set<D> filterOutOverriding(@NotNull Set<D> candidateSet) {
137 //noinspection unchecked
138 return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDDEN);
139 }
140
141 @NotNull
142 public static <D> Set<D> filterOutOverridden(
143 @NotNull Set<D> candidateSet,
144 @NotNull Function<? super D, ? extends CallableDescriptor> transform
145 ) {
146 return filterOverrides(candidateSet, transform, Filtering.RETAIN_OVERRIDING);
147 }
148
149 @NotNull
150 private static <D> Set<D> filterOverrides(
151 @NotNull Set<D> candidateSet,
152 @NotNull final Function<? super D, ? extends CallableDescriptor> transform,
153 @NotNull Filtering filtering
154 ) {
155 if (candidateSet.size() <= 1) return candidateSet;
156
157 // In a multi-module project different "copies" of the same class may be present in different libraries,
158 // that's why we use structural equivalence for members (DescriptorEquivalenceForOverrides).
159 // Here we filter out structurally equivalent descriptors before processing overrides, because such descriptors
160 // "override" each other (overrides(f, g) = overrides(g, f) = true) and the code below removes them all from the
161 // candidates, unless we first compute noDuplicates
162 Set<D> noDuplicates = HashSetUtil.linkedHashSet(
163 candidateSet,
164 new EqualityPolicy<D>() {
165 @Override
166 public int getHashCode(D d) {
167 return DescriptorUtils.getFqName(transform.fun(d).getContainingDeclaration()).hashCode();
168 }
169
170 @Override
171 public boolean isEqual(D d1, D d2) {
172 CallableDescriptor f = transform.fun(d1);
173 CallableDescriptor g = transform.fun(d2);
174 return DescriptorEquivalenceForOverrides.INSTANCE$.areEquivalent(f.getOriginal(), g.getOriginal());
175 }
176 });
177
178 Set<D> candidates = Sets.newLinkedHashSet();
179 outerLoop:
180 for (D meD : noDuplicates) {
181 CallableDescriptor me = transform.fun(meD);
182 for (D otherD : noDuplicates) {
183 CallableDescriptor other = transform.fun(otherD);
184 if (me == other) continue;
185 if (filtering == Filtering.RETAIN_OVERRIDING) {
186 if (overrides(other, me)) {
187 continue outerLoop;
188 }
189 }
190 else if (filtering == Filtering.RETAIN_OVERRIDDEN) {
191 if (overrides(me, other)) {
192 continue outerLoop;
193 }
194 }
195 else {
196 throw new AssertionError("Unexpected Filtering object: " + filtering);
197 }
198 }
199 for (D otherD : candidates) {
200 CallableDescriptor other = transform.fun(otherD);
201 if (me.getOriginal() == other.getOriginal()
202 && OverridingUtil.DEFAULT.isOverridableBy(other, me, null).getResult() == OVERRIDABLE
203 && OverridingUtil.DEFAULT.isOverridableBy(me, other, null).getResult() == OVERRIDABLE) {
204 continue outerLoop;
205 }
206 }
207 candidates.add(meD);
208 }
209
210 assert !candidates.isEmpty() : "All candidates filtered out from " + candidateSet;
211
212 return candidates;
213 }
214
215 // check whether f overrides g
216 public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) {
217 // This first check cover the case of duplicate classes in different modules:
218 // when B is defined in modules m1 and m2, and C (indirectly) inherits from both versions,
219 // we'll be getting sets of members that do not override each other, but are structurally equivalent.
220 // As other code relies on no equal descriptors passed here, we guard against f == g, but this may not be necessary
221 if (!f.equals(g) && DescriptorEquivalenceForOverrides.INSTANCE$.areEquivalent(f.getOriginal(), g.getOriginal())) return true;
222 CallableDescriptor originalG = g.getOriginal();
223 for (D overriddenFunction : DescriptorUtils.getAllOverriddenDescriptors(f)) {
224 if (DescriptorEquivalenceForOverrides.INSTANCE$.areEquivalent(originalG, overriddenFunction.getOriginal())) return true;
225 }
226 return false;
227 }
228
229 private static <T extends DeclarationDescriptor> MultiMap<Name, T> groupDescriptorsByName(Collection<T> properties) {
230 MultiMap<Name, T> r = new LinkedMultiMap<Name, T>();
231 for (T property : properties) {
232 r.putValue(property.getName(), property);
233 }
234 return r;
235 }
236
237
238 private static List<CallableMemberDescriptor> getCallableMembersFromSupertypes(ClassDescriptor classDescriptor) {
239 Set<CallableMemberDescriptor> r = Sets.newLinkedHashSet();
240 for (KotlinType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
241 r.addAll(getCallableMembersFromType(supertype));
242 }
243 return new ArrayList<CallableMemberDescriptor>(r);
244 }
245
246 private static List<CallableMemberDescriptor> getCallableMembersFromType(KotlinType type) {
247 List<CallableMemberDescriptor> r = Lists.newArrayList();
248 for (DeclarationDescriptor decl : DescriptorUtils.getAllDescriptors(type.getMemberScope())) {
249 if (decl instanceof PropertyDescriptor || decl instanceof SimpleFunctionDescriptor) {
250 r.add((CallableMemberDescriptor) decl);
251 }
252 }
253 return r;
254 }
255
256 private void checkOverrides(@NotNull TopDownAnalysisContext c) {
257 for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
258 checkOverridesInAClass(entry.getValue(), entry.getKey());
259 }
260 }
261
262 private void checkOverridesInAClass(@NotNull ClassDescriptorWithResolutionScopes classDescriptor, @NotNull final KtClassOrObject klass) {
263 // Check overrides for internal consistency
264 for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
265 checkOverrideForMember(member);
266 }
267
268 CollectErrorInformationForInheritedMembersStrategy inheritedMemberErrors =
269 new CollectErrorInformationForInheritedMembersStrategy(klass, classDescriptor);
270
271 checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors);
272 inheritedMemberErrors.doReportErrors();
273 }
274
275 @NotNull
276 public static Set<CallableMemberDescriptor> getMissingImplementations(@NotNull ClassDescriptor classDescriptor) {
277 CollectMissingImplementationsStrategy collector = new CollectMissingImplementationsStrategy();
278 checkInheritedAndDelegatedSignatures(classDescriptor, collector, null);
279 return collector.shouldImplement;
280 }
281
282 private interface CheckInheritedSignaturesReportStrategy {
283 void abstractMemberNotImplemented(CallableMemberDescriptor descriptor);
284 void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor);
285 void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor);
286 void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor);
287 void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
288 void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2);
289 }
290
291 private static class CollectMissingImplementationsStrategy implements CheckInheritedSignaturesReportStrategy {
292 private final Set<CallableMemberDescriptor> shouldImplement = new LinkedHashSet<CallableMemberDescriptor>();
293
294 @Override
295 public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
296 shouldImplement.add(descriptor);
297 }
298
299 @Override
300 public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
301 // don't care
302 }
303
304 @Override
305 public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
306 shouldImplement.add(descriptor);
307 }
308
309 @Override
310 public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
311 // don't care
312 }
313
314 @Override
315 public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
316 // don't care
317 }
318
319 @Override
320 public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
321 // don't care
322 }
323 }
324
325 private class CollectErrorInformationForInheritedMembersStrategy
326 implements CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy {
327 private final KtClassOrObject klass;
328 private final ClassDescriptor classDescriptor;
329
330 private final Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
331 private final Set<CallableMemberDescriptor> multipleImplementations = Sets.newLinkedHashSet();
332 private final Set<CallableMemberDescriptor> abstractInBaseClassNoImpl = Sets.newLinkedHashSet();
333 private final Set<CallableMemberDescriptor> conflictingInterfaceMembers = Sets.newLinkedHashSet();
334 private final Set<CallableMemberDescriptor> conflictingReturnTypes = Sets.newHashSet();
335
336 private final Set<DiagnosticFactoryWithPsiElement> onceErrorsReported = new SmartHashSet<DiagnosticFactoryWithPsiElement>();
337
338 public CollectErrorInformationForInheritedMembersStrategy(
339 @NotNull KtClassOrObject klass,
340 @NotNull ClassDescriptor classDescriptor
341 ) {
342 this.klass = klass;
343 this.classDescriptor = classDescriptor;
344 }
345
346 @Override
347 public void abstractMemberNotImplemented(CallableMemberDescriptor descriptor) {
348 abstractNoImpl.add(descriptor);
349 }
350
351 @Override
352 public void abstractBaseClassMemberNotImplemented(CallableMemberDescriptor descriptor) {
353 abstractInBaseClassNoImpl.add(descriptor);
354 }
355
356 @Override
357 public void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor) {
358 multipleImplementations.add(descriptor);
359 }
360
361 @Override
362 public void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor) {
363 conflictingInterfaceMembers.add(descriptor);
364 }
365
366 @Override
367 public void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
368 conflictingReturnTypes.add(descriptor1);
369 conflictingReturnTypes.add(descriptor2);
370
371 reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
372 }
373
374 @Override
375 public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
376 conflictingReturnTypes.add(descriptor1);
377 conflictingReturnTypes.add(descriptor2);
378
379 if (descriptor1.isVar() || descriptor2.isVar()) {
380 reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
381 }
382 else {
383 reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
384 }
385 }
386
387 private void reportInheritanceConflictIfRequired(
388 @NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
389 @NotNull CallableMemberDescriptor descriptor1,
390 @NotNull CallableMemberDescriptor descriptor2
391 ) {
392 if (!onceErrorsReported.contains(diagnosticFactory)) {
393 onceErrorsReported.add(diagnosticFactory);
394 trace.report(diagnosticFactory.on(klass, descriptor1, descriptor2));
395 }
396 }
397
398 @Override
399 public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
400 reportDelegationProblemIfRequired(OVERRIDING_FINAL_MEMBER_BY_DELEGATION, overriding, overridden);
401 }
402
403 @Override
404 public void returnTypeMismatchOnOverride(
405 @NotNull CallableMemberDescriptor overriding,
406 @NotNull CallableMemberDescriptor overridden
407 ) {
408 // Always reported as RETURN_TYPE_MISMATCH_ON_INHERITANCE
409 }
410
411 @Override
412 public void propertyTypeMismatchOnOverride(
413 @NotNull PropertyDescriptor overriding,
414 @NotNull PropertyDescriptor overridden
415 ) {
416 // Always reported as PROPERTY_TYPE_MISMATCH_ON_INHERITANCE
417 }
418
419 @Override
420 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
421 reportDelegationProblemIfRequired(VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, overriding, overridden);
422 }
423
424 private void reportDelegationProblemIfRequired(
425 @NotNull DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> diagnosticFactory,
426 @NotNull CallableMemberDescriptor delegate,
427 @NotNull CallableMemberDescriptor overridden
428 ) {
429 assert delegate.getKind() == DELEGATION : "Delegate expected, got " + delegate + " of kind " + delegate.getKind();
430
431 if (!onceErrorsReported.contains(diagnosticFactory)) {
432 onceErrorsReported.add(diagnosticFactory);
433 trace.report(diagnosticFactory.on(klass, delegate, overridden));
434 }
435 }
436
437 @Override
438 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
439 assert overriding.getKind() == DELEGATION : "Delegate expected, got " + overriding + " of kind " + overriding.getKind();
440 assert overriding.getKind() != DELEGATION : "Delegated member can't override an invisible member; " + invisibleOverridden;
441 }
442
443 @Override
444 public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
445 assert overriding.getKind() == DELEGATION : "Delegate expected, got " + overriding + " of kind " + overriding.getKind();
446 assert overriding.getKind() != DELEGATION : "Delegated member can't override nothing; " + overriding;
447 }
448
449 void doReportErrors() {
450 if (!classCanHaveAbstractMembers(classDescriptor)) {
451 if (!abstractInBaseClassNoImpl.isEmpty()) {
452 trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.iterator().next()));
453 }
454 else if (!abstractNoImpl.isEmpty()) {
455 trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()));
456 }
457 }
458
459 conflictingInterfaceMembers.removeAll(conflictingReturnTypes);
460 multipleImplementations.removeAll(conflictingReturnTypes);
461 if (!conflictingInterfaceMembers.isEmpty()) {
462 trace.report(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED.on(klass, klass, conflictingInterfaceMembers.iterator().next()));
463 }
464 else if (!multipleImplementations.isEmpty()) {
465 trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, multipleImplementations.iterator().next()));
466 }
467 }
468 }
469
470 private static void checkInheritedAndDelegatedSignatures(
471 @NotNull ClassDescriptor classDescriptor,
472 @NotNull CheckInheritedSignaturesReportStrategy inheritedReportStrategy,
473 @Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
474 ) {
475 for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
476 if (member instanceof CallableMemberDescriptor) {
477 checkInheritedAndDelegatedSignatures((CallableMemberDescriptor) member, inheritedReportStrategy, overrideReportStrategyForDelegates);
478 }
479 }
480 }
481
482 private static void checkInheritedAndDelegatedSignatures(
483 @NotNull CallableMemberDescriptor descriptor,
484 @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy,
485 @Nullable CheckOverrideReportStrategy overrideReportStrategyForDelegates
486 ) {
487 CallableMemberDescriptor.Kind kind = descriptor.getKind();
488 if (kind != FAKE_OVERRIDE && kind != DELEGATION) return;
489 if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
490
491 Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
492 assert !directOverridden.isEmpty() : kind + " " + descriptor.getName().asString() + " must override something";
493
494 // collects map from the directly overridden descriptor to the set of declarations:
495 // -- if directly overridden is not fake, the set consists of one element: this directly overridden
496 // -- if it's fake, overridden declarations (non-fake) of this descriptor are collected
497 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
498
499 List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
500 Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = filterOutOverridden(
501 Sets.newLinkedHashSet(allOverriddenDeclarations));
502
503 Set<CallableMemberDescriptor> relevantDirectlyOverridden =
504 getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
505
506 checkInheritedDescriptorsGroup(relevantDirectlyOverridden, descriptor, reportingStrategy);
507
508 if (kind == DELEGATION && overrideReportStrategyForDelegates != null) {
509 checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates);
510 }
511
512 if (kind != DELEGATION) {
513 checkMissingOverridesByJava8Restrictions(relevantDirectlyOverridden, reportingStrategy);
514 }
515
516 List<CallableMemberDescriptor> implementations = collectImplementations(relevantDirectlyOverridden);
517
518 int numImplementations = implementations.size();
519
520 if (numImplementations == 1 && isReturnTypeOkForOverride(descriptor, implementations.get(0))) return;
521
522 List<CallableMemberDescriptor> abstractOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
523 List<CallableMemberDescriptor> concreteOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
524 filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden);
525
526 if (numImplementations == 0) {
527 if (kind != DELEGATION) {
528 for (CallableMemberDescriptor member : abstractOverridden) {
529 reportingStrategy.abstractMemberNotImplemented(member);
530 }
531 }
532 }
533 else if (numImplementations > 1) {
534 for (CallableMemberDescriptor member : concreteOverridden) {
535 reportingStrategy.multipleImplementationsMemberNotImplemented(member);
536 }
537 }
538 else {
539 if (kind != DELEGATION) {
540 List<CallableMemberDescriptor> membersWithMoreSpecificReturnType =
541 collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations.get(0));
542 for (CallableMemberDescriptor member : membersWithMoreSpecificReturnType) {
543 reportingStrategy.abstractMemberNotImplemented(member);
544 }
545 }
546 }
547 }
548
549 private static void checkMissingOverridesByJava8Restrictions(
550 @NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden,
551 @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
552 ) {
553 // Java 8:
554 // -- class should implement an abstract member of a super-class,
555 // even if relevant default implementation is provided in one of the super-interfaces;
556 // -- inheriting multiple override equivalent methods from an interface is a conflict
557 // regardless of 'default' vs 'abstract'.
558
559 boolean overridesClassMember = false;
560 boolean overridesNonAbstractInterfaceMember = false;
561 CallableMemberDescriptor overridesAbstractInBaseClass = null;
562 List<CallableMemberDescriptor> overriddenInterfaceMembers = new SmartList<CallableMemberDescriptor>();
563 for (CallableMemberDescriptor overridden : relevantDirectlyOverridden) {
564 DeclarationDescriptor containingDeclaration = overridden.getContainingDeclaration();
565 if (containingDeclaration instanceof ClassDescriptor) {
566 ClassDescriptor baseClassOrInterface = (ClassDescriptor) containingDeclaration;
567 if (baseClassOrInterface.getKind() == ClassKind.CLASS) {
568 overridesClassMember = true;
569 if (overridden.getModality() == Modality.ABSTRACT) {
570 overridesAbstractInBaseClass = overridden;
571 }
572 }
573 else if (baseClassOrInterface.getKind() == ClassKind.INTERFACE) {
574 overriddenInterfaceMembers.add(overridden);
575 if (overridden.getModality() != Modality.ABSTRACT) {
576 overridesNonAbstractInterfaceMember = true;
577 }
578 }
579 }
580 }
581
582 if (overridesAbstractInBaseClass != null) {
583 reportingStrategy.abstractBaseClassMemberNotImplemented(overridesAbstractInBaseClass);
584 }
585 if (!overridesClassMember && overridesNonAbstractInterfaceMember && overriddenInterfaceMembers.size() > 1) {
586 for (CallableMemberDescriptor member : overriddenInterfaceMembers) {
587 reportingStrategy.conflictingInterfaceMemberNotImplemented(member);
588 }
589 }
590 }
591
592 @NotNull
593 private static List<CallableMemberDescriptor> collectImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
594 List<CallableMemberDescriptor> result = new ArrayList<CallableMemberDescriptor>(relevantDirectlyOverridden.size());
595 for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
596 if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
597 result.add(overriddenDescriptor);
598 }
599 }
600 return result;
601 }
602
603 private static void filterNotSynthesizedDescriptorsByModality(
604 @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
605 @NotNull List<CallableMemberDescriptor> abstractOverridden,
606 @NotNull List<CallableMemberDescriptor> concreteOverridden
607 ) {
608 for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
609 if (!CallResolverUtilKt.isOrOverridesSynthesized(overridden)) {
610 if (overridden.getModality() == Modality.ABSTRACT) {
611 abstractOverridden.add(overridden);
612 }
613 else {
614 concreteOverridden.add(overridden);
615 }
616 }
617 }
618 }
619
620 @NotNull
621 private static List<CallableMemberDescriptor> collectAbstractMethodsWithMoreSpecificReturnType(
622 @NotNull List<CallableMemberDescriptor> abstractOverridden,
623 @NotNull CallableMemberDescriptor implementation
624 ) {
625 List<CallableMemberDescriptor> result = new ArrayList<CallableMemberDescriptor>(abstractOverridden.size());
626 for (CallableMemberDescriptor abstractMember : abstractOverridden) {
627 if (!isReturnTypeOkForOverride(abstractMember, implementation)) {
628 result.add(abstractMember);
629 }
630 }
631 assert !result.isEmpty() : "Implementation (" + implementation + ") doesn't have the most specific type, " +
632 "but none of the other overridden methods does either: " + abstractOverridden;
633 return result;
634 }
635
636 @NotNull
637 private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
638 @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
639 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
640 ) {
641 /* Let the following class hierarchy is declared:
642
643 trait A { fun foo() = 1 }
644 trait B : A
645 trait C : A
646 trait D : A { override fun foo() = 2 }
647 trait E : B, C, D {}
648
649 Traits B and C have fake descriptors for function foo.
650 The map 'overriddenByParent' is:
651 { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
652 This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
653 that are overridden by this descriptor.
654
655 The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
656 In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
657 So only 'foo in D' is relevant.
658
659 Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
660 More precisely directly overridden descriptor is not relevant if:
661 - it's declaration set is a subset of declaration set for other directly overridden descriptor
662 ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
663 - each member of it's declaration set is overridden by a member of other declaration set
664 ('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')
665
666 For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
667 is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
668 are overridden by some other function and corresponding directly overridden descriptor is not relevant.
669 */
670
671 for (Iterator<Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>>> iterator =
672 overriddenByParent.entrySet().iterator(); iterator.hasNext(); ) {
673 if (!isRelevant(iterator.next().getValue(), overriddenByParent.values(), allFilteredOverriddenDeclarations)) {
674 iterator.remove();
675 }
676 }
677 return overriddenByParent.keySet();
678 }
679
680 private static boolean isRelevant(
681 @NotNull Set<CallableMemberDescriptor> declarationSet,
682 @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
683 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
684 ) {
685 for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
686 if (otherSet == declarationSet) continue;
687 if (otherSet.containsAll(declarationSet)) return false;
688 if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
689 }
690 return true;
691 }
692
693 @NotNull
694 private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
695 @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
696 ) {
697 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
698 for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
699 Set<CallableMemberDescriptor> overriddenDeclarations = getOverriddenDeclarations(descriptor);
700 Set<CallableMemberDescriptor> filteredOverrides = filterOutOverridden(overriddenDeclarations);
701 overriddenDeclarationsByDirectParent.put(descriptor, new LinkedHashSet<CallableMemberDescriptor>(filteredOverrides));
702 }
703 return overriddenDeclarationsByDirectParent;
704 }
705
706 /**
707 * @return overridden real descriptors (not fake overrides). Note that all usages of this method should be followed by calling
708 * {@link #filterOutOverridden(java.util.Set)} or {@link #filterOutOverriding(java.util.Set)}, because some of the declarations
709 * can override the other
710 * TODO: merge this method with filterOutOverridden
711 */
712 @NotNull
713 public static Set<CallableMemberDescriptor> getOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) {
714 Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
715 getOverriddenDeclarations(descriptor, result);
716 return result;
717 }
718
719 private static void getOverriddenDeclarations(
720 @NotNull CallableMemberDescriptor descriptor,
721 @NotNull Set<CallableMemberDescriptor> result
722 ) {
723 if (descriptor.getKind().isReal()) {
724 result.add(descriptor);
725 }
726 else {
727 if (descriptor.getOverriddenDescriptors().isEmpty()) {
728 throw new IllegalStateException("No overridden descriptors found for (fake override) " + descriptor);
729 }
730 for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
731 getOverriddenDeclarations(overridden, result);
732 }
733 }
734 }
735
736 private interface CheckOverrideReportStrategy {
737 void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
738 void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
739 void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden);
740 void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
741 void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden);
742 void nothingToOverride(@NotNull CallableMemberDescriptor overriding);
743 }
744
745 private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
746 if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
747 if (DataClassUtilsKt.isComponentLike(declared.getName())) {
748 checkOverrideForComponentFunction(declared);
749 }
750 return;
751 }
752
753 if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
754 return;
755 }
756
757 final KtNamedDeclaration member = (KtNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(declared);
758 if (member == null) {
759 throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
760 }
761
762 KtModifierList modifierList = member.getModifierList();
763 boolean hasOverrideNode = modifierList != null && modifierList.hasModifier(KtTokens.OVERRIDE_KEYWORD);
764 Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
765
766 if (hasOverrideNode) {
767 checkOverridesForMemberMarkedOverride(declared, true, new CheckOverrideReportStrategy() {
768 private boolean finalOverriddenError = false;
769 private boolean typeMismatchError = false;
770 private boolean kindMismatchError = false;
771
772 @Override
773 public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
774 if (!finalOverriddenError) {
775 finalOverriddenError = true;
776 trace.report(OVERRIDING_FINAL_MEMBER.on(member, overridden, overridden.getContainingDeclaration()));
777 }
778 }
779
780 @Override
781 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
782 if (!typeMismatchError) {
783 typeMismatchError = true;
784 trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
785 }
786 }
787
788 @Override
789 public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
790 if (!typeMismatchError) {
791 typeMismatchError = true;
792 if (overridden.isVar()) {
793 trace.report(VAR_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
794 }
795 else {
796 trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
797 }
798 }
799 }
800
801 @Override
802 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
803 if (!kindMismatchError) {
804 kindMismatchError = true;
805 trace.report(VAR_OVERRIDDEN_BY_VAL.on(member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
806 }
807 }
808
809 @Override
810 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
811 trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden));
812 }
813
814 @Override
815 public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
816 trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
817 }
818 });
819 }
820 else if (!overriddenDescriptors.isEmpty()) {
821 CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
822 trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
823 }
824 }
825
826 private static void checkInheritedDescriptorsGroup(
827 @NotNull Collection<CallableMemberDescriptor> inheritedDescriptors,
828 @NotNull CallableMemberDescriptor mostSpecific,
829 @NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
830 ) {
831 if (inheritedDescriptors.size() > 1) {
832 PropertyDescriptor mostSpecificProperty = mostSpecific instanceof PropertyDescriptor ? (PropertyDescriptor) mostSpecific : null;
833
834 for (CallableMemberDescriptor inheritedDescriptor : inheritedDescriptors) {
835 if (mostSpecificProperty != null) {
836 assert inheritedDescriptor instanceof PropertyDescriptor
837 : inheritedDescriptor + " inherited from " + mostSpecificProperty + " is not a property";
838 PropertyDescriptor inheritedPropertyDescriptor = (PropertyDescriptor) inheritedDescriptor;
839
840 if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) {
841 reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificProperty, inheritedPropertyDescriptor);
842 }
843 }
844 else if (!isReturnTypeOkForOverride(inheritedDescriptor, mostSpecific)) {
845 reportingStrategy.returnTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor);
846 }
847 }
848 }
849 }
850
851 private static void checkOverridesForMemberMarkedOverride(
852 @NotNull CallableMemberDescriptor declared,
853 boolean checkIfOverridesNothing,
854 @NotNull CheckOverrideReportStrategy reportError
855 ) {
856 Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
857
858 checkOverridesForMember(declared, overriddenDescriptors, reportError);
859
860 if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
861 DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
862 assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
863 ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
864
865 CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
866 if (invisibleOverriddenDescriptor != null) {
867 reportError.cannotOverrideInvisibleMember(declared, invisibleOverriddenDescriptor);
868 }
869 else {
870 reportError.nothingToOverride(declared);
871 }
872 }
873 }
874
875 private static void checkOverridesForMember(
876 @NotNull CallableMemberDescriptor memberDescriptor,
877 @NotNull Collection<? extends CallableMemberDescriptor> overriddenDescriptors,
878 @NotNull CheckOverrideReportStrategy reportError
879 ) {
880 PropertyDescriptor propertyMemberDescriptor =
881 memberDescriptor instanceof PropertyDescriptor ? (PropertyDescriptor) memberDescriptor : null;
882
883 for (CallableMemberDescriptor overridden : overriddenDescriptors) {
884 if (overridden == null) continue;
885
886 if (!ModalityKt.isOverridable(overridden)) {
887 reportError.overridingFinalMember(memberDescriptor, overridden);
888 }
889
890 if (propertyMemberDescriptor != null) {
891 assert overridden instanceof PropertyDescriptor : overridden + " is overridden by property " + propertyMemberDescriptor;
892 PropertyDescriptor overriddenProperty = (PropertyDescriptor) overridden;
893 if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) {
894 reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty);
895 }
896 }
897 else if (!isReturnTypeOkForOverride(overridden, memberDescriptor)) {
898 reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden);
899 }
900
901 if (checkPropertyKind(overridden, true) && checkPropertyKind(memberDescriptor, false)) {
902 reportError.varOverriddenByVal(memberDescriptor, overridden);
903 }
904 }
905 }
906
907 public static boolean isReturnTypeOkForOverride(
908 @NotNull CallableDescriptor superDescriptor,
909 @NotNull CallableDescriptor subDescriptor
910 ) {
911 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
912 if (typeSubstitutor == null) return false;
913
914 KotlinType superReturnType = superDescriptor.getReturnType();
915 assert superReturnType != null;
916
917 KotlinType subReturnType = subDescriptor.getReturnType();
918 assert subReturnType != null;
919
920 KotlinType substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE);
921 assert substitutedSuperReturnType != null;
922
923 return KotlinTypeChecker.DEFAULT.isSubtypeOf(subReturnType, substitutedSuperReturnType);
924 }
925
926 @Nullable
927 private static TypeSubstitutor prepareTypeSubstitutor(
928 @NotNull CallableDescriptor superDescriptor,
929 @NotNull CallableDescriptor subDescriptor
930 ) {
931 List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
932 List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
933 if (subTypeParameters.size() != superTypeParameters.size()) return null;
934
935 ArrayList<TypeProjection> arguments = new ArrayList<TypeProjection>(subTypeParameters.size());
936 for (int i = 0; i < superTypeParameters.size(); i++) {
937 arguments.add(new TypeProjectionImpl(subTypeParameters.get(i).getDefaultType()));
938 }
939
940 return new IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor();
941 }
942
943 public static boolean isPropertyTypeOkForOverride(
944 @NotNull PropertyDescriptor superDescriptor,
945 @NotNull PropertyDescriptor subDescriptor
946 ) {
947 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
948 if (typeSubstitutor == null) return false;
949
950 KotlinType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getType(), Variance.OUT_VARIANCE);
951 assert substitutedSuperReturnType != null;
952
953 if (superDescriptor.isVar()) {
954 return KotlinTypeChecker.DEFAULT.equalTypes(subDescriptor.getType(), substitutedSuperReturnType);
955 }
956 else {
957 return KotlinTypeChecker.DEFAULT.isSubtypeOf(subDescriptor.getType(), substitutedSuperReturnType);
958 }
959 }
960
961 private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
962 final PsiElement dataModifier = findDataModifierForDataClass(componentFunction.getContainingDeclaration());
963
964 checkOverridesForMemberMarkedOverride(componentFunction, false, new CheckOverrideReportStrategy() {
965 private boolean overrideConflict = false;
966
967 @Override
968 public void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
969 if (!overrideConflict) {
970 overrideConflict = true;
971 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
972 }
973 }
974
975 @Override
976 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
977 if (!overrideConflict) {
978 overrideConflict = true;
979 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataModifier, componentFunction, overridden.getContainingDeclaration()));
980 }
981 }
982
983 @Override
984 public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
985 throw new IllegalStateException("Component functions are not properties");
986 }
987
988 @Override
989 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
990 throw new IllegalStateException("Component functions are not properties");
991 }
992
993 @Override
994 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden) {
995 throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
996 }
997
998 @Override
999 public void nothingToOverride(@NotNull CallableMemberDescriptor overriding) {
1000 throw new IllegalStateException("Component functions are OK to override nothing");
1001 }
1002 });
1003 }
1004
1005 @NotNull
1006 private static PsiElement findDataModifierForDataClass(@NotNull DeclarationDescriptor dataClass) {
1007 KtClass classDeclaration = (KtClass) DescriptorToSourceUtils.getSourceFromDescriptor(dataClass);
1008 if (classDeclaration != null && classDeclaration.getModifierList() != null) {
1009 PsiElement modifier = classDeclaration.getModifierList().getModifier(KtTokens.DATA_KEYWORD);
1010 if (modifier != null) {
1011 return modifier;
1012 }
1013 }
1014
1015 throw new IllegalStateException("No data modifier is found for data class " + dataClass);
1016 }
1017
1018 @Nullable
1019 private static CallableMemberDescriptor findInvisibleOverriddenDescriptor(
1020 @NotNull CallableMemberDescriptor declared,
1021 @NotNull ClassDescriptor declaringClass
1022 ) {
1023 for (KotlinType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
1024 Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
1025 all.addAll(supertype.getMemberScope().getContributedFunctions(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
1026 //noinspection unchecked
1027 all.addAll((Collection) supertype.getMemberScope().getContributedVariables(declared.getName(), NoLookupLocation.WHEN_CHECK_OVERRIDES));
1028 for (CallableMemberDescriptor fromSuper : all) {
1029 if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared, null).getResult() == OVERRIDABLE) {
1030 if (Visibilities.isVisibleWithIrrelevantReceiver(fromSuper, declared)) {
1031 throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
1032 " and visible but does not appear in its getOverriddenDescriptors()");
1033 }
1034 return fromSuper;
1035 }
1036 }
1037 }
1038 return null;
1039 }
1040
1041 private void checkParameterOverridesForAllClasses(@NotNull TopDownAnalysisContext c) {
1042 for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) {
1043 for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope())) {
1044 if (member instanceof CallableMemberDescriptor) {
1045 checkOverridesForParameters((CallableMemberDescriptor) member);
1046 }
1047 }
1048 }
1049 }
1050
1051 private void checkOverridesForParameters(@NotNull CallableMemberDescriptor declared) {
1052 boolean isDeclaration = declared.getKind() == CallableMemberDescriptor.Kind.DECLARATION;
1053 if (isDeclaration) {
1054 // No check if the function is not marked as 'override'
1055 KtModifierListOwner declaration = (KtModifierListOwner) DescriptorToSourceUtils.descriptorToDeclaration(declared);
1056 if (declaration != null && !declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) {
1057 return;
1058 }
1059 }
1060
1061 // Let p1 be a parameter of the overriding function
1062 // Let p2 be a parameter of the function being overridden
1063 // Then
1064 // a) p1 is not allowed to have a default value declared
1065 // b) p1 must have the same name as p2
1066 for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
1067 int defaultsInSuper = 0;
1068 for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
1069 if (parameterFromSuperclass.declaresDefaultValue()) {
1070 defaultsInSuper++;
1071 }
1072 }
1073 boolean multipleDefaultsInSuper = defaultsInSuper > 1;
1074
1075 if (isDeclaration) {
1076 checkNameAndDefaultForDeclaredParameter(parameterFromSubclass, multipleDefaultsInSuper);
1077 }
1078 else {
1079 checkNameAndDefaultForFakeOverrideParameter(declared, parameterFromSubclass, multipleDefaultsInSuper);
1080 }
1081 }
1082 }
1083
1084 private void checkNameAndDefaultForDeclaredParameter(@NotNull ValueParameterDescriptor descriptor, boolean multipleDefaultsInSuper) {
1085 KtParameter parameter = (KtParameter) DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
1086 assert parameter != null : "Declaration not found for parameter: " + descriptor;
1087
1088 if (descriptor.declaresDefaultValue()) {
1089 trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
1090 }
1091
1092 if (multipleDefaultsInSuper) {
1093 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, descriptor));
1094 }
1095
1096 for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
1097 if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
1098 //noinspection ConstantConditions
1099 trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(
1100 parameter,
1101 (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(),
1102 parameterFromSuperclass)
1103 );
1104 }
1105 }
1106 }
1107
1108 private void checkNameAndDefaultForFakeOverrideParameter(
1109 @NotNull CallableMemberDescriptor containingFunction,
1110 @NotNull ValueParameterDescriptor descriptor,
1111 boolean multipleDefaultsInSuper
1112 ) {
1113 DeclarationDescriptor containingClass = containingFunction.getContainingDeclaration();
1114 KtClassOrObject classElement = (KtClassOrObject) DescriptorToSourceUtils.descriptorToDeclaration(containingClass);
1115 assert classElement != null : "Declaration not found for class: " + containingClass;
1116
1117 if (multipleDefaultsInSuper) {
1118 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, descriptor));
1119 }
1120
1121 for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
1122 if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
1123 trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(
1124 classElement,
1125 containingFunction.getOverriddenDescriptors(),
1126 parameterFromSuperclass.getIndex() + 1)
1127 );
1128 }
1129 }
1130 }
1131
1132 public static boolean shouldReportParameterNameOverrideWarning(
1133 @NotNull ValueParameterDescriptor parameterFromSubclass,
1134 @NotNull ValueParameterDescriptor parameterFromSuperclass
1135 ) {
1136 return parameterFromSubclass.getContainingDeclaration().hasStableParameterNames() &&
1137 parameterFromSuperclass.getContainingDeclaration().hasStableParameterNames() &&
1138 !parameterFromSuperclass.getName().equals(parameterFromSubclass.getName());
1139 }
1140
1141 private static boolean checkPropertyKind(@NotNull CallableMemberDescriptor descriptor, boolean isVar) {
1142 return descriptor instanceof PropertyDescriptor && ((PropertyDescriptor) descriptor).isVar() == isVar;
1143 }
1144
1145 private void checkVisibility(@NotNull TopDownAnalysisContext c) {
1146 for (Map.Entry<KtCallableDeclaration, CallableMemberDescriptor> entry : c.getMembers().entrySet()) {
1147 checkVisibilityForMember(entry.getKey(), entry.getValue());
1148 if (entry.getKey() instanceof KtProperty && entry.getValue() instanceof PropertyDescriptor) {
1149 KtPropertyAccessor setter = ((KtProperty) entry.getKey()).getSetter();
1150 PropertySetterDescriptor setterDescriptor = ((PropertyDescriptor) entry.getValue()).getSetter();
1151 if (setter != null && setterDescriptor != null) {
1152 checkVisibilityForMember(setter, setterDescriptor);
1153 }
1154 }
1155 }
1156 }
1157
1158 private void checkVisibilityForMember(@NotNull KtDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
1159 Visibility visibility = memberDescriptor.getVisibility();
1160 for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
1161 Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
1162 if (compare == null) {
1163 trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
1164 return;
1165 }
1166 else if (compare < 0) {
1167 trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
1168 return;
1169 }
1170 }
1171 }
1172
1173 @NotNull
1174 public static <D extends CallableMemberDescriptor> Collection<D> getDirectlyOverriddenDeclarations(@NotNull D descriptor) {
1175 Set<D> result = new LinkedHashSet<D>();
1176 //noinspection unchecked
1177 for (D overriddenDescriptor : (Collection<D>) descriptor.getOverriddenDescriptors()) {
1178 CallableMemberDescriptor.Kind kind = overriddenDescriptor.getKind();
1179 if (kind == DECLARATION) {
1180 result.add(overriddenDescriptor);
1181 }
1182 else if (kind == FAKE_OVERRIDE || kind == DELEGATION) {
1183 result.addAll(getDirectlyOverriddenDeclarations(overriddenDescriptor));
1184 }
1185 else if (kind == SYNTHESIZED) {
1186 //do nothing
1187 }
1188 else {
1189 throw new AssertionError("Unexpected callable kind " + kind);
1190 }
1191 }
1192 return filterOutOverridden(result);
1193 }
1194
1195 @NotNull
1196 @ReadOnly
1197 public static <D extends CallableMemberDescriptor> Set<D> getDeepestSuperDeclarations(@NotNull D functionDescriptor) {
1198 Set<D> overriddenDeclarations = DescriptorUtils.getAllOverriddenDeclarations(functionDescriptor);
1199 if (overriddenDeclarations.isEmpty()) {
1200 return Collections.singleton(functionDescriptor);
1201 }
1202
1203 return filterOutOverriding(overriddenDeclarations);
1204 }
1205 }