KT-315 I need list of FunctionDEscriptors to be taken from traits

This commit is contained in:
Andrey Breslav
2011-09-21 21:18:46 +04:00
parent 8670d53a0b
commit 4a7c211abe
5 changed files with 106 additions and 39 deletions
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
@@ -11,6 +12,7 @@ import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.Variance;
import java.util.List;
import java.util.Set;
/**
* @author abreslav
@@ -20,6 +22,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
private final Modality modality;
private final boolean isVar;
private final ReceiverDescriptor receiver;
private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet();
private final List<TypeParameterDescriptor> typeParemeters = Lists.newArrayListWithCapacity(0);
private final PropertyDescriptor original;
private PropertyGetterDescriptor getter;
@@ -145,4 +148,14 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
public PropertyDescriptor getOriginal() {
return original;
}
public void addOverriddenDescriptor(PropertyDescriptor overridden) {
overriddenProperties.add(overridden);
}
@NotNull
@Override
public Set<? extends CallableDescriptor> getOverriddenDescriptors() {
return overriddenProperties;
}
}
@@ -94,7 +94,6 @@ public class BodyResolver {
}
private void bindOverridesInAClass(MutableClassDescriptor classDescriptor) {
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
FunctionDescriptor overridden = findFunctionOverridableBy(declaredFunction, supertype);
@@ -103,6 +102,15 @@ public class BodyResolver {
}
}
}
for (PropertyDescriptor propertyDescriptor : classDescriptor.getProperties()) {
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
PropertyDescriptor overridden = findPropertyOverridableBy(propertyDescriptor, supertype);
if (overridden != null) {
propertyDescriptor.addOverriddenDescriptor(overridden);
}
}
}
}
@Nullable
@@ -116,6 +124,32 @@ public class BodyResolver {
return null;
}
@Nullable
private PropertyDescriptor findPropertyOverridableBy(@NotNull PropertyDescriptor declaredProperty, @NotNull JetType supertype) {
PropertyDescriptor property = (PropertyDescriptor) supertype.getMemberScope().getVariable(declaredProperty.getName());
if (property == null) {
return null;
}
if (isOverridableBy(property, declaredProperty)) {
return property;
}
return null;
}
private boolean isOverridableBy(@NotNull PropertyDescriptor property, @NotNull PropertyDescriptor overrideCandidate) {
boolean var = property.isVar();
if (var && !overrideCandidate.isVar()) return false;
JetType propertyType = property.getReturnType();
JetType overrideType = overrideCandidate.getReturnType();
JetTypeChecker typeChecker = context.getSemanticServices().getTypeChecker();
if (var) {
return typeChecker.equalTypes(propertyType, overrideType);
}
else {
return typeChecker.isSubtypeOf(overrideType, propertyType);
}
}
private void checkOverrides() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
checkOverridesInAClass(entry.getValue(), entry.getKey());
@@ -0,0 +1,53 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import java.util.Collection;
import java.util.Set;
/**
* @author abreslav
*/
public class OverridingUtil {
public static Set<CallableDescriptor> getEffectiveMembers(@NotNull ClassDescriptor classDescriptor) {
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors();
Set<CallableDescriptor> allMembers = Sets.newLinkedHashSet();
for (DeclarationDescriptor descriptor : allDescriptors) {
assert !(descriptor instanceof ConstructorDescriptor);
if (descriptor instanceof CallableDescriptor) {
CallableDescriptor callableDescriptor = (CallableDescriptor) descriptor;
allMembers.add(callableDescriptor);
}
}
return filterOverrides(allMembers);
}
public static <D extends CallableDescriptor> Set<D> filterOverrides(Set<D> candidateSet) {
Set<D> candidates = Sets.newLinkedHashSet(candidateSet);
for (D descriptor : candidateSet) {
candidates.removeAll(descriptor.getOverriddenDescriptors());
}
return candidates;
}
public static <Descriptor extends CallableDescriptor> boolean overrides(@NotNull Descriptor f, @NotNull Descriptor g) {
Set<CallableDescriptor> overriddenDescriptors = Sets.newHashSet();
getAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors);
CallableDescriptor originalG = g.getOriginal();
for (CallableDescriptor overriddenFunction : overriddenDescriptors) {
if (originalG.equals(overriddenFunction.getOriginal())) return true;
}
return false;
}
private static void getAllOverriddenDescriptors(@NotNull CallableDescriptor current, @NotNull Set<CallableDescriptor> overriddenDescriptors) {
if (overriddenDescriptors.contains(current)) return;
for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) {
getAllOverriddenDescriptors(descriptor, overriddenDescriptors);
overriddenDescriptors.add(descriptor);
}
}
}
@@ -524,7 +524,7 @@ public class CallResolver {
return OverloadResolutionResult.success(maximallySpecificGenericsDiscriminated);
}
Set<D> noOverrides = filterOverrides(successfulCandidates.keySet());
Set<D> noOverrides = OverridingUtil.filterOverrides(successfulCandidates.keySet());
if (dirtyCandidates.isEmpty()) {
// tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: "
// + makeErrorMessageForMultipleDescriptors(noOverrides));
@@ -547,7 +547,7 @@ public class CallResolver {
}
else if (!failedCandidates.isEmpty()) {
if (failedCandidates.size() != 1) {
Set<D> noOverrides = filterOverrides(failedCandidates);
Set<D> noOverrides = OverridingUtil.filterOverrides(failedCandidates);
if (noOverrides.size() != 1) {
// tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: "
// + makeErrorMessageForMultipleDescriptors(noOverrides));
@@ -568,20 +568,6 @@ public class CallResolver {
}
}
private <D extends CallableDescriptor> Set<D> filterOverrides(Set<D> candidateSet) {
Set<D> candidates = Sets.newLinkedHashSet();
outerLoop:
for (D me : candidateSet) {
for (D other : candidateSet) {
if (OverloadingConflictResolver.overrides(other, me)) {
continue outerLoop;
}
}
candidates.add(me);
}
return candidates;
}
private boolean checkValueArgumentTypes(JetScope scope, JetTypeInferrer.Services temporaryServices, Map<ValueArgument, ValueParameterDescriptor> argumentsToParameters, Flag dirty, Function<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap) {
boolean result = true;
for (Map.Entry<ValueArgument, ValueParameterDescriptor> entry : argumentsToParameters.entrySet()) {
@@ -1,13 +1,13 @@
package org.jetbrains.jet.lang.resolve.calls;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
@@ -15,7 +15,6 @@ import org.jetbrains.jet.lang.types.JetType;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author abreslav
@@ -57,8 +56,8 @@ import java.util.Set;
* Int < Short < Byte
*/
private <Descriptor extends CallableDescriptor> boolean moreSpecific(Descriptor f, Descriptor g, boolean discriminateGenericDescriptors) {
if (overrides(f, g)) return true;
if (overrides(g, f)) return false;
if (OverridingUtil.overrides(f, g)) return true;
if (OverridingUtil.overrides(g, f)) return false;
ReceiverDescriptor receiverOfF = f.getReceiver();
ReceiverDescriptor receiverOfG = g.getReceiver();
@@ -121,22 +120,4 @@ import java.util.Set;
return false;
}
public static <Descriptor extends CallableDescriptor> boolean overrides(@NotNull Descriptor f, @NotNull Descriptor g) {
Set<CallableDescriptor> overriddenDescriptors = Sets.newHashSet();
getAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors);
CallableDescriptor originalG = g.getOriginal();
for (CallableDescriptor overriddenFunction : overriddenDescriptors) {
if (originalG.equals(overriddenFunction.getOriginal())) return true;
}
return false;
}
private static void getAllOverriddenDescriptors(@NotNull CallableDescriptor current, @NotNull Set<CallableDescriptor> overriddenDescriptors) {
if (overriddenDescriptors.contains(current)) return;
for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) {
getAllOverriddenDescriptors(descriptor, overriddenDescriptors);
overriddenDescriptors.add(descriptor);
}
}
}