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