001 /* 002 * Copyright 2010-2015 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.jetbrains.kotlin.resolve; 018 019 import kotlin.CollectionsKt; 020 import kotlin.Unit; 021 import kotlin.jvm.functions.Function1; 022 import org.jetbrains.annotations.NotNull; 023 import org.jetbrains.annotations.Nullable; 024 import org.jetbrains.kotlin.descriptors.*; 025 import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl; 026 import org.jetbrains.kotlin.descriptors.impl.PropertyAccessorDescriptorImpl; 027 import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl; 028 import org.jetbrains.kotlin.name.Name; 029 import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; 030 import org.jetbrains.kotlin.types.KotlinType; 031 import org.jetbrains.kotlin.types.TypeConstructor; 032 import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; 033 import org.jetbrains.kotlin.utils.DFS; 034 035 import java.util.*; 036 037 import static org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.*; 038 039 public class OverridingUtil { 040 041 private static final List<ExternalOverridabilityCondition> EXTERNAL_CONDITIONS = 042 CollectionsKt.toList(ServiceLoader.load( 043 ExternalOverridabilityCondition.class, 044 ExternalOverridabilityCondition.class.getClassLoader() 045 )); 046 047 public static final OverridingUtil DEFAULT = new OverridingUtil(new KotlinTypeChecker.TypeConstructorEquality() { 048 @Override 049 public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { 050 return a.equals(b); 051 } 052 }); 053 054 @NotNull 055 public static OverridingUtil createWithEqualityAxioms(@NotNull KotlinTypeChecker.TypeConstructorEquality equalityAxioms) { 056 return new OverridingUtil(equalityAxioms); 057 } 058 059 private final KotlinTypeChecker.TypeConstructorEquality equalityAxioms; 060 061 private OverridingUtil(KotlinTypeChecker.TypeConstructorEquality axioms) { 062 equalityAxioms = axioms; 063 } 064 065 @NotNull 066 public OverrideCompatibilityInfo isOverridableBy(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { 067 return isOverridableBy(superDescriptor, subDescriptor, false); 068 } 069 070 @NotNull 071 public OverrideCompatibilityInfo isOverridableByIncludingReturnType(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) { 072 return isOverridableBy(superDescriptor, subDescriptor, true); 073 } 074 075 @NotNull 076 private OverrideCompatibilityInfo isOverridableBy( 077 @NotNull CallableDescriptor superDescriptor, 078 @NotNull CallableDescriptor subDescriptor, 079 boolean checkReturnType 080 ) { 081 if (superDescriptor instanceof FunctionDescriptor) { 082 if (!(subDescriptor instanceof FunctionDescriptor)) return OverrideCompatibilityInfo.memberKindMismatch(); 083 } 084 else if (superDescriptor instanceof PropertyDescriptor) { 085 if (!(subDescriptor instanceof PropertyDescriptor)) return OverrideCompatibilityInfo.memberKindMismatch(); 086 } 087 else { 088 throw new IllegalArgumentException("This type of CallableDescriptor cannot be checked for overridability: " + superDescriptor); 089 } 090 091 // TODO: check outside of this method 092 if (!superDescriptor.getName().equals(subDescriptor.getName())) { 093 return OverrideCompatibilityInfo.nameMismatch(); 094 } 095 096 OverrideCompatibilityInfo receiverAndParameterResult = checkReceiverAndParameterCount(superDescriptor, subDescriptor); 097 if (receiverAndParameterResult != null) { 098 return receiverAndParameterResult; 099 } 100 101 List<KotlinType> superValueParameters = compiledValueParameters(superDescriptor); 102 List<KotlinType> subValueParameters = compiledValueParameters(subDescriptor); 103 104 List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters(); 105 List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters(); 106 107 if (superTypeParameters.size() != subTypeParameters.size()) { 108 for (int i = 0; i < superValueParameters.size(); ++i) { 109 KotlinType superValueParameterType = getUpperBound(superValueParameters.get(i)); 110 KotlinType subValueParameterType = getUpperBound(subValueParameters.get(i)); 111 // TODO: compare erasure 112 if (!KotlinTypeChecker.DEFAULT.equalTypes(superValueParameterType, subValueParameterType)) { 113 return OverrideCompatibilityInfo.typeParameterNumberMismatch(); 114 } 115 } 116 return OverrideCompatibilityInfo.valueParameterTypeMismatch(null, null, OverrideCompatibilityInfo.Result.CONFLICT); 117 } 118 119 final Map<TypeConstructor, TypeConstructor> matchingTypeConstructors = new HashMap<TypeConstructor, TypeConstructor>(); 120 for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) { 121 TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); 122 TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); 123 matchingTypeConstructors.put(superTypeParameter.getTypeConstructor(), subTypeParameter.getTypeConstructor()); 124 } 125 126 KotlinTypeChecker.TypeConstructorEquality localEqualityAxioms = new KotlinTypeChecker.TypeConstructorEquality() { 127 @Override 128 public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { 129 if (equalityAxioms.equals(a, b)) return true; 130 TypeConstructor img1 = matchingTypeConstructors.get(a); 131 TypeConstructor img2 = matchingTypeConstructors.get(b); 132 if (!(img1 != null && img1.equals(b)) && 133 !(img2 != null && img2.equals(a))) { 134 return false; 135 } 136 return true; 137 } 138 }; 139 140 for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) { 141 TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); 142 TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); 143 144 if (!areTypesEquivalent(superTypeParameter.getUpperBoundsAsType(), subTypeParameter.getUpperBoundsAsType(), localEqualityAxioms)) { 145 return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter); 146 } 147 } 148 149 for (int i = 0, unsubstitutedValueParametersSize = superValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { 150 KotlinType superValueParameter = superValueParameters.get(i); 151 KotlinType subValueParameter = subValueParameters.get(i); 152 153 if (!areTypesEquivalent(superValueParameter, subValueParameter, localEqualityAxioms)) { 154 return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameter, subValueParameter, INCOMPATIBLE); 155 } 156 } 157 158 if (checkReturnType) { 159 KotlinType superReturnType = superDescriptor.getReturnType(); 160 KotlinType subReturnType = subDescriptor.getReturnType(); 161 162 if (superReturnType != null && subReturnType != null) { 163 boolean bothErrors = subReturnType.isError() && superReturnType.isError(); 164 if (!bothErrors && !KotlinTypeChecker.withAxioms(localEqualityAxioms).isSubtypeOf(subReturnType, superReturnType)) { 165 return OverrideCompatibilityInfo.returnTypeMismatch(superReturnType, subReturnType); 166 } 167 } 168 } 169 170 171 for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) { 172 if (!externalCondition.isOverridable(superDescriptor, subDescriptor)) { 173 return OverrideCompatibilityInfo.externalConditionFailed(externalCondition.getClass()); 174 } 175 } 176 177 return OverrideCompatibilityInfo.success(); 178 } 179 180 @Nullable 181 static OverrideCompatibilityInfo checkReceiverAndParameterCount( 182 CallableDescriptor superDescriptor, 183 CallableDescriptor subDescriptor 184 ) { 185 if ((superDescriptor.getExtensionReceiverParameter() == null) != (subDescriptor.getExtensionReceiverParameter() == null)) { 186 return OverrideCompatibilityInfo.receiverPresenceMismatch(); 187 } 188 189 if (superDescriptor.getValueParameters().size() != subDescriptor.getValueParameters().size()) { 190 return OverrideCompatibilityInfo.valueParameterNumberMismatch(); 191 } 192 193 return null; 194 } 195 196 private static boolean areTypesEquivalent( 197 @NotNull KotlinType typeInSuper, 198 @NotNull KotlinType typeInSub, 199 @NotNull KotlinTypeChecker.TypeConstructorEquality axioms 200 ) { 201 boolean bothErrors = typeInSuper.isError() && typeInSub.isError(); 202 if (!bothErrors && !KotlinTypeChecker.withAxioms(axioms).equalTypes(typeInSuper, typeInSub)) { 203 return false; 204 } 205 return true; 206 } 207 208 static List<KotlinType> compiledValueParameters(CallableDescriptor callableDescriptor) { 209 ReceiverParameterDescriptor receiverParameter = callableDescriptor.getExtensionReceiverParameter(); 210 ArrayList<KotlinType> parameters = new ArrayList<KotlinType>(); 211 if (receiverParameter != null) { 212 parameters.add(receiverParameter.getType()); 213 } 214 for (ValueParameterDescriptor valueParameterDescriptor : callableDescriptor.getValueParameters()) { 215 parameters.add(valueParameterDescriptor.getType()); 216 } 217 return parameters; 218 } 219 220 static KotlinType getUpperBound(KotlinType type) { 221 if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { 222 return type; 223 } 224 else if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { 225 return ((TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor()).getUpperBoundsAsType(); 226 } 227 else { 228 throw new IllegalStateException("unknown type constructor: " + type.getConstructor().getClass().getName()); 229 } 230 } 231 232 public static void generateOverridesInFunctionGroup( 233 @SuppressWarnings("UnusedParameters") 234 @NotNull Name name, //DO NOT DELETE THIS PARAMETER: needed to make sure all descriptors have the same name 235 @NotNull Collection<? extends CallableMemberDescriptor> membersFromSupertypes, 236 @NotNull Collection<? extends CallableMemberDescriptor> membersFromCurrent, 237 @NotNull ClassDescriptor current, 238 @NotNull DescriptorSink sink 239 ) { 240 Collection<CallableMemberDescriptor> notOverridden = new LinkedHashSet<CallableMemberDescriptor>(membersFromSupertypes); 241 242 for (CallableMemberDescriptor fromCurrent : membersFromCurrent) { 243 Collection<CallableMemberDescriptor> bound = 244 extractAndBindOverridesForMember(fromCurrent, membersFromSupertypes, current, sink); 245 notOverridden.removeAll(bound); 246 } 247 248 createAndBindFakeOverrides(current, notOverridden, sink); 249 } 250 251 private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember( 252 @NotNull CallableMemberDescriptor fromCurrent, 253 @NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper, 254 @NotNull ClassDescriptor current, 255 @NotNull DescriptorSink sink 256 ) { 257 Collection<CallableMemberDescriptor> bound = new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size()); 258 for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) { 259 OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent).getResult(); 260 261 boolean isVisible = Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSupertype, current); 262 switch (result) { 263 case OVERRIDABLE: 264 if (isVisible) { 265 fromCurrent.addOverriddenDescriptor(fromSupertype); 266 } 267 bound.add(fromSupertype); 268 break; 269 case CONFLICT: 270 if (isVisible) { 271 sink.conflict(fromSupertype, fromCurrent); 272 } 273 bound.add(fromSupertype); 274 break; 275 case INCOMPATIBLE: 276 break; 277 } 278 } 279 return bound; 280 } 281 282 private static void createAndBindFakeOverrides( 283 @NotNull ClassDescriptor current, 284 @NotNull Collection<CallableMemberDescriptor> notOverridden, 285 @NotNull DescriptorSink sink 286 ) { 287 Queue<CallableMemberDescriptor> fromSuperQueue = new LinkedList<CallableMemberDescriptor>(notOverridden); 288 while (!fromSuperQueue.isEmpty()) { 289 CallableMemberDescriptor notOverriddenFromSuper = VisibilityUtilKt.findMemberWithMaxVisibility(fromSuperQueue); 290 Collection<CallableMemberDescriptor> overridables = 291 extractMembersOverridableInBothWays(notOverriddenFromSuper, fromSuperQueue, sink); 292 createAndBindFakeOverride(overridables, current, sink); 293 } 294 } 295 296 private static boolean isMoreSpecific(@NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) { 297 if (a instanceof SimpleFunctionDescriptor) { 298 assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass(); 299 300 KotlinType aReturnType = a.getReturnType(); 301 assert aReturnType != null; 302 KotlinType bReturnType = b.getReturnType(); 303 assert bReturnType != null; 304 305 return KotlinTypeChecker.DEFAULT.isSubtypeOf(aReturnType, bReturnType); 306 } 307 if (a instanceof PropertyDescriptor) { 308 assert b instanceof PropertyDescriptor : "b is " + b.getClass(); 309 310 if (((PropertyDescriptor) a).isVar() || ((PropertyDescriptor) b).isVar()) { 311 return ((PropertyDescriptor) a).isVar(); 312 } 313 314 // both vals 315 return KotlinTypeChecker.DEFAULT.isSubtypeOf(((PropertyDescriptor) a).getType(), ((PropertyDescriptor) b).getType()); 316 } 317 throw new IllegalArgumentException("Unexpected callable: " + a.getClass()); 318 } 319 320 private static CallableMemberDescriptor selectMostSpecificMemberFromSuper(@NotNull Collection<CallableMemberDescriptor> overridables) { 321 CallableMemberDescriptor result = null; 322 for (CallableMemberDescriptor overridable : overridables) { 323 if (result == null || isMoreSpecific(overridable, result)) { 324 result = overridable; 325 } 326 } 327 return result; 328 } 329 330 private static void createAndBindFakeOverride( 331 @NotNull Collection<CallableMemberDescriptor> overridables, 332 @NotNull ClassDescriptor current, 333 @NotNull DescriptorSink sink 334 ) { 335 Collection<CallableMemberDescriptor> visibleOverridables = filterVisibleFakeOverrides(current, overridables); 336 boolean allInvisible = visibleOverridables.isEmpty(); 337 Collection<CallableMemberDescriptor> effectiveOverridden = allInvisible ? overridables : visibleOverridables; 338 339 Modality modality = getMinimalModality(effectiveOverridden); 340 Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED; 341 CallableMemberDescriptor mostSpecific = selectMostSpecificMemberFromSuper(effectiveOverridden); 342 CallableMemberDescriptor fakeOverride = 343 mostSpecific.copy(current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false); 344 for (CallableMemberDescriptor descriptor : effectiveOverridden) { 345 fakeOverride.addOverriddenDescriptor(descriptor); 346 } 347 sink.addFakeOverride(fakeOverride); 348 } 349 350 @NotNull 351 private static Modality getMinimalModality(@NotNull Collection<CallableMemberDescriptor> descriptors) { 352 Modality modality = Modality.ABSTRACT; 353 for (CallableMemberDescriptor descriptor : descriptors) { 354 if (descriptor.getModality().compareTo(modality) < 0) { 355 modality = descriptor.getModality(); 356 } 357 } 358 return modality; 359 } 360 361 @NotNull 362 private static Collection<CallableMemberDescriptor> filterVisibleFakeOverrides( 363 @NotNull final ClassDescriptor current, 364 @NotNull Collection<CallableMemberDescriptor> toFilter 365 ) { 366 return CollectionsKt.filter(toFilter, new Function1<CallableMemberDescriptor, Boolean>() { 367 @Override 368 public Boolean invoke(CallableMemberDescriptor descriptor) { 369 //nested class could capture private member, so check for private visibility added 370 return !Visibilities.isPrivate(descriptor.getVisibility()) && 371 Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, current); 372 } 373 }); 374 } 375 376 @NotNull 377 private static Collection<CallableMemberDescriptor> extractMembersOverridableInBothWays( 378 @NotNull CallableMemberDescriptor overrider, 379 @NotNull Queue<CallableMemberDescriptor> extractFrom, 380 @NotNull DescriptorSink sink 381 ) { 382 Collection<CallableMemberDescriptor> overridable = new ArrayList<CallableMemberDescriptor>(); 383 overridable.add(overrider); 384 for (Iterator<CallableMemberDescriptor> iterator = extractFrom.iterator(); iterator.hasNext(); ) { 385 CallableMemberDescriptor candidate = iterator.next(); 386 if (overrider == candidate) { 387 iterator.remove(); 388 continue; 389 } 390 391 OverrideCompatibilityInfo.Result result1 = DEFAULT.isOverridableBy(candidate, overrider).getResult(); 392 OverrideCompatibilityInfo.Result result2 = DEFAULT.isOverridableBy(overrider, candidate).getResult(); 393 if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) { 394 overridable.add(candidate); 395 iterator.remove(); 396 } 397 else if (result1 == CONFLICT || result2 == CONFLICT) { 398 sink.conflict(overrider, candidate); 399 iterator.remove(); 400 } 401 } 402 return overridable; 403 } 404 405 public static void resolveUnknownVisibilityForMember( 406 @NotNull CallableMemberDescriptor memberDescriptor, 407 @Nullable Function1<CallableMemberDescriptor, Unit> cannotInferVisibility 408 ) { 409 for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) { 410 if (descriptor.getVisibility() == Visibilities.INHERITED) { 411 resolveUnknownVisibilityForMember(descriptor, cannotInferVisibility); 412 } 413 } 414 415 if (memberDescriptor.getVisibility() != Visibilities.INHERITED) { 416 return; 417 } 418 419 Visibility maxVisibility = computeVisibilityToInherit(memberDescriptor); 420 Visibility visibilityToInherit; 421 if (maxVisibility == null) { 422 if (cannotInferVisibility != null) { 423 cannotInferVisibility.invoke(memberDescriptor); 424 } 425 visibilityToInherit = Visibilities.PUBLIC; 426 } 427 else { 428 visibilityToInherit = maxVisibility; 429 } 430 431 if (memberDescriptor instanceof PropertyDescriptorImpl) { 432 ((PropertyDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit); 433 for (PropertyAccessorDescriptor accessor : ((PropertyDescriptor) memberDescriptor).getAccessors()) { 434 // If we couldn't infer visibility for property, the diagnostic is already reported, no need to report it again on accessors 435 resolveUnknownVisibilityForMember(accessor, maxVisibility == null ? null : cannotInferVisibility); 436 } 437 } 438 else if (memberDescriptor instanceof FunctionDescriptorImpl) { 439 ((FunctionDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit); 440 } 441 else { 442 assert memberDescriptor instanceof PropertyAccessorDescriptorImpl; 443 ((PropertyAccessorDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit); 444 } 445 } 446 447 @Nullable 448 private static Visibility computeVisibilityToInherit(@NotNull CallableMemberDescriptor memberDescriptor) { 449 Collection<? extends CallableMemberDescriptor> overriddenDescriptors = memberDescriptor.getOverriddenDescriptors(); 450 Visibility maxVisibility = findMaxVisibility(overriddenDescriptors); 451 if (maxVisibility == null) { 452 return null; 453 } 454 if (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { 455 for (CallableMemberDescriptor overridden : overriddenDescriptors) { 456 // An implementation (a non-abstract overridden member) of a fake override should have the maximum possible visibility 457 if (overridden.getModality() != Modality.ABSTRACT && !overridden.getVisibility().equals(maxVisibility)) { 458 return null; 459 } 460 } 461 return maxVisibility; 462 } 463 return maxVisibility.normalize(); 464 } 465 466 @Nullable 467 public static Visibility findMaxVisibility(@NotNull Collection<? extends CallableMemberDescriptor> descriptors) { 468 if (descriptors.isEmpty()) { 469 return Visibilities.DEFAULT_VISIBILITY; 470 } 471 Visibility maxVisibility = null; 472 for (CallableMemberDescriptor descriptor : descriptors) { 473 Visibility visibility = descriptor.getVisibility(); 474 assert visibility != Visibilities.INHERITED : "Visibility should have been computed for " + descriptor; 475 if (maxVisibility == null) { 476 maxVisibility = visibility; 477 continue; 478 } 479 Integer compareResult = Visibilities.compare(visibility, maxVisibility); 480 if (compareResult == null) { 481 maxVisibility = null; 482 } 483 else if (compareResult > 0) { 484 maxVisibility = visibility; 485 } 486 } 487 // TODO: IDEA seems to issue an incorrect warning here 488 //noinspection ConstantConditions 489 if (maxVisibility == null) { 490 return null; 491 } 492 for (CallableMemberDescriptor descriptor : descriptors) { 493 Integer compareResult = Visibilities.compare(maxVisibility, descriptor.getVisibility()); 494 if (compareResult == null || compareResult < 0) { 495 return null; 496 } 497 } 498 return maxVisibility; 499 } 500 501 @NotNull 502 public static List<? extends CallableDescriptor> getTopmostOverridenDescriptors(@NotNull CallableDescriptor originalDescriptor) { 503 return DFS.dfs( 504 Collections.singletonList(originalDescriptor), 505 new DFS.Neighbors<CallableDescriptor>() { 506 @NotNull 507 @Override 508 public Iterable<? extends CallableDescriptor> getNeighbors(CallableDescriptor current) { 509 return current.getOverriddenDescriptors(); 510 } 511 }, 512 new DFS.CollectingNodeHandler<CallableDescriptor, CallableDescriptor, ArrayList<CallableDescriptor>>( 513 new ArrayList<CallableDescriptor>() 514 ) { 515 @Override 516 public void afterChildren(CallableDescriptor current) { 517 if (current.getOverriddenDescriptors().isEmpty()) { 518 result.add(current); 519 } 520 } 521 } 522 ); 523 } 524 525 public interface DescriptorSink { 526 void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride); 527 528 void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent); 529 } 530 531 public static class OverrideCompatibilityInfo { 532 533 public enum Result { 534 OVERRIDABLE, 535 INCOMPATIBLE, 536 CONFLICT, 537 } 538 539 private static final OverrideCompatibilityInfo SUCCESS = new OverrideCompatibilityInfo(Result.OVERRIDABLE, "SUCCESS"); 540 541 @NotNull 542 public static OverrideCompatibilityInfo success() { 543 return SUCCESS; 544 } 545 546 @NotNull 547 public static OverrideCompatibilityInfo nameMismatch() { 548 return new OverrideCompatibilityInfo(INCOMPATIBLE, "nameMismatch"); // TODO 549 } 550 551 @NotNull 552 public static OverrideCompatibilityInfo typeParameterNumberMismatch() { 553 return new OverrideCompatibilityInfo(INCOMPATIBLE, "typeParameterNumberMismatch"); // TODO 554 } 555 556 @NotNull 557 public static OverrideCompatibilityInfo receiverPresenceMismatch() { 558 return new OverrideCompatibilityInfo(INCOMPATIBLE, "receiverPresenceMismatch"); // TODO 559 } 560 561 @NotNull 562 public static OverrideCompatibilityInfo valueParameterNumberMismatch() { 563 return new OverrideCompatibilityInfo(INCOMPATIBLE, "valueParameterNumberMismatch"); // TODO 564 } 565 566 @NotNull 567 public static OverrideCompatibilityInfo boundsMismatch(TypeParameterDescriptor superTypeParameter, TypeParameterDescriptor subTypeParameter) { 568 return new OverrideCompatibilityInfo(INCOMPATIBLE, "boundsMismatch"); // TODO 569 } 570 571 @NotNull 572 public static OverrideCompatibilityInfo valueParameterTypeMismatch(KotlinType superValueParameter, KotlinType subValueParameter, Result result) { 573 return new OverrideCompatibilityInfo(result, "valueParameterTypeMismatch"); // TODO 574 } 575 576 @NotNull 577 public static OverrideCompatibilityInfo memberKindMismatch() { 578 return new OverrideCompatibilityInfo(INCOMPATIBLE, "memberKindMismatch"); // TODO 579 } 580 581 @NotNull 582 public static OverrideCompatibilityInfo returnTypeMismatch(KotlinType substitutedSuperReturnType, KotlinType unsubstitutedSubReturnType) { 583 return new OverrideCompatibilityInfo(Result.CONFLICT, "returnTypeMismatch: " + unsubstitutedSubReturnType + " >< " + substitutedSuperReturnType); // TODO 584 } 585 586 @NotNull 587 public static OverrideCompatibilityInfo varOverriddenByVal() { 588 return new OverrideCompatibilityInfo(INCOMPATIBLE, "varOverriddenByVal"); // TODO 589 } 590 591 @NotNull 592 public static OverrideCompatibilityInfo externalConditionFailed(Class<? extends ExternalOverridabilityCondition> conditionClass) { 593 return new OverrideCompatibilityInfo(INCOMPATIBLE, "externalConditionFailed: " + conditionClass.getName()); // TODO 594 } 595 596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////// 597 598 private final Result overridable; 599 private final String message; 600 601 public OverrideCompatibilityInfo(Result success, String message) { 602 this.overridable = success; 603 this.message = message; 604 } 605 606 public Result getResult() { 607 return overridable; 608 } 609 610 public String getMessage() { 611 return message; 612 } 613 } 614 }