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.containers.ContainerUtil;
025 import com.intellij.util.containers.LinkedMultiMap;
026 import com.intellij.util.containers.MultiMap;
027 import com.intellij.util.containers.hash.EqualityPolicy;
028 import kotlin.Unit;
029 import kotlin.jvm.functions.Function1;
030 import org.jetbrains.annotations.NotNull;
031 import org.jetbrains.annotations.Nullable;
032 import org.jetbrains.annotations.ReadOnly;
033 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
034 import org.jetbrains.kotlin.descriptors.*;
035 import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
036 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
037 import org.jetbrains.kotlin.lexer.JetToken;
038 import org.jetbrains.kotlin.lexer.JetTokens;
039 import org.jetbrains.kotlin.name.Name;
040 import org.jetbrains.kotlin.psi.*;
041 import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
042 import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsPackage;
043 import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
044 import org.jetbrains.kotlin.types.*;
045 import org.jetbrains.kotlin.types.checker.JetTypeChecker;
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 JetDeclaration) {
117 trace.report(CANNOT_INFER_VISIBILITY.on((JetDeclaration) 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).getResult() == OVERRIDABLE
203 && OverridingUtil.DEFAULT.isOverridableBy(me, other).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 (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
241 r.addAll(getCallableMembersFromType(supertype));
242 }
243 return new ArrayList<CallableMemberDescriptor>(r);
244 }
245
246 private static List<CallableMemberDescriptor> getCallableMembersFromType(JetType type) {
247 List<CallableMemberDescriptor> r = Lists.newArrayList();
248 for (DeclarationDescriptor decl : type.getMemberScope().getAllDescriptors()) {
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<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
258 checkOverridesInAClass(entry.getValue(), entry.getKey());
259 }
260 }
261
262 private void checkOverridesInAClass(@NotNull ClassDescriptorWithResolutionScopes classDescriptor, @NotNull JetClassOrObject klass) {
263 // Check overrides for internal consistency
264 for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
265 checkOverrideForMember(member);
266 }
267
268 // Check if everything that must be overridden, actually is
269 // More than one implementation or no implementations at all
270 Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
271 Set<CallableMemberDescriptor> manyImpl = Sets.newLinkedHashSet();
272 collectMissingImplementations(classDescriptor, abstractNoImpl, manyImpl);
273
274 if (!manyImpl.isEmpty()) {
275 trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, manyImpl.iterator().next()));
276 }
277
278 if (!classCanHaveAbstractMembers(classDescriptor) && !abstractNoImpl.isEmpty()) {
279 trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()));
280 }
281 }
282
283 @NotNull
284 public static Set<CallableMemberDescriptor> getMissingImplementations(@NotNull ClassDescriptor classDescriptor) {
285 Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
286 collectMissingImplementations(classDescriptor, result, result);
287 return result;
288 }
289
290 private static void collectMissingImplementations(
291 @NotNull ClassDescriptor classDescriptor,
292 @NotNull Set<CallableMemberDescriptor> abstractNoImpl,
293 @NotNull Set<CallableMemberDescriptor> manyImpl
294 ) {
295 for (DeclarationDescriptor member : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
296 if (member instanceof CallableMemberDescriptor) {
297 collectMissingImplementations((CallableMemberDescriptor) member, abstractNoImpl, manyImpl);
298 }
299 }
300 }
301
302 private static void collectMissingImplementations(
303 @NotNull CallableMemberDescriptor descriptor,
304 @NotNull Set<CallableMemberDescriptor> abstractNoImpl,
305 @NotNull Set<CallableMemberDescriptor> manyImpl
306 ) {
307 if (descriptor.getKind().isReal()) return;
308 if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
309
310 Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
311 if (directOverridden.size() == 0) {
312 throw new IllegalStateException("A 'fake override' must override something");
313 }
314
315 // collects map from the directly overridden descriptor to the set of declarations:
316 // -- if directly overridden is not fake, the set consists of one element: this directly overridden
317 // -- if it's fake, overridden declarations (non-fake) of this descriptor are collected
318 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
319
320 List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
321 Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = filterOutOverridden(
322 Sets.newLinkedHashSet(allOverriddenDeclarations));
323
324 Set<CallableMemberDescriptor> relevantDirectlyOverridden =
325 getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
326
327 List<CallableMemberDescriptor> implementations = collectImplementations(relevantDirectlyOverridden);
328 if (implementations.size() == 1 && isReturnTypeOkForOverride(descriptor, implementations.get(0))) return;
329
330 List<CallableMemberDescriptor> abstractOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
331 List<CallableMemberDescriptor> concreteOverridden = new ArrayList<CallableMemberDescriptor>(allFilteredOverriddenDeclarations.size());
332 filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden);
333
334 if (implementations.isEmpty()) {
335 abstractNoImpl.addAll(abstractOverridden);
336 }
337 else if (implementations.size() > 1) {
338 manyImpl.addAll(concreteOverridden);
339 }
340 else {
341 abstractNoImpl.addAll(collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations.get(0)));
342 }
343 }
344
345 @NotNull
346 private static List<CallableMemberDescriptor> collectImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
347 List<CallableMemberDescriptor> result = new ArrayList<CallableMemberDescriptor>(relevantDirectlyOverridden.size());
348 for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
349 if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
350 result.add(overriddenDescriptor);
351 }
352 }
353 return result;
354 }
355
356 private static void filterNotSynthesizedDescriptorsByModality(
357 @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
358 @NotNull List<CallableMemberDescriptor> abstractOverridden,
359 @NotNull List<CallableMemberDescriptor> concreteOverridden
360 ) {
361 for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
362 if (!CallResolverUtilPackage.isOrOverridesSynthesized(overridden)) {
363 if (overridden.getModality() == Modality.ABSTRACT) {
364 abstractOverridden.add(overridden);
365 }
366 else {
367 concreteOverridden.add(overridden);
368 }
369 }
370 }
371 }
372
373 @NotNull
374 private static List<CallableMemberDescriptor> collectAbstractMethodsWithMoreSpecificReturnType(
375 @NotNull List<CallableMemberDescriptor> abstractOverridden,
376 @NotNull CallableMemberDescriptor implementation
377 ) {
378 List<CallableMemberDescriptor> result = new ArrayList<CallableMemberDescriptor>(abstractOverridden.size());
379 for (CallableMemberDescriptor abstractMember : abstractOverridden) {
380 if (!isReturnTypeOkForOverride(abstractMember, implementation)) {
381 result.add(abstractMember);
382 }
383 }
384 assert !result.isEmpty() : "Implementation (" + implementation + ") doesn't have the most specific type, " +
385 "but none of the other overridden methods does either: " + abstractOverridden;
386 return result;
387 }
388
389 @NotNull
390 private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
391 @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
392 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
393 ) {
394 /* Let the following class hierarchy is declared:
395
396 trait A { fun foo() = 1 }
397 trait B : A
398 trait C : A
399 trait D : A { override fun foo() = 2 }
400 trait E : B, C, D {}
401
402 Traits B and C have fake descriptors for function foo.
403 The map 'overriddenByParent' is:
404 { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
405 This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
406 that are overridden by this descriptor.
407
408 The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
409 In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
410 So only 'foo in D' is relevant.
411
412 Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
413 More precisely directly overridden descriptor is not relevant if:
414 - it's declaration set is a subset of declaration set for other directly overridden descriptor
415 ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
416 - each member of it's declaration set is overridden by a member of other declaration set
417 ('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')
418
419 For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
420 is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
421 are overridden by some other function and corresponding directly overridden descriptor is not relevant.
422 */
423
424 for (Iterator<Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>>> iterator =
425 overriddenByParent.entrySet().iterator(); iterator.hasNext(); ) {
426 if (!isRelevant(iterator.next().getValue(), overriddenByParent.values(), allFilteredOverriddenDeclarations)) {
427 iterator.remove();
428 }
429 }
430 return overriddenByParent.keySet();
431 }
432
433 private static boolean isRelevant(
434 @NotNull Set<CallableMemberDescriptor> declarationSet,
435 @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
436 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
437 ) {
438 for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
439 if (otherSet == declarationSet) continue;
440 if (otherSet.containsAll(declarationSet)) return false;
441 if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
442 }
443 return true;
444 }
445
446 @NotNull
447 private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
448 @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
449 ) {
450 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
451 for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
452 Set<CallableMemberDescriptor> overriddenDeclarations = getOverriddenDeclarations(descriptor);
453 Set<CallableMemberDescriptor> filteredOverrides = filterOutOverridden(overriddenDeclarations);
454 overriddenDeclarationsByDirectParent.put(descriptor, new LinkedHashSet<CallableMemberDescriptor>(filteredOverrides));
455 }
456 return overriddenDeclarationsByDirectParent;
457 }
458
459 /**
460 * @return overridden real descriptors (not fake overrides). Note that all usages of this method should be followed by calling
461 * {@link #filterOutOverridden(java.util.Set)} or {@link #filterOutOverriding(java.util.Set)}, because some of the declarations
462 * can override the other
463 * TODO: merge this method with filterOutOverridden
464 */
465 @NotNull
466 public static Set<CallableMemberDescriptor> getOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) {
467 Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
468 getOverriddenDeclarations(descriptor, result);
469 return result;
470 }
471
472 private static void getOverriddenDeclarations(
473 @NotNull CallableMemberDescriptor descriptor,
474 @NotNull Set<CallableMemberDescriptor> result
475 ) {
476 if (descriptor.getKind().isReal()) {
477 result.add(descriptor);
478 }
479 else {
480 if (descriptor.getOverriddenDescriptors().isEmpty()) {
481 throw new IllegalStateException("No overridden descriptors found for (fake override) " + descriptor);
482 }
483 for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
484 getOverriddenDeclarations(overridden, result);
485 }
486 }
487 }
488
489 private interface CheckOverrideReportStrategy {
490 void overridingFinalMember(@NotNull CallableMemberDescriptor overridden);
491
492 void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
493
494 void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
495
496 void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden);
497
498 void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden);
499
500 void nothingToOverride();
501 }
502
503 private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
504 if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
505 if (DataClassUtilsPackage.isComponentLike(declared.getName())) {
506 checkOverrideForComponentFunction(declared);
507 }
508 return;
509 }
510
511 if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
512 return;
513 }
514
515 final JetNamedDeclaration member = (JetNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(declared);
516 if (member == null) {
517 throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
518 }
519
520 JetModifierList modifierList = member.getModifierList();
521 boolean hasOverrideNode = modifierList != null && modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD);
522 Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
523
524 if (hasOverrideNode) {
525 checkOverridesForMemberMarkedOverride(declared, true, new CheckOverrideReportStrategy() {
526 private boolean finalOverriddenError = false;
527 private boolean typeMismatchError = false;
528 private boolean kindMismatchError = false;
529
530 @Override
531 public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
532 if (!finalOverriddenError) {
533 finalOverriddenError = true;
534 trace.report(OVERRIDING_FINAL_MEMBER.on(member, overridden, overridden.getContainingDeclaration()));
535 }
536 }
537
538 @Override
539 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
540 if (!typeMismatchError) {
541 typeMismatchError = true;
542 trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
543 }
544 }
545
546 @Override
547 public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
548 if (!typeMismatchError) {
549 typeMismatchError = true;
550 trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
551 }
552 }
553
554 @Override
555 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
556 if (!kindMismatchError) {
557 kindMismatchError = true;
558 trace.report(VAR_OVERRIDDEN_BY_VAL.on(member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
559 }
560 }
561
562 @Override
563 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
564 trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden));
565 }
566
567 @Override
568 public void nothingToOverride() {
569 trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
570 }
571 });
572 }
573 else if (!overriddenDescriptors.isEmpty()) {
574 CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
575 trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
576 }
577 }
578
579 private static void checkOverridesForMemberMarkedOverride(
580 @NotNull CallableMemberDescriptor declared,
581 boolean checkIfOverridesNothing,
582 @NotNull CheckOverrideReportStrategy reportError
583 ) {
584 Collection<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
585
586 for (CallableMemberDescriptor overridden : overriddenDescriptors) {
587 if (overridden == null) continue;
588
589 if (!overridden.getModality().isOverridable()) {
590 reportError.overridingFinalMember(overridden);
591 }
592
593 if (declared instanceof PropertyDescriptor &&
594 !isPropertyTypeOkForOverride((PropertyDescriptor) overridden, (PropertyDescriptor) declared)) {
595 reportError.propertyTypeMismatchOnOverride(overridden);
596 }
597 else if (!isReturnTypeOkForOverride(overridden, declared)) {
598 reportError.returnTypeMismatchOnOverride(overridden);
599 }
600
601 if (checkPropertyKind(overridden, true) && checkPropertyKind(declared, false)) {
602 reportError.varOverriddenByVal(overridden);
603 }
604 }
605
606 if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
607 DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
608 assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
609 ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
610
611 CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
612 if (invisibleOverriddenDescriptor != null) {
613 reportError.cannotOverrideInvisibleMember(invisibleOverriddenDescriptor);
614 }
615 else {
616 reportError.nothingToOverride();
617 }
618 }
619 }
620
621 public static boolean isReturnTypeOkForOverride(
622 @NotNull CallableDescriptor superDescriptor,
623 @NotNull CallableDescriptor subDescriptor
624 ) {
625 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
626 if (typeSubstitutor == null) return false;
627
628 JetType superReturnType = superDescriptor.getReturnType();
629 assert superReturnType != null;
630
631 JetType subReturnType = subDescriptor.getReturnType();
632 assert subReturnType != null;
633
634 JetType substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE);
635 assert substitutedSuperReturnType != null;
636
637 return JetTypeChecker.DEFAULT.isSubtypeOf(subReturnType, substitutedSuperReturnType);
638 }
639
640 @Nullable
641 private static TypeSubstitutor prepareTypeSubstitutor(
642 @NotNull CallableDescriptor superDescriptor,
643 @NotNull CallableDescriptor subDescriptor
644 ) {
645 List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
646 List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
647 if (subTypeParameters.size() != superTypeParameters.size()) return null;
648
649 ArrayList<TypeProjection> arguments = new ArrayList<TypeProjection>(subTypeParameters.size());
650 for (int i = 0; i < superTypeParameters.size(); i++) {
651 arguments.add(new TypeProjectionImpl(subTypeParameters.get(i).getDefaultType()));
652 }
653
654 return new IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor();
655 }
656
657 public static boolean isPropertyTypeOkForOverride(
658 @NotNull PropertyDescriptor superDescriptor,
659 @NotNull PropertyDescriptor subDescriptor
660 ) {
661 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
662 if (typeSubstitutor == null) return false;
663
664 if (!superDescriptor.isVar()) return true;
665
666 JetType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getType(), Variance.OUT_VARIANCE);
667 assert substitutedSuperReturnType != null;
668 return JetTypeChecker.DEFAULT.equalTypes(subDescriptor.getType(), substitutedSuperReturnType);
669 }
670
671 private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
672 final PsiElement dataAnnotation = findDataAnnotationForDataClass(componentFunction.getContainingDeclaration());
673
674 checkOverridesForMemberMarkedOverride(componentFunction, false, new CheckOverrideReportStrategy() {
675 private boolean overrideConflict = false;
676
677 @Override
678 public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
679 if (!overrideConflict) {
680 overrideConflict = true;
681 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
682 }
683 }
684
685 @Override
686 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
687 if (!overrideConflict) {
688 overrideConflict = true;
689 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
690 }
691 }
692
693 @Override
694 public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
695 throw new IllegalStateException("Component functions are not properties");
696 }
697
698 @Override
699 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
700 throw new IllegalStateException("Component functions are not properties");
701 }
702
703 @Override
704 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
705 throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
706 }
707
708 @Override
709 public void nothingToOverride() {
710 throw new IllegalStateException("Component functions are OK to override nothing");
711 }
712 });
713 }
714
715 @NotNull
716 private static PsiElement findDataAnnotationForDataClass(@NotNull DeclarationDescriptor dataClass) {
717 AnnotationDescriptor annotation = dataClass.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.data);
718 if (annotation != null) {
719 JetAnnotationEntry entry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation);
720 if (entry != null) {
721 return entry;
722 }
723 }
724
725
726 JetClass classDeclaration = (JetClass) DescriptorToSourceUtils.getSourceFromDescriptor(dataClass);
727 if (classDeclaration != null && classDeclaration.getModifierList() != null) {
728 PsiElement modifier = classDeclaration.getModifierList().getModifier(JetTokens.DATA_KEYWORD);
729 if (modifier != null) {
730 return modifier;
731 }
732 }
733
734 throw new IllegalStateException("No data annotation is found for data class " + dataClass);
735 }
736
737 @Nullable
738 private static CallableMemberDescriptor findInvisibleOverriddenDescriptor(
739 @NotNull CallableMemberDescriptor declared,
740 @NotNull ClassDescriptor declaringClass
741 ) {
742 for (JetType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
743 Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
744 all.addAll(supertype.getMemberScope().getFunctions(declared.getName(), NoLookupLocation.UNSORTED));
745 //noinspection unchecked
746 all.addAll((Collection) supertype.getMemberScope().getProperties(declared.getName(), NoLookupLocation.UNSORTED));
747 for (CallableMemberDescriptor fromSuper : all) {
748 if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) {
749 if (Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSuper, declared)) {
750 throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
751 " and visible but does not appear in its getOverriddenDescriptors()");
752 }
753 return fromSuper;
754 }
755 }
756 }
757 return null;
758 }
759
760 private void checkParameterOverridesForAllClasses(@NotNull TopDownAnalysisContext c) {
761 for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) {
762 for (DeclarationDescriptor member : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
763 if (member instanceof CallableMemberDescriptor) {
764 checkOverridesForParameters((CallableMemberDescriptor) member);
765 }
766 }
767 }
768 }
769
770 private void checkOverridesForParameters(@NotNull CallableMemberDescriptor declared) {
771 boolean isDeclaration = declared.getKind() == CallableMemberDescriptor.Kind.DECLARATION;
772 if (isDeclaration) {
773 // No check if the function is not marked as 'override'
774 JetModifierListOwner declaration = (JetModifierListOwner) DescriptorToSourceUtils.descriptorToDeclaration(declared);
775 if (declaration != null && !declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
776 return;
777 }
778 }
779
780 // Let p1 be a parameter of the overriding function
781 // Let p2 be a parameter of the function being overridden
782 // Then
783 // a) p1 is not allowed to have a default value declared
784 // b) p1 must have the same name as p2
785 for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
786 int defaultsInSuper = 0;
787 for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
788 if (parameterFromSuperclass.declaresDefaultValue()) {
789 defaultsInSuper++;
790 }
791 }
792 boolean multipleDefaultsInSuper = defaultsInSuper > 1;
793
794 if (isDeclaration) {
795 checkNameAndDefaultForDeclaredParameter(parameterFromSubclass, multipleDefaultsInSuper);
796 }
797 else {
798 checkNameAndDefaultForFakeOverrideParameter(declared, parameterFromSubclass, multipleDefaultsInSuper);
799 }
800 }
801 }
802
803 private void checkNameAndDefaultForDeclaredParameter(@NotNull ValueParameterDescriptor descriptor, boolean multipleDefaultsInSuper) {
804 JetParameter parameter = (JetParameter) DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
805 assert parameter != null : "Declaration not found for parameter: " + descriptor;
806
807 if (descriptor.declaresDefaultValue()) {
808 trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
809 }
810
811 if (multipleDefaultsInSuper) {
812 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, descriptor));
813 }
814
815 for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
816 if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
817 //noinspection ConstantConditions
818 trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(
819 parameter,
820 (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(),
821 parameterFromSuperclass)
822 );
823 }
824 }
825 }
826
827 private void checkNameAndDefaultForFakeOverrideParameter(
828 @NotNull CallableMemberDescriptor containingFunction,
829 @NotNull ValueParameterDescriptor descriptor,
830 boolean multipleDefaultsInSuper
831 ) {
832 DeclarationDescriptor containingClass = containingFunction.getContainingDeclaration();
833 JetClassOrObject classElement = (JetClassOrObject) DescriptorToSourceUtils.descriptorToDeclaration(containingClass);
834 assert classElement != null : "Declaration not found for class: " + containingClass;
835
836 if (multipleDefaultsInSuper) {
837 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, descriptor));
838 }
839
840 for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
841 if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
842 trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(
843 classElement,
844 containingFunction.getOverriddenDescriptors(),
845 parameterFromSuperclass.getIndex() + 1)
846 );
847 }
848 }
849 }
850
851 public static boolean shouldReportParameterNameOverrideWarning(
852 @NotNull ValueParameterDescriptor parameterFromSubclass,
853 @NotNull ValueParameterDescriptor parameterFromSuperclass
854 ) {
855 return parameterFromSubclass.getContainingDeclaration().hasStableParameterNames() &&
856 parameterFromSuperclass.getContainingDeclaration().hasStableParameterNames() &&
857 !parameterFromSuperclass.getName().equals(parameterFromSubclass.getName());
858 }
859
860 private static boolean checkPropertyKind(@NotNull CallableMemberDescriptor descriptor, boolean isVar) {
861 return descriptor instanceof PropertyDescriptor && ((PropertyDescriptor) descriptor).isVar() == isVar;
862 }
863
864 private void checkVisibility(@NotNull TopDownAnalysisContext c) {
865 for (Map.Entry<JetCallableDeclaration, CallableMemberDescriptor> entry : c.getMembers().entrySet()) {
866 checkVisibilityForMember(entry.getKey(), entry.getValue());
867 }
868 }
869
870 private void checkVisibilityForMember(@NotNull JetDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
871 Visibility visibility = memberDescriptor.getVisibility();
872 for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
873 Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
874 if (compare == null) {
875 trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
876 return;
877 }
878 else if (compare < 0) {
879 trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
880 return;
881 }
882 }
883 }
884
885 @NotNull
886 public static <D extends CallableMemberDescriptor> Collection<D> getDirectlyOverriddenDeclarations(@NotNull D descriptor) {
887 Set<D> result = new LinkedHashSet<D>();
888 //noinspection unchecked
889 for (D overriddenDescriptor : (Collection<D>) descriptor.getOverriddenDescriptors()) {
890 CallableMemberDescriptor.Kind kind = overriddenDescriptor.getKind();
891 if (kind == DECLARATION) {
892 result.add(overriddenDescriptor);
893 }
894 else if (kind == FAKE_OVERRIDE || kind == DELEGATION) {
895 result.addAll(getDirectlyOverriddenDeclarations(overriddenDescriptor));
896 }
897 else if (kind == SYNTHESIZED) {
898 //do nothing
899 }
900 else {
901 throw new AssertionError("Unexpected callable kind " + kind);
902 }
903 }
904 return filterOutOverridden(result);
905 }
906
907 @NotNull
908 @ReadOnly
909 public static <D extends CallableMemberDescriptor> Set<D> getDeepestSuperDeclarations(@NotNull D functionDescriptor) {
910 Set<D> overriddenDeclarations = DescriptorUtils.getAllOverriddenDeclarations(functionDescriptor);
911 if (overriddenDeclarations.isEmpty()) {
912 return Collections.singleton(functionDescriptor);
913 }
914
915 return filterOutOverriding(overriddenDeclarations);
916 }
917 }