Got rid of a global map for invisible overridden descriptors
This commit is contained in:
@@ -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<CallableDescriptor, CallableDescriptor> 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<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors) {
|
||||
private void generateOverrides() {
|
||||
Set<MutableClassDescriptor> ourClasses = new HashSet<MutableClassDescriptor>();
|
||||
ourClasses.addAll(context.getClasses().values());
|
||||
ourClasses.addAll(context.getObjects().values());
|
||||
@@ -91,12 +89,13 @@ public class OverrideResolver {
|
||||
Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>();
|
||||
|
||||
for (MutableClassDescriptor clazz : ourClasses) {
|
||||
generateOverridesInAClass(clazz, processed, ourClasses, invisibleOverriddenDescriptors);
|
||||
generateOverridesInAClass(clazz, processed, ourClasses);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor, @NotNull Set<ClassifierDescriptor> processed,
|
||||
@NotNull Set<MutableClassDescriptor> ourClasses, @NotNull Multimap<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors) {
|
||||
public void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor,
|
||||
@NotNull Set<ClassifierDescriptor> processed,
|
||||
@NotNull Set<MutableClassDescriptor> 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<? extends CallableMemberDescriptor> functionsFromSupertypes,
|
||||
@NotNull Collection<? extends CallableMemberDescriptor> functionsFromCurrent,
|
||||
@NotNull ClassDescriptor current,
|
||||
@Nullable Multimap<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors,
|
||||
@NotNull DescriptorSink sink) {
|
||||
|
||||
List<CallableMemberDescriptor> 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<CallableDescriptor, CallableDescriptor> invisibleOverriddenDescriptors) {
|
||||
private void checkOverrides() {
|
||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||
checkOverridesInAClass(entry.getValue(), entry.getKey(), invisibleOverriddenDescriptors);
|
||||
checkOverridesInAClass(entry.getValue(), entry.getKey());
|
||||
}
|
||||
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> 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<CallableDescriptor, CallableDescriptor> 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<CallableDescriptor, CallableDescriptor> 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<CallableMemberDescriptor> 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<MutableClassDescriptor> allClasses = Lists.newArrayList(context.getClasses().values());
|
||||
allClasses.addAll(context.getObjects().values());
|
||||
|
||||
Reference in New Issue
Block a user