Move utilities out of OverrideResolver

This commit is contained in:
Alexander Udalov
2013-08-21 19:29:02 +04:00
parent f5faf8acb2
commit effbdcaa4c
6 changed files with 289 additions and 277 deletions
@@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import javax.inject.Inject;
@@ -17,6 +17,6 @@ public class FakeOverrideVisibilityResolverImpl implements FakeOverrideVisibilit
@Override
public void resolveUnknownVisibilityForMember(@NotNull CallableMemberDescriptor descriptor) {
OverrideResolver.resolveUnknownVisibilityForMember(null, descriptor, trace);
OverridingUtil.resolveUnknownVisibilityForMember(null, descriptor, trace);
}
}
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.TraceUtil;
import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNullable;
import org.jetbrains.jet.lang.resolve.lazy.storage.NotNullLazyValue;
@@ -420,15 +420,15 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements
@NotNull final Collection<D> result
) {
List<CallableMemberDescriptor> fromCurrent = new ArrayList<CallableMemberDescriptor>(result);
OverrideResolver.generateOverridesInFunctionGroup(
OverridingUtil.generateOverridesInFunctionGroup(
name,
fromSupertypes,
fromCurrent,
classDescriptor,
new OverrideResolver.DescriptorSink() {
new OverridingUtil.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
OverrideResolver.resolveUnknownVisibilityForMember(null, fakeOverride, TraceUtil.TRACE_STUB);
OverridingUtil.resolveUnknownVisibilityForMember(null, fakeOverride, TraceUtil.TRACE_STUB);
//noinspection unchecked
result.add((D) fakeOverride);
}
@@ -16,18 +16,20 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.google.common.collect.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.LinkedMultiMap;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
@@ -43,7 +45,6 @@ import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
public class OverrideResolver {
@@ -134,12 +135,12 @@ public class OverrideResolver {
Collection<CallableMemberDescriptor> fromSupertypes = membersFromSupertypesByName.get(memberName);
Collection<CallableMemberDescriptor> fromCurrent = membersFromCurrentByName.get(memberName);
generateOverridesInFunctionGroup(
OverridingUtil.generateOverridesInFunctionGroup(
memberName,
fromSupertypes,
fromCurrent,
classDescriptor,
new DescriptorSink() {
new OverridingUtil.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
if (fakeOverride instanceof PropertyDescriptor) {
@@ -175,189 +176,10 @@ public class OverrideResolver {
declaration = (JetDeclaration) element;
}
}
resolveUnknownVisibilityForMember(declaration, memberDescriptor, trace);
OverridingUtil.resolveUnknownVisibilityForMember(declaration, memberDescriptor, trace);
}
}
public interface DescriptorSink {
void addToScope(@NotNull CallableMemberDescriptor fakeOverride);
void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent);
}
public static void generateOverridesInFunctionGroup(
@NotNull Name name, //DO NOT DELETE THIS PARAMETER: needed to make sure all descriptors have the same name
@NotNull Collection<? extends CallableMemberDescriptor> membersFromSupertypes,
@NotNull Collection<? extends CallableMemberDescriptor> membersFromCurrent,
@NotNull ClassDescriptor current,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> notOverridden = Sets.newLinkedHashSet(membersFromSupertypes);
for (CallableMemberDescriptor fromCurrent : membersFromCurrent) {
Collection<CallableMemberDescriptor> bound =
extractAndBindOverridesForMember(fromCurrent, membersFromSupertypes, current, sink);
notOverridden.removeAll(bound);
}
createAndBindFakeOverrides(current, notOverridden, sink);
}
private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember(
@NotNull CallableMemberDescriptor fromCurrent,
@NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
@NotNull ClassDescriptor current,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> bound = Lists.newArrayList();
for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
OverridingUtil.OverrideCompatibilityInfo.Result result =
OverridingUtil.isOverridableBy(fromSupertype, fromCurrent).getResult();
boolean isVisible = Visibilities.isVisible(fromSupertype, current);
switch (result) {
case OVERRIDABLE:
if (isVisible) {
OverridingUtil.bindOverride(fromCurrent, fromSupertype);
}
bound.add(fromSupertype);
break;
case CONFLICT:
if (isVisible) {
sink.conflict(fromSupertype, fromCurrent);
}
bound.add(fromSupertype);
break;
case INCOMPATIBLE:
break;
}
}
return bound;
}
private static void createAndBindFakeOverrides(
@NotNull ClassDescriptor current,
@NotNull Collection<CallableMemberDescriptor> notOverridden,
@NotNull DescriptorSink sink
) {
Queue<CallableMemberDescriptor> fromSuperQueue = new LinkedList<CallableMemberDescriptor>(notOverridden);
while (!fromSuperQueue.isEmpty()) {
CallableMemberDescriptor notOverriddenFromSuper = VisibilityUtil.findMemberWithMaxVisibility(fromSuperQueue);
Collection<CallableMemberDescriptor> overridables = extractMembersOverridableInBothWays(notOverriddenFromSuper, fromSuperQueue,
sink);
createAndBindFakeOverride(overridables, current, sink);
}
}
private static boolean isMoreSpecific(@NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) {
if (a instanceof SimpleFunctionDescriptor) {
assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();
JetType aReturnType = a.getReturnType();
assert aReturnType != null;
JetType bReturnType = b.getReturnType();
assert bReturnType != null;
return JetTypeChecker.INSTANCE.isSubtypeOf(aReturnType, bReturnType);
}
if (a instanceof PropertyDescriptor) {
assert b instanceof PropertyDescriptor : "b is " + b.getClass();
if (((PropertyDescriptor) a).isVar() || ((PropertyDescriptor) b).isVar()) {
return ((PropertyDescriptor) a).isVar();
}
// both vals
return JetTypeChecker.INSTANCE.isSubtypeOf(((PropertyDescriptor) a).getType(), ((PropertyDescriptor) b).getType());
}
throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
}
private static CallableMemberDescriptor selectMostSpecificMemberFromSuper(@NotNull Collection<CallableMemberDescriptor> overridables) {
CallableMemberDescriptor result = null;
for (CallableMemberDescriptor overridable : overridables) {
if (result == null || isMoreSpecific(overridable, result)) {
result = overridable;
}
}
return result;
}
private static void createAndBindFakeOverride(
@NotNull Collection<CallableMemberDescriptor> overridables,
@NotNull ClassDescriptor current,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> visibleOverridables = filterVisibleFakeOverrides(current, overridables);
Modality modality = getMinimalModality(visibleOverridables);
boolean allInvisible = visibleOverridables.isEmpty();
Collection<CallableMemberDescriptor> effectiveOverridden = allInvisible ? overridables : visibleOverridables;
Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED;
CallableMemberDescriptor mostSpecific = selectMostSpecificMemberFromSuper(effectiveOverridden);
CallableMemberDescriptor fakeOverride =
mostSpecific.copy(current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
for (CallableMemberDescriptor descriptor : effectiveOverridden) {
OverridingUtil.bindOverride(fakeOverride, descriptor);
}
sink.addToScope(fakeOverride);
}
@NotNull
private static Modality getMinimalModality(@NotNull Collection<CallableMemberDescriptor> descriptors) {
Modality modality = Modality.ABSTRACT;
for (CallableMemberDescriptor descriptor : descriptors) {
if (descriptor.getModality().compareTo(modality) < 0) {
modality = descriptor.getModality();
}
}
return modality;
}
@NotNull
private static Collection<CallableMemberDescriptor> filterVisibleFakeOverrides(
@NotNull final ClassDescriptor current,
@NotNull Collection<CallableMemberDescriptor> toFilter
) {
return Collections2.filter(toFilter, new Predicate<CallableMemberDescriptor>() {
@Override
public boolean apply(@Nullable CallableMemberDescriptor descriptor) {
//nested class could capture private member, so check for private visibility added
return descriptor.getVisibility() != Visibilities.PRIVATE && Visibilities.isVisible(descriptor, current);
}
});
}
@NotNull
private static Collection<CallableMemberDescriptor> extractMembersOverridableInBothWays(
@NotNull CallableMemberDescriptor overrider,
@NotNull Queue<CallableMemberDescriptor> extractFrom,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> overridable = Lists.newArrayList();
overridable.add(overrider);
for (Iterator<CallableMemberDescriptor> iterator = extractFrom.iterator(); iterator.hasNext(); ) {
CallableMemberDescriptor candidate = iterator.next();
if (overrider == candidate) {
iterator.remove();
continue;
}
OverridingUtil.OverrideCompatibilityInfo.Result result1 =
OverridingUtil.isOverridableBy(candidate, overrider).getResult();
OverridingUtil.OverrideCompatibilityInfo.Result result2 =
OverridingUtil.isOverridableBy(overrider, candidate).getResult();
if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) {
overridable.add(candidate);
iterator.remove();
}
else if (result1 == CONFLICT || result2 == CONFLICT) {
sink.conflict(overrider, candidate);
iterator.remove();
}
}
return overridable;
}
private static <T extends DeclarationDescriptor> MultiMap<Name, T> groupDescriptorsByName(Collection<T> properties) {
MultiMap<Name, T> r = new LinkedMultiMap<Name, T>();
for (T property : properties) {
@@ -893,78 +715,6 @@ public class OverrideResolver {
return false;
}
public static void resolveUnknownVisibilityForMember(@Nullable JetDeclaration member, @NotNull CallableMemberDescriptor memberDescriptor, @NotNull BindingTrace trace) {
resolveUnknownVisibilityForOverriddenDescriptors(memberDescriptor.getOverriddenDescriptors(), trace);
if (memberDescriptor.getVisibility() != Visibilities.INHERITED) {
return;
}
Visibility visibility = findMaxVisibility(memberDescriptor.getOverriddenDescriptors());
if (visibility == null) {
if (member != null) {
trace.report(CANNOT_INFER_VISIBILITY.on(member));
}
visibility = Visibilities.PUBLIC;
}
if (memberDescriptor instanceof PropertyDescriptorImpl) {
((PropertyDescriptorImpl)memberDescriptor).setVisibility(visibility.normalize());
for (PropertyAccessorDescriptor accessor : ((PropertyDescriptor) memberDescriptor).getAccessors()) {
resolveUnknownVisibilityForMember(null, accessor, trace);
}
}
else if (memberDescriptor instanceof FunctionDescriptorImpl) {
((FunctionDescriptorImpl)memberDescriptor).setVisibility(visibility.normalize());
}
else {
assert memberDescriptor instanceof PropertyAccessorDescriptorImpl;
((PropertyAccessorDescriptorImpl) memberDescriptor).setVisibility(visibility.normalize());
}
}
private static void resolveUnknownVisibilityForOverriddenDescriptors(@NotNull Collection<? extends CallableMemberDescriptor> descriptors, @NotNull BindingTrace trace) {
for (CallableMemberDescriptor descriptor : descriptors) {
if (descriptor.getVisibility() == Visibilities.INHERITED) {
PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor);
JetDeclaration declaration = (element instanceof JetDeclaration) ? (JetDeclaration) element : null;
resolveUnknownVisibilityForMember(declaration, descriptor, trace);
}
}
}
@Nullable
private static Visibility findMaxVisibility(@NotNull Collection<? extends CallableMemberDescriptor> descriptors) {
if (descriptors.isEmpty()) {
return Visibilities.INTERNAL;
}
Visibility maxVisibility = null;
for (CallableMemberDescriptor descriptor : descriptors) {
Visibility visibility = descriptor.getVisibility();
assert visibility != Visibilities.INHERITED;
if (maxVisibility == null) {
maxVisibility = visibility;
continue;
}
Integer compareResult = Visibilities.compare(visibility, maxVisibility);
if (compareResult == null) {
maxVisibility = null;
}
else if (compareResult > 0) {
maxVisibility = visibility;
}
}
if (maxVisibility == null) {
return null;
}
for (CallableMemberDescriptor descriptor : descriptors) {
Integer compareResult = Visibilities.compare(maxVisibility, descriptor.getVisibility());
if (compareResult == null || compareResult < 0) {
return null;
}
}
return maxVisibility;
}
private void checkVisibility() {
for (Map.Entry<JetDeclaration, CallableMemberDescriptor> entry : context.getMembers().entrySet()) {
checkVisibilityForMember(entry.getKey(), entry.getValue());
@@ -16,20 +16,28 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.base.Predicate;
import com.google.common.collect.*;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.PropertyAccessorDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.CANNOT_INFER_VISIBILITY;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
public class OverridingUtil {
private static final List<ExternalOverridabilityCondition> EXTERNAL_CONDITIONS =
@@ -308,6 +316,257 @@ public class OverridingUtil {
}
}
public static void generateOverridesInFunctionGroup(
@SuppressWarnings("UnusedParameters")
@NotNull Name name, //DO NOT DELETE THIS PARAMETER: needed to make sure all descriptors have the same name
@NotNull Collection<? extends CallableMemberDescriptor> membersFromSupertypes,
@NotNull Collection<? extends CallableMemberDescriptor> membersFromCurrent,
@NotNull ClassDescriptor current,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> notOverridden = Sets.newLinkedHashSet(membersFromSupertypes);
for (CallableMemberDescriptor fromCurrent : membersFromCurrent) {
Collection<CallableMemberDescriptor> bound =
extractAndBindOverridesForMember(fromCurrent, membersFromSupertypes, current, sink);
notOverridden.removeAll(bound);
}
createAndBindFakeOverrides(current, notOverridden, sink);
}
private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember(
@NotNull CallableMemberDescriptor fromCurrent,
@NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
@NotNull ClassDescriptor current,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> bound = Lists.newArrayList();
for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
OverrideCompatibilityInfo.Result result = isOverridableBy(fromSupertype, fromCurrent).getResult();
boolean isVisible = Visibilities.isVisible(fromSupertype, current);
switch (result) {
case OVERRIDABLE:
if (isVisible) {
bindOverride(fromCurrent, fromSupertype);
}
bound.add(fromSupertype);
break;
case CONFLICT:
if (isVisible) {
sink.conflict(fromSupertype, fromCurrent);
}
bound.add(fromSupertype);
break;
case INCOMPATIBLE:
break;
}
}
return bound;
}
private static void createAndBindFakeOverrides(
@NotNull ClassDescriptor current,
@NotNull Collection<CallableMemberDescriptor> notOverridden,
@NotNull DescriptorSink sink
) {
Queue<CallableMemberDescriptor> fromSuperQueue = new LinkedList<CallableMemberDescriptor>(notOverridden);
while (!fromSuperQueue.isEmpty()) {
CallableMemberDescriptor notOverriddenFromSuper = VisibilityUtil.findMemberWithMaxVisibility(fromSuperQueue);
Collection<CallableMemberDescriptor> overridables =
extractMembersOverridableInBothWays(notOverriddenFromSuper, fromSuperQueue, sink);
createAndBindFakeOverride(overridables, current, sink);
}
}
private static boolean isMoreSpecific(@NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) {
if (a instanceof SimpleFunctionDescriptor) {
assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();
JetType aReturnType = a.getReturnType();
assert aReturnType != null;
JetType bReturnType = b.getReturnType();
assert bReturnType != null;
return JetTypeChecker.INSTANCE.isSubtypeOf(aReturnType, bReturnType);
}
if (a instanceof PropertyDescriptor) {
assert b instanceof PropertyDescriptor : "b is " + b.getClass();
if (((PropertyDescriptor) a).isVar() || ((PropertyDescriptor) b).isVar()) {
return ((PropertyDescriptor) a).isVar();
}
// both vals
return JetTypeChecker.INSTANCE.isSubtypeOf(((PropertyDescriptor) a).getType(), ((PropertyDescriptor) b).getType());
}
throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
}
private static CallableMemberDescriptor selectMostSpecificMemberFromSuper(@NotNull Collection<CallableMemberDescriptor> overridables) {
CallableMemberDescriptor result = null;
for (CallableMemberDescriptor overridable : overridables) {
if (result == null || isMoreSpecific(overridable, result)) {
result = overridable;
}
}
return result;
}
private static void createAndBindFakeOverride(
@NotNull Collection<CallableMemberDescriptor> overridables,
@NotNull ClassDescriptor current,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> visibleOverridables = filterVisibleFakeOverrides(current, overridables);
Modality modality = getMinimalModality(visibleOverridables);
boolean allInvisible = visibleOverridables.isEmpty();
Collection<CallableMemberDescriptor> effectiveOverridden = allInvisible ? overridables : visibleOverridables;
Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED;
CallableMemberDescriptor mostSpecific = selectMostSpecificMemberFromSuper(effectiveOverridden);
CallableMemberDescriptor fakeOverride =
mostSpecific.copy(current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
for (CallableMemberDescriptor descriptor : effectiveOverridden) {
bindOverride(fakeOverride, descriptor);
}
sink.addToScope(fakeOverride);
}
@NotNull
private static Modality getMinimalModality(@NotNull Collection<CallableMemberDescriptor> descriptors) {
Modality modality = Modality.ABSTRACT;
for (CallableMemberDescriptor descriptor : descriptors) {
if (descriptor.getModality().compareTo(modality) < 0) {
modality = descriptor.getModality();
}
}
return modality;
}
@NotNull
private static Collection<CallableMemberDescriptor> filterVisibleFakeOverrides(
@NotNull final ClassDescriptor current,
@NotNull Collection<CallableMemberDescriptor> toFilter
) {
return Collections2.filter(toFilter, new Predicate<CallableMemberDescriptor>() {
@Override
public boolean apply(@Nullable CallableMemberDescriptor descriptor) {
//nested class could capture private member, so check for private visibility added
return descriptor != null &&
descriptor.getVisibility() != Visibilities.PRIVATE &&
Visibilities.isVisible(descriptor, current);
}
});
}
@NotNull
private static Collection<CallableMemberDescriptor> extractMembersOverridableInBothWays(
@NotNull CallableMemberDescriptor overrider,
@NotNull Queue<CallableMemberDescriptor> extractFrom,
@NotNull DescriptorSink sink
) {
Collection<CallableMemberDescriptor> overridable = Lists.newArrayList();
overridable.add(overrider);
for (Iterator<CallableMemberDescriptor> iterator = extractFrom.iterator(); iterator.hasNext(); ) {
CallableMemberDescriptor candidate = iterator.next();
if (overrider == candidate) {
iterator.remove();
continue;
}
OverrideCompatibilityInfo.Result result1 = isOverridableBy(candidate, overrider).getResult();
OverrideCompatibilityInfo.Result result2 = isOverridableBy(overrider, candidate).getResult();
if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) {
overridable.add(candidate);
iterator.remove();
}
else if (result1 == CONFLICT || result2 == CONFLICT) {
sink.conflict(overrider, candidate);
iterator.remove();
}
}
return overridable;
}
public static void resolveUnknownVisibilityForMember(@Nullable JetDeclaration member, @NotNull CallableMemberDescriptor memberDescriptor, @NotNull BindingTrace trace) {
resolveUnknownVisibilityForOverriddenDescriptors(memberDescriptor.getOverriddenDescriptors(), trace);
if (memberDescriptor.getVisibility() != Visibilities.INHERITED) {
return;
}
Visibility visibility = findMaxVisibility(memberDescriptor.getOverriddenDescriptors());
if (visibility == null) {
if (member != null) {
trace.report(CANNOT_INFER_VISIBILITY.on(member));
}
visibility = Visibilities.PUBLIC;
}
if (memberDescriptor instanceof PropertyDescriptorImpl) {
((PropertyDescriptorImpl)memberDescriptor).setVisibility(visibility.normalize());
for (PropertyAccessorDescriptor accessor : ((PropertyDescriptor) memberDescriptor).getAccessors()) {
resolveUnknownVisibilityForMember(null, accessor, trace);
}
}
else if (memberDescriptor instanceof FunctionDescriptorImpl) {
((FunctionDescriptorImpl)memberDescriptor).setVisibility(visibility.normalize());
}
else {
assert memberDescriptor instanceof PropertyAccessorDescriptorImpl;
((PropertyAccessorDescriptorImpl) memberDescriptor).setVisibility(visibility.normalize());
}
}
private static void resolveUnknownVisibilityForOverriddenDescriptors(@NotNull Collection<? extends CallableMemberDescriptor> descriptors, @NotNull BindingTrace trace) {
for (CallableMemberDescriptor descriptor : descriptors) {
if (descriptor.getVisibility() == Visibilities.INHERITED) {
PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor);
JetDeclaration declaration = (element instanceof JetDeclaration) ? (JetDeclaration) element : null;
resolveUnknownVisibilityForMember(declaration, descriptor, trace);
}
}
}
@Nullable
private static Visibility findMaxVisibility(@NotNull Collection<? extends CallableMemberDescriptor> descriptors) {
if (descriptors.isEmpty()) {
return Visibilities.INTERNAL;
}
Visibility maxVisibility = null;
for (CallableMemberDescriptor descriptor : descriptors) {
Visibility visibility = descriptor.getVisibility();
assert visibility != Visibilities.INHERITED;
if (maxVisibility == null) {
maxVisibility = visibility;
continue;
}
Integer compareResult = Visibilities.compare(visibility, maxVisibility);
if (compareResult == null) {
maxVisibility = null;
}
else if (compareResult > 0) {
maxVisibility = visibility;
}
}
if (maxVisibility == null) {
return null;
}
for (CallableMemberDescriptor descriptor : descriptors) {
Integer compareResult = Visibilities.compare(maxVisibility, descriptor.getVisibility());
if (compareResult == null || compareResult < 0) {
return null;
}
}
return maxVisibility;
}
public interface DescriptorSink {
void addToScope(@NotNull CallableMemberDescriptor fakeOverride);
void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent);
}
public static class OverrideCompatibilityInfo {
public enum Result {
@@ -39,7 +39,10 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescriptor, ClassMemberDeclarationProvider> {
@@ -101,12 +104,12 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
@NotNull final Collection<D> result,
@NotNull final Class<? extends D> exactDescriptorClass
) {
OverrideResolver.generateOverridesInFunctionGroup(
OverridingUtil.generateOverridesInFunctionGroup(
name,
fromSupertypes,
Lists.newArrayList(result),
thisDescriptor,
new OverrideResolver.DescriptorSink() {
new OverridingUtil.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
assert exactDescriptorClass.isInstance(fakeOverride) : "Wrong descriptor type in an override: " +
@@ -140,7 +143,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
if (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue;
PsiElement element =
BindingContextUtils.callableDescriptorToDeclaration(resolveSession.getTrace().getBindingContext(), functionDescriptor);
OverrideResolver.resolveUnknownVisibilityForMember((JetDeclaration) element, functionDescriptor, resolveSession.getTrace());
OverridingUtil.resolveUnknownVisibilityForMember((JetDeclaration) element, functionDescriptor, resolveSession.getTrace());
}
return functions;
}
@@ -214,7 +217,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue;
PsiElement element =
BindingContextUtils.callableDescriptorToDeclaration(resolveSession.getTrace().getBindingContext(), propertyDescriptor);
OverrideResolver.resolveUnknownVisibilityForMember((JetDeclaration) element, propertyDescriptor, resolveSession.getTrace());
OverridingUtil.resolveUnknownVisibilityForMember((JetDeclaration) element, propertyDescriptor, resolveSession.getTrace());
}
return properties;
}
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.java.structure.*;
@@ -70,9 +70,9 @@ public final class DescriptorResolverUtils {
) {
final Set<D> result = new HashSet<D>();
OverrideResolver.generateOverridesInFunctionGroup(
OverridingUtil.generateOverridesInFunctionGroup(
name, membersFromSupertypes, membersFromCurrent, classDescriptor,
new OverrideResolver.DescriptorSink() {
new OverridingUtil.DescriptorSink() {
@Override
@SuppressWarnings("unchecked")
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {