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.base.Predicate; 020 import com.google.common.collect.*; 021 import com.intellij.util.Function; 022 import com.intellij.util.containers.ContainerUtil; 023 import org.jetbrains.annotations.NotNull; 024 import org.jetbrains.annotations.Nullable; 025 import org.jetbrains.jet.lang.descriptors.*; 026 import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorImpl; 027 import org.jetbrains.jet.lang.descriptors.impl.PropertyAccessorDescriptorImpl; 028 import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl; 029 import org.jetbrains.jet.lang.resolve.name.Name; 030 import org.jetbrains.jet.lang.types.*; 031 import org.jetbrains.jet.lang.types.checker.JetTypeChecker; 032 033 import java.util.*; 034 035 import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT; 036 import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE; 037 038 public class OverridingUtil { 039 040 private static final List<ExternalOverridabilityCondition> EXTERNAL_CONDITIONS = 041 ContainerUtil.collect(ServiceLoader.load( 042 ExternalOverridabilityCondition.class, 043 ExternalOverridabilityCondition.class.getClassLoader()).iterator() 044 ); 045 046 private OverridingUtil() { 047 } 048 049 private static enum Filtering { 050 RETAIN_OVERRIDING, 051 RETAIN_OVERRIDDEN 052 } 053 054 @NotNull 055 public static <D extends CallableDescriptor> Set<D> filterOutOverridden(@NotNull Set<D> candidateSet) { 056 return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDING); 057 } 058 059 @NotNull 060 public static <D> Set<D> filterOutOverriding(@NotNull Set<D> candidateSet) { 061 return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDDEN); 062 } 063 064 @NotNull 065 public static <D> Set<D> filterOutOverridden( 066 @NotNull Set<D> candidateSet, 067 @NotNull Function<? super D, ? extends CallableDescriptor> transform 068 ) { 069 return filterOverrides(candidateSet, transform, Filtering.RETAIN_OVERRIDING); 070 } 071 072 @NotNull 073 private static <D> Set<D> filterOverrides( 074 @NotNull Set<D> candidateSet, 075 @NotNull Function<? super D, ? extends CallableDescriptor> transform, 076 @NotNull Filtering filtering 077 ) { 078 Set<D> candidates = Sets.newLinkedHashSet(); 079 outerLoop: 080 for (D meD : candidateSet) { 081 CallableDescriptor me = transform.fun(meD); 082 for (D otherD : candidateSet) { 083 CallableDescriptor other = transform.fun(otherD); 084 if (me == other) continue; 085 if (filtering == Filtering.RETAIN_OVERRIDING) { 086 if (overrides(other, me)) { 087 continue outerLoop; 088 } 089 } 090 else if (filtering == Filtering.RETAIN_OVERRIDDEN) { 091 if (overrides(me, other)) { 092 continue outerLoop; 093 } 094 } 095 else { 096 throw new AssertionError("Unexpected Filtering object: " + filtering); 097 } 098 } 099 for (D otherD : candidates) { 100 CallableDescriptor other = transform.fun(otherD); 101 if (me.getOriginal() == other.getOriginal() 102 && isOverridableBy(other, me).getResult() == OverrideCompatibilityInfo.Result.OVERRIDABLE 103 && isOverridableBy(me, other).getResult() == OverrideCompatibilityInfo.Result.OVERRIDABLE) { 104 continue outerLoop; 105 } 106 } 107 candidates.add(meD); 108 } 109 return candidates; 110 } 111 112 public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) { 113 CallableDescriptor originalG = g.getOriginal(); 114 for (CallableDescriptor overriddenFunction : getAllOverriddenDescriptors(f)) { 115 if (originalG.equals(overriddenFunction.getOriginal())) return true; 116 } 117 return false; 118 } 119 120 public static Set<CallableDescriptor> getAllOverriddenDescriptors(CallableDescriptor f) { 121 Set<CallableDescriptor> overriddenDescriptors = Sets.newHashSet(); 122 collectAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors); 123 return overriddenDescriptors; 124 } 125 126 private static void collectAllOverriddenDescriptors( 127 @NotNull CallableDescriptor current, 128 @NotNull Set<CallableDescriptor> result 129 ) { 130 if (result.contains(current)) return; 131 for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) { 132 collectAllOverriddenDescriptors(descriptor, result); 133 result.add(descriptor); 134 } 135 } 136 137 @NotNull 138 public static OverrideCompatibilityInfo isOverridableBy(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { 139 if (superDescriptor instanceof FunctionDescriptor) { 140 if (!(subDescriptor instanceof FunctionDescriptor)) return OverrideCompatibilityInfo.memberKindMismatch(); 141 } 142 else if (superDescriptor instanceof PropertyDescriptor) { 143 if (!(subDescriptor instanceof PropertyDescriptor)) return OverrideCompatibilityInfo.memberKindMismatch(); 144 } 145 else { 146 throw new IllegalArgumentException("This type of CallableDescriptor cannot be checked for overridability: " + superDescriptor); 147 } 148 149 // TODO: check outside of this method 150 if (!superDescriptor.getName().equals(subDescriptor.getName())) { 151 return OverrideCompatibilityInfo.nameMismatch(); 152 } 153 154 return isOverridableByImpl(superDescriptor, subDescriptor, true); 155 } 156 157 private static List<JetType> compiledValueParameters(CallableDescriptor callableDescriptor) { 158 ReceiverParameterDescriptor receiverParameter = callableDescriptor.getReceiverParameter(); 159 ArrayList<JetType> parameters = new ArrayList<JetType>(); 160 if (receiverParameter != null) { 161 parameters.add(receiverParameter.getType()); 162 } 163 for (ValueParameterDescriptor valueParameterDescriptor : callableDescriptor.getValueParameters()) { 164 parameters.add(valueParameterDescriptor.getType()); 165 } 166 return parameters; 167 } 168 169 /** 170 * @param forOverride true for override, false for overload 171 */ 172 static OverrideCompatibilityInfo isOverridableByImpl(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor, boolean forOverride) { 173 174 // TODO : Visibility 175 176 if ((superDescriptor.getReceiverParameter() == null) != (subDescriptor.getReceiverParameter() == null)) { 177 return OverrideCompatibilityInfo.receiverPresenceMismatch(); 178 } 179 180 if (superDescriptor.getValueParameters().size() != subDescriptor.getValueParameters().size()) { 181 return OverrideCompatibilityInfo.valueParameterNumberMismatch(); 182 } 183 184 List<JetType> superValueParameters = compiledValueParameters(superDescriptor); 185 List<JetType> subValueParameters = compiledValueParameters(subDescriptor); 186 187 if (forOverride) { 188 if (superDescriptor.getTypeParameters().size() != subDescriptor.getTypeParameters().size()) { 189 for (int i = 0; i < superValueParameters.size(); ++i) { 190 JetType superValueParameterType = getUpperBound(superValueParameters.get(i)); 191 JetType subValueParameterType = getUpperBound(subValueParameters.get(i)); 192 // TODO: compare erasure 193 if (!JetTypeChecker.INSTANCE.equalTypes(superValueParameterType, subValueParameterType)) { 194 return OverrideCompatibilityInfo.typeParameterNumberMismatch(); 195 } 196 } 197 return OverrideCompatibilityInfo.valueParameterTypeMismatch(null, null, OverrideCompatibilityInfo.Result.CONFLICT); 198 } 199 } 200 201 if (forOverride) { 202 203 List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters(); 204 List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters(); 205 206 BiMap<TypeConstructor, TypeConstructor> axioms = HashBiMap.create(); 207 for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) { 208 TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); 209 TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); 210 axioms.put(superTypeParameter.getTypeConstructor(), subTypeParameter.getTypeConstructor()); 211 } 212 213 for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) { 214 TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); 215 TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); 216 217 if (!JetTypeChecker.INSTANCE.equalTypes(superTypeParameter.getUpperBoundsAsType(), subTypeParameter.getUpperBoundsAsType(), axioms)) { 218 return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter); 219 } 220 } 221 222 for (int i = 0, unsubstitutedValueParametersSize = superValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { 223 JetType superValueParameter = superValueParameters.get(i); 224 JetType subValueParameter = subValueParameters.get(i); 225 226 boolean bothErrors = superValueParameter.isError() && subValueParameter.isError(); 227 if (!bothErrors && !JetTypeChecker.INSTANCE.equalTypes(superValueParameter, subValueParameter, axioms)) { 228 return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameter, subValueParameter, OverrideCompatibilityInfo.Result.INCOMPATIBLE); 229 } 230 } 231 232 for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) { 233 if (!externalCondition.isOverridable(superDescriptor, subDescriptor)) { 234 return OverrideCompatibilityInfo.externalConditionFailed(externalCondition.getClass()); 235 } 236 } 237 } 238 else { 239 240 for (int i = 0; i < superValueParameters.size(); ++i) { 241 JetType superValueParameterType = getUpperBound(superValueParameters.get(i)); 242 JetType subValueParameterType = getUpperBound(subValueParameters.get(i)); 243 // TODO: compare erasure 244 if (!JetTypeChecker.INSTANCE.equalTypes(superValueParameterType, subValueParameterType)) { 245 return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameterType, subValueParameterType, OverrideCompatibilityInfo.Result.INCOMPATIBLE); 246 } 247 } 248 249 return OverrideCompatibilityInfo.success(); 250 251 } 252 253 // TODO : Default values, varargs etc 254 255 return OverrideCompatibilityInfo.success(); 256 } 257 258 private static JetType getUpperBound(JetType type) { 259 if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { 260 return type; 261 } 262 else if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { 263 return ((TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor()).getUpperBoundsAsType(); 264 } 265 else { 266 throw new IllegalStateException("unknown type constructor: " + type.getConstructor().getClass().getName()); 267 } 268 } 269 270 public static boolean isReturnTypeOkForOverride(@NotNull JetTypeChecker typeChecker, @NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { 271 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor); 272 if (typeSubstitutor == null) return false; 273 274 JetType superReturnType = superDescriptor.getReturnType(); 275 assert superReturnType != null; 276 277 JetType subReturnType = subDescriptor.getReturnType(); 278 assert subReturnType != null; 279 280 JetType substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE); 281 assert substitutedSuperReturnType != null; 282 283 return typeChecker.isSubtypeOf(subReturnType, substitutedSuperReturnType); 284 } 285 286 @Nullable 287 private static TypeSubstitutor prepareTypeSubstitutor(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { 288 List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters(); 289 List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters(); 290 if (subTypeParameters.size() != superTypeParameters.size()) return null; 291 292 Map<TypeConstructor, TypeProjection> substitutionContext = Maps.newHashMap(); 293 for (int i = 0; i < superTypeParameters.size(); i++) { 294 TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); 295 TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); 296 substitutionContext.put( 297 superTypeParameter.getTypeConstructor(), 298 new TypeProjectionImpl(subTypeParameter.getDefaultType())); 299 } 300 return TypeSubstitutor.create(substitutionContext); 301 } 302 303 public static boolean isPropertyTypeOkForOverride(@NotNull JetTypeChecker typeChecker, @NotNull PropertyDescriptor superDescriptor, @NotNull PropertyDescriptor subDescriptor) { 304 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor); 305 JetType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getReturnType(), Variance.OUT_VARIANCE); 306 assert substitutedSuperReturnType != null; 307 if (superDescriptor.isVar() && !typeChecker.equalTypes(subDescriptor.getReturnType(), substitutedSuperReturnType)) { 308 return false; 309 } 310 311 return true; 312 } 313 314 /** 315 * Get overridden descriptors that are declarations or delegations. 316 * 317 * @see CallableMemberDescriptor.Kind#isReal() 318 */ 319 public static Collection<CallableMemberDescriptor> getOverriddenDeclarations(CallableMemberDescriptor descriptor) { 320 Map<ClassDescriptor, CallableMemberDescriptor> result = Maps.newHashMap(); 321 getOverriddenDeclarations(descriptor, result); 322 return result.values(); 323 } 324 325 private static void getOverriddenDeclarations(CallableMemberDescriptor descriptor, Map<ClassDescriptor, CallableMemberDescriptor> r) { 326 if (descriptor.getKind().isReal()) { 327 r.put((ClassDescriptor) descriptor.getContainingDeclaration(), descriptor); 328 } 329 else { 330 if (descriptor.getOverriddenDescriptors().isEmpty()) { 331 throw new IllegalStateException("No overridden descriptors found for (fake override) " + descriptor); 332 } 333 for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) { 334 getOverriddenDeclarations(overridden, r); 335 } 336 } 337 } 338 339 public static void bindOverride(CallableMemberDescriptor fromCurrent, CallableMemberDescriptor fromSupertype) { 340 fromCurrent.addOverriddenDescriptor(fromSupertype); 341 342 for (ValueParameterDescriptor parameterFromCurrent : fromCurrent.getValueParameters()) { 343 assert parameterFromCurrent.getIndex() < fromSupertype.getValueParameters().size() 344 : "An override relation between functions implies that they have the same number of value parameters"; 345 ValueParameterDescriptor parameterFromSupertype = fromSupertype.getValueParameters().get(parameterFromCurrent.getIndex()); 346 parameterFromCurrent.addOverriddenDescriptor(parameterFromSupertype); 347 } 348 } 349 350 public static void generateOverridesInFunctionGroup( 351 @SuppressWarnings("UnusedParameters") 352 @NotNull Name name, //DO NOT DELETE THIS PARAMETER: needed to make sure all descriptors have the same name 353 @NotNull Collection<? extends CallableMemberDescriptor> membersFromSupertypes, 354 @NotNull Collection<? extends CallableMemberDescriptor> membersFromCurrent, 355 @NotNull ClassDescriptor current, 356 @NotNull DescriptorSink sink 357 ) { 358 Collection<CallableMemberDescriptor> notOverridden = Sets.newLinkedHashSet(membersFromSupertypes); 359 360 for (CallableMemberDescriptor fromCurrent : membersFromCurrent) { 361 Collection<CallableMemberDescriptor> bound = 362 extractAndBindOverridesForMember(fromCurrent, membersFromSupertypes, current, sink); 363 notOverridden.removeAll(bound); 364 } 365 366 createAndBindFakeOverrides(current, notOverridden, sink); 367 } 368 369 private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember( 370 @NotNull CallableMemberDescriptor fromCurrent, 371 @NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper, 372 @NotNull ClassDescriptor current, 373 @NotNull DescriptorSink sink 374 ) { 375 Collection<CallableMemberDescriptor> bound = Lists.newArrayList(); 376 for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) { 377 OverrideCompatibilityInfo.Result result = isOverridableBy(fromSupertype, fromCurrent).getResult(); 378 379 boolean isVisible = Visibilities.isVisible(fromSupertype, current); 380 switch (result) { 381 case OVERRIDABLE: 382 if (isVisible) { 383 bindOverride(fromCurrent, fromSupertype); 384 } 385 bound.add(fromSupertype); 386 break; 387 case CONFLICT: 388 if (isVisible) { 389 sink.conflict(fromSupertype, fromCurrent); 390 } 391 bound.add(fromSupertype); 392 break; 393 case INCOMPATIBLE: 394 break; 395 } 396 } 397 return bound; 398 } 399 400 private static void createAndBindFakeOverrides( 401 @NotNull ClassDescriptor current, 402 @NotNull Collection<CallableMemberDescriptor> notOverridden, 403 @NotNull DescriptorSink sink 404 ) { 405 Queue<CallableMemberDescriptor> fromSuperQueue = new LinkedList<CallableMemberDescriptor>(notOverridden); 406 while (!fromSuperQueue.isEmpty()) { 407 CallableMemberDescriptor notOverriddenFromSuper = VisibilityUtil.findMemberWithMaxVisibility(fromSuperQueue); 408 Collection<CallableMemberDescriptor> overridables = 409 extractMembersOverridableInBothWays(notOverriddenFromSuper, fromSuperQueue, sink); 410 createAndBindFakeOverride(overridables, current, sink); 411 } 412 } 413 414 private static boolean isMoreSpecific(@NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) { 415 if (a instanceof SimpleFunctionDescriptor) { 416 assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass(); 417 418 JetType aReturnType = a.getReturnType(); 419 assert aReturnType != null; 420 JetType bReturnType = b.getReturnType(); 421 assert bReturnType != null; 422 423 return JetTypeChecker.INSTANCE.isSubtypeOf(aReturnType, bReturnType); 424 } 425 if (a instanceof PropertyDescriptor) { 426 assert b instanceof PropertyDescriptor : "b is " + b.getClass(); 427 428 if (((PropertyDescriptor) a).isVar() || ((PropertyDescriptor) b).isVar()) { 429 return ((PropertyDescriptor) a).isVar(); 430 } 431 432 // both vals 433 return JetTypeChecker.INSTANCE.isSubtypeOf(((PropertyDescriptor) a).getType(), ((PropertyDescriptor) b).getType()); 434 } 435 throw new IllegalArgumentException("Unexpected callable: " + a.getClass()); 436 } 437 438 private static CallableMemberDescriptor selectMostSpecificMemberFromSuper(@NotNull Collection<CallableMemberDescriptor> overridables) { 439 CallableMemberDescriptor result = null; 440 for (CallableMemberDescriptor overridable : overridables) { 441 if (result == null || isMoreSpecific(overridable, result)) { 442 result = overridable; 443 } 444 } 445 return result; 446 } 447 448 private static void createAndBindFakeOverride( 449 @NotNull Collection<CallableMemberDescriptor> overridables, 450 @NotNull ClassDescriptor current, 451 @NotNull DescriptorSink sink 452 ) { 453 Collection<CallableMemberDescriptor> visibleOverridables = filterVisibleFakeOverrides(current, overridables); 454 Modality modality = getMinimalModality(visibleOverridables); 455 boolean allInvisible = visibleOverridables.isEmpty(); 456 Collection<CallableMemberDescriptor> effectiveOverridden = allInvisible ? overridables : visibleOverridables; 457 Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED; 458 CallableMemberDescriptor mostSpecific = selectMostSpecificMemberFromSuper(effectiveOverridden); 459 CallableMemberDescriptor fakeOverride = 460 mostSpecific.copy(current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false); 461 for (CallableMemberDescriptor descriptor : effectiveOverridden) { 462 bindOverride(fakeOverride, descriptor); 463 } 464 sink.addToScope(fakeOverride); 465 } 466 467 @NotNull 468 private static Modality getMinimalModality(@NotNull Collection<CallableMemberDescriptor> descriptors) { 469 Modality modality = Modality.ABSTRACT; 470 for (CallableMemberDescriptor descriptor : descriptors) { 471 if (descriptor.getModality().compareTo(modality) < 0) { 472 modality = descriptor.getModality(); 473 } 474 } 475 return modality; 476 } 477 478 @NotNull 479 private static Collection<CallableMemberDescriptor> filterVisibleFakeOverrides( 480 @NotNull final ClassDescriptor current, 481 @NotNull Collection<CallableMemberDescriptor> toFilter 482 ) { 483 return Collections2.filter(toFilter, new Predicate<CallableMemberDescriptor>() { 484 @Override 485 public boolean apply(@Nullable CallableMemberDescriptor descriptor) { 486 //nested class could capture private member, so check for private visibility added 487 return descriptor != null && 488 descriptor.getVisibility() != Visibilities.PRIVATE && 489 Visibilities.isVisible(descriptor, current); 490 } 491 }); 492 } 493 494 @NotNull 495 private static Collection<CallableMemberDescriptor> extractMembersOverridableInBothWays( 496 @NotNull CallableMemberDescriptor overrider, 497 @NotNull Queue<CallableMemberDescriptor> extractFrom, 498 @NotNull DescriptorSink sink 499 ) { 500 Collection<CallableMemberDescriptor> overridable = Lists.newArrayList(); 501 overridable.add(overrider); 502 for (Iterator<CallableMemberDescriptor> iterator = extractFrom.iterator(); iterator.hasNext(); ) { 503 CallableMemberDescriptor candidate = iterator.next(); 504 if (overrider == candidate) { 505 iterator.remove(); 506 continue; 507 } 508 509 OverrideCompatibilityInfo.Result result1 = isOverridableBy(candidate, overrider).getResult(); 510 OverrideCompatibilityInfo.Result result2 = isOverridableBy(overrider, candidate).getResult(); 511 if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) { 512 overridable.add(candidate); 513 iterator.remove(); 514 } 515 else if (result1 == CONFLICT || result2 == CONFLICT) { 516 sink.conflict(overrider, candidate); 517 iterator.remove(); 518 } 519 } 520 return overridable; 521 } 522 523 public static void resolveUnknownVisibilityForMember( 524 @NotNull CallableMemberDescriptor memberDescriptor, 525 @NotNull NotInferredVisibilitySink sink 526 ) { 527 for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) { 528 if (descriptor.getVisibility() == Visibilities.INHERITED) { 529 resolveUnknownVisibilityForMember(descriptor, sink); 530 } 531 } 532 533 if (memberDescriptor.getVisibility() != Visibilities.INHERITED) { 534 return; 535 } 536 537 Visibility visibilityToInherit = computeVisibilityToInherit(memberDescriptor, sink); 538 if (memberDescriptor instanceof PropertyDescriptorImpl) { 539 ((PropertyDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit); 540 for (PropertyAccessorDescriptor accessor : ((PropertyDescriptor) memberDescriptor).getAccessors()) { 541 resolveUnknownVisibilityForMember(accessor, sink); 542 } 543 } 544 else if (memberDescriptor instanceof FunctionDescriptorImpl) { 545 ((FunctionDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit); 546 } 547 else { 548 assert memberDescriptor instanceof PropertyAccessorDescriptorImpl; 549 ((PropertyAccessorDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit); 550 } 551 } 552 553 @NotNull 554 private static Visibility computeVisibilityToInherit( 555 @NotNull CallableMemberDescriptor memberDescriptor, 556 @NotNull NotInferredVisibilitySink sink 557 ) { 558 Visibility maxVisibility = findMaxVisibility(memberDescriptor.getOverriddenDescriptors()); 559 if (maxVisibility == null) { 560 sink.cannotInferVisibility(memberDescriptor); 561 return Visibilities.PUBLIC; 562 } 563 if (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { 564 return maxVisibility; 565 } 566 return maxVisibility.normalize(); 567 } 568 569 @Nullable 570 private static Visibility findMaxVisibility(@NotNull Collection<? extends CallableMemberDescriptor> descriptors) { 571 if (descriptors.isEmpty()) { 572 return Visibilities.INTERNAL; 573 } 574 Visibility maxVisibility = null; 575 for (CallableMemberDescriptor descriptor : descriptors) { 576 Visibility visibility = descriptor.getVisibility(); 577 assert visibility != Visibilities.INHERITED; 578 if (maxVisibility == null) { 579 maxVisibility = visibility; 580 continue; 581 } 582 Integer compareResult = Visibilities.compare(visibility, maxVisibility); 583 if (compareResult == null) { 584 maxVisibility = null; 585 } 586 else if (compareResult > 0) { 587 maxVisibility = visibility; 588 } 589 } 590 if (maxVisibility == null) { 591 return null; 592 } 593 for (CallableMemberDescriptor descriptor : descriptors) { 594 Integer compareResult = Visibilities.compare(maxVisibility, descriptor.getVisibility()); 595 if (compareResult == null || compareResult < 0) { 596 return null; 597 } 598 } 599 return maxVisibility; 600 } 601 602 public interface DescriptorSink { 603 void addToScope(@NotNull CallableMemberDescriptor fakeOverride); 604 605 void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent); 606 } 607 608 public interface NotInferredVisibilitySink { 609 void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor); 610 } 611 612 public static class OverrideCompatibilityInfo { 613 614 public enum Result { 615 OVERRIDABLE, 616 INCOMPATIBLE, 617 CONFLICT, 618 } 619 620 private static final OverrideCompatibilityInfo SUCCESS = new OverrideCompatibilityInfo(Result.OVERRIDABLE, "SUCCESS"); 621 622 @NotNull 623 public static OverrideCompatibilityInfo success() { 624 return SUCCESS; 625 } 626 627 @NotNull 628 public static OverrideCompatibilityInfo nameMismatch() { 629 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "nameMismatch"); // TODO 630 } 631 632 @NotNull 633 public static OverrideCompatibilityInfo typeParameterNumberMismatch() { 634 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "typeParameterNumberMismatch"); // TODO 635 } 636 637 @NotNull 638 public static OverrideCompatibilityInfo receiverPresenceMismatch() { 639 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "receiverPresenceMismatch"); // TODO 640 } 641 642 @NotNull 643 public static OverrideCompatibilityInfo valueParameterNumberMismatch() { 644 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "valueParameterNumberMismatch"); // TODO 645 } 646 647 @NotNull 648 public static OverrideCompatibilityInfo boundsMismatch(TypeParameterDescriptor superTypeParameter, TypeParameterDescriptor subTypeParameter) { 649 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "boundsMismatch"); // TODO 650 } 651 652 @NotNull 653 public static OverrideCompatibilityInfo valueParameterTypeMismatch(JetType superValueParameter, JetType subValueParameter, Result result) { 654 return new OverrideCompatibilityInfo(result, "valueParameterTypeMismatch"); // TODO 655 } 656 657 @NotNull 658 public static OverrideCompatibilityInfo memberKindMismatch() { 659 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "memberKindMismatch"); // TODO 660 } 661 662 @NotNull 663 public static OverrideCompatibilityInfo returnTypeMismatch(JetType substitutedSuperReturnType, JetType unsubstitutedSubReturnType) { 664 return new OverrideCompatibilityInfo(Result.CONFLICT, "returnTypeMismatch: " + unsubstitutedSubReturnType + " >< " + substitutedSuperReturnType); // TODO 665 } 666 667 @NotNull 668 public static OverrideCompatibilityInfo varOverriddenByVal() { 669 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "varOverriddenByVal"); // TODO 670 } 671 672 @NotNull 673 public static OverrideCompatibilityInfo externalConditionFailed(Class<? extends ExternalOverridabilityCondition> conditionClass) { 674 return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "externalConditionFailed: " + conditionClass.getName()); // TODO 675 } 676 677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////// 678 679 private final Result overridable; 680 private final String message; 681 682 public OverrideCompatibilityInfo(Result success, String message) { 683 this.overridable = success; 684 this.message = message; 685 } 686 687 public Result getResult() { 688 return overridable; 689 } 690 691 public String getMessage() { 692 return message; 693 } 694 } 695 }