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