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