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