From 83eaa4deb732ce6fa127ac94916d7e39f60efdf4 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 31 May 2012 13:50:15 +0400 Subject: [PATCH] Got rid of a global map for invisible overridden descriptors --- .../jet/lang/resolve/OverrideResolver.java | 81 +++++++++++-------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index a4e580f9a08..7efe6e22aab 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -16,7 +16,6 @@ package org.jetbrains.jet.lang.resolve; -import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; @@ -31,7 +30,6 @@ import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lexer.JetTokens; @@ -42,6 +40,7 @@ import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED; +import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE; /** * @author abreslav @@ -72,18 +71,17 @@ public class OverrideResolver { public void process() { //all created fake descriptors are stored to resolve visibility on them later - Multimap invisibleOverriddenDescriptors = LinkedHashMultimap.create(); - generateOverrides(invisibleOverriddenDescriptors); + generateOverrides(); checkVisibility(); - checkOverrides(invisibleOverriddenDescriptors); + checkOverrides(); checkParameterOverridesForAllClasses(); } /** * Generate fake overrides and add overridden descriptors to existing descriptors. */ - private void generateOverrides(@NotNull Multimap invisibleOverriddenDescriptors) { + private void generateOverrides() { Set ourClasses = new HashSet(); ourClasses.addAll(context.getClasses().values()); ourClasses.addAll(context.getObjects().values()); @@ -91,12 +89,13 @@ public class OverrideResolver { Set processed = new HashSet(); for (MutableClassDescriptor clazz : ourClasses) { - generateOverridesInAClass(clazz, processed, ourClasses, invisibleOverriddenDescriptors); + generateOverridesInAClass(clazz, processed, ourClasses); } } - private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor, @NotNull Set processed, - @NotNull Set ourClasses, @NotNull Multimap invisibleOverriddenDescriptors) { + public void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor, + @NotNull Set processed, + @NotNull Set ourClasses) { if (!processed.add(classDescriptor)) { return; } @@ -109,7 +108,7 @@ public class OverrideResolver { for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) { ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor(); if (superclass instanceof MutableClassDescriptor) { - generateOverridesInAClass((MutableClassDescriptor) superclass, processed, ourClasses, invisibleOverriddenDescriptors); + generateOverridesInAClass((MutableClassDescriptor) superclass, processed, ourClasses); } } @@ -129,7 +128,6 @@ public class OverrideResolver { functionsFromSupertypesByName.get(functionName), functionsFromCurrentByName.get(functionName), classDescriptor, - invisibleOverriddenDescriptors, new DescriptorSink() { @Override public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { @@ -175,7 +173,6 @@ public class OverrideResolver { @NotNull Collection functionsFromSupertypes, @NotNull Collection functionsFromCurrent, @NotNull ClassDescriptor current, - @Nullable Multimap invisibleOverriddenDescriptors, @NotNull DescriptorSink sink) { List fakeOverrideList = Lists.newArrayList(); @@ -187,14 +184,9 @@ public class OverrideResolver { for (CallableMemberDescriptor functionFromCurrent : functionsFromCurrent) { OverridingUtil.OverrideCompatibilityInfo.Result result = OverridingUtil.isOverridableBy(functionFromSupertype, functionFromCurrent).getResult(); - if (result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) { + if (result == OVERRIDABLE) { - if (!isVisible) { - if (invisibleOverriddenDescriptors != null) { - invisibleOverriddenDescriptors.put(functionFromCurrent, functionFromSupertype); - } - } - else { + if (isVisible) { OverridingUtil.bindOverride(functionFromCurrent, functionFromSupertype); } overrides = true; @@ -205,7 +197,7 @@ public class OverrideResolver { } for (CallableMemberDescriptor fakeOverride : fakeOverrideList) { - if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) { + if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).getResult() == OVERRIDABLE) { OverridingUtil.bindOverride(fakeOverride, functionFromSupertype); overrides = true; } @@ -251,22 +243,21 @@ public class OverrideResolver { return r; } - private void checkOverrides(@NotNull Multimap invisibleOverriddenDescriptors) { + private void checkOverrides() { for (Map.Entry entry : context.getClasses().entrySet()) { - checkOverridesInAClass(entry.getValue(), entry.getKey(), invisibleOverriddenDescriptors); + checkOverridesInAClass(entry.getValue(), entry.getKey()); } for (Map.Entry entry : context.getObjects().entrySet()) { - checkOverridesInAClass(entry.getValue(), entry.getKey(), invisibleOverriddenDescriptors); + checkOverridesInAClass(entry.getValue(), entry.getKey()); } } - protected void checkOverridesInAClass(@NotNull MutableClassDescriptor classDescriptor, @NotNull JetClassOrObject klass, - @NotNull Multimap invisibleOverriddenDescriptors) { + protected void checkOverridesInAClass(@NotNull MutableClassDescriptor classDescriptor, @NotNull JetClassOrObject klass) { if (topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) return; // Check overrides for internal consistency for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) { - checkOverrideForMember(member, invisibleOverriddenDescriptors); + checkOverrideForMember(member); } // Check if everything that must be overridden, actually is @@ -356,8 +347,8 @@ public class OverrideResolver { for (CallableMemberDescriptor another : filteredMembers) { // if (one == another) continue; factoredMembers.put(one, one); - if (OverridingUtil.isOverridableBy(one, another).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE - || OverridingUtil.isOverridableBy(another, one).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) { + if (OverridingUtil.isOverridableBy(one, another).getResult() == OVERRIDABLE + || OverridingUtil.isOverridableBy(another, one).getResult() == OVERRIDABLE) { factoredMembers.put(one, another); } } @@ -365,8 +356,7 @@ public class OverrideResolver { return factoredMembers; } - private void checkOverrideForMember(@NotNull CallableMemberDescriptor declared, - @NotNull Multimap invisibleOverriddenDescriptors) { + private void checkOverrideForMember(@NotNull CallableMemberDescriptor declared) { JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared); if (member == null) { Boolean delegated = trace.get(DELEGATED, declared); @@ -410,9 +400,14 @@ public class OverrideResolver { } if (hasOverrideModifier && declared.getOverriddenDescriptors().size() == 0) { - if (!invisibleOverriddenDescriptors.get(declared).isEmpty()) { - CallableDescriptor descriptor = invisibleOverriddenDescriptors.values().iterator().next(); - trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, descriptor, descriptor.getContainingDeclaration())); + DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration(); + assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration; + ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration; + + CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass); + if (invisibleOverriddenDescriptor != null) { + trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverriddenDescriptor, + invisibleOverriddenDescriptor.getContainingDeclaration())); } else { trace.report(NOTHING_TO_OVERRIDE.on(member, declared)); @@ -425,6 +420,26 @@ public class OverrideResolver { } } + private CallableMemberDescriptor findInvisibleOverriddenDescriptor(CallableMemberDescriptor declared, ClassDescriptor declaringClass) { + CallableMemberDescriptor invisibleOverride = null; + outer: + for (JetType supertype : declaringClass.getTypeConstructor().getSupertypes()) { + Set all = Sets.newLinkedHashSet(); + all.addAll(supertype.getMemberScope().getFunctions(declared.getName())); + all.addAll((Set) supertype.getMemberScope().getProperties(declared.getName())); + for (CallableMemberDescriptor fromSuper : all) { + if (OverridingUtil.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) { + invisibleOverride = fromSuper; + if (Visibilities.isVisible(fromSuper, declared)) { + throw new IllegalStateException("Descriptor " + fromSuper + "is overridable by " + declared + " and visible but does not appear in its getOverriddenDescriptors()"); + } + break outer; + } + } + } + return invisibleOverride; + } + private void checkParameterOverridesForAllClasses() { List allClasses = Lists.newArrayList(context.getClasses().values()); allClasses.addAll(context.getObjects().values());