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