From 136b07e7e13553a331fd07282d0fdb7cb20b7536 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 25 Apr 2012 20:08:38 +0400 Subject: [PATCH] Introduced the notion of "overriding" for value parameters Example: trait A { fun foo(a : Int) } class B : A { override fun foo(a : Int) {} } B.foo.a overrides A.foo.a --- .../lang/descriptors/FunctionDescriptorImpl.java | 5 +++-- .../jet/lang/descriptors/PropertyDescriptor.java | 5 +++-- .../descriptors/ValueParameterDescriptor.java | 12 ++++++++++++ .../ValueParameterDescriptorImpl.java | 16 +++++++++++++++- .../jet/lang/resolve/OverrideResolver.java | 8 +++----- .../jet/lang/resolve/OverridingUtil.java | 11 +++++++++++ 6 files changed, 47 insertions(+), 10 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java index 96c7cae015e..b71c09f28b6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java @@ -21,6 +21,7 @@ import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.OverridingUtil; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; @@ -47,7 +48,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i protected Modality modality; protected Visibility visibility; - protected final Set overriddenFunctions = Sets.newLinkedHashSet(); + protected final Set overriddenFunctions = Sets.newLinkedHashSet(); // LinkedHashSet is essential here private final FunctionDescriptor original; private final Kind kind; @@ -230,7 +231,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i ); if (copyOverrides) { for (FunctionDescriptor overriddenFunction : overriddenFunctions) { - substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor)); + OverridingUtil.bindOverride(substitutedDescriptor, overriddenFunction.substitute(substitutor)); } } return substitutedDescriptor; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java index a7edd5d4ea5..fc8a496610d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.OverridingUtil; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; @@ -42,7 +43,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab private Visibility visibility; private final boolean isVar; private final boolean isObject; - private final Set overriddenProperties = Sets.newLinkedHashSet(); + private final Set overriddenProperties = Sets.newLinkedHashSet(); // LinkedHashSet is essential here private final PropertyDescriptor original; private final Kind kind; @@ -268,7 +269,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab if (copyOverrides) { for (PropertyDescriptor propertyDescriptor : overriddenProperties) { - substitutedDescriptor.addOverriddenDescriptor(propertyDescriptor.substitute(substitutor)); + OverridingUtil.bindOverride(substitutedDescriptor, propertyDescriptor.substitute(substitutor)); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java index 5a3c4a17c52..4893e9f4598 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java @@ -21,6 +21,8 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.types.JetType; +import java.util.Set; + /** * @author abreslav */ @@ -46,4 +48,14 @@ public interface ValueParameterDescriptor extends VariableDescriptor, Annotated @NotNull ValueParameterDescriptor copy(DeclarationDescriptor newOwner); + /** + * Parameter p1 overrides p2 iff + * a) their respective owners (function declarations) f1 override f2 + * b) p1 and p2 have the same indices in the owners' parameter lists + */ + @NotNull + @Override + Set getOverriddenDescriptors(); + + void addOverriddenDescriptor(@NotNull ValueParameterDescriptor overridden); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java index 09ff2883b3f..9928db66858 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java @@ -17,6 +17,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; @@ -24,6 +25,7 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeSubstitutor; import java.util.List; +import java.util.Set; /** * @author abreslav @@ -34,6 +36,7 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme private final boolean isVar; private final int index; private final ValueParameterDescriptor original; + private final Set overriddenDescriptors = Sets.newHashSet(); public ValueParameterDescriptorImpl( @NotNull DeclarationDescriptor containingDeclaration, @@ -59,7 +62,7 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme boolean isVar, @NotNull JetType outType, @Nullable JetType varargElementType - ) { + ) { super(containingDeclaration, annotations, original.getName(), outType); this.original = original; this.index = original.getIndex(); @@ -131,4 +134,15 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme public Visibility getVisibility() { return Visibilities.LOCAL; } + + @NotNull + @Override + public Set getOverriddenDescriptors() { + return overriddenDescriptors; + } + + @Override + public void addOverriddenDescriptor(@NotNull ValueParameterDescriptor overridden) { + overriddenDescriptors.add(overridden); + } } 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 cb1e794bf8c..2884df035e7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -36,7 +36,6 @@ import javax.inject.Inject; import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR; import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED; /** @@ -176,7 +175,7 @@ public class OverrideResolver { for (CallableMemberDescriptor functionFromCurrent : functionsFromCurrent) { OverridingUtil.OverrideCompatibilityInfo.Result result = OverridingUtil.isOverridableBy(functionFromSupertype, functionFromCurrent).getResult(); if (result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) { - functionFromCurrent.addOverriddenDescriptor(functionFromSupertype); + OverridingUtil.bindOverride(functionFromCurrent, functionFromSupertype); overrides = true; } else if (result == OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT) { @@ -186,14 +185,14 @@ public class OverrideResolver { for (CallableMemberDescriptor fakeOverride : fakeOverrideList) { if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) { - fakeOverride.addOverriddenDescriptor(functionFromSupertype); + OverridingUtil.bindOverride(fakeOverride, functionFromSupertype); overrides = true; } } if (!overrides) { CallableMemberDescriptor fakeOverride = functionFromSupertype.copy(current, false, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false); - fakeOverride.addOverriddenDescriptor(functionFromSupertype); + OverridingUtil.bindOverride(fakeOverride, functionFromSupertype); fakeOverrideList.add(fakeOverride); if (fakeOverrides != null) { fakeOverrides.add(fakeOverride); @@ -203,7 +202,6 @@ public class OverrideResolver { } } - private static MultiMap groupDescriptorsByName(Collection properties) { MultiMap r = new LinkedMultiMap(); for (T property : properties) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java index 4a3872c6945..d2a9429311e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java @@ -268,6 +268,17 @@ public class OverridingUtil { } } + public static void bindOverride(CallableMemberDescriptor fromCurrent, CallableMemberDescriptor fromSupertype) { + fromCurrent.addOverriddenDescriptor(fromSupertype); + + for (ValueParameterDescriptor parameterFromCurrent : fromCurrent.getValueParameters()) { + assert parameterFromCurrent.getIndex() < fromSupertype.getValueParameters().size() + : "An override relation between functions implies that they have the same number of value parameters"; + ValueParameterDescriptor parameterFromSupertype = fromSupertype.getValueParameters().get(parameterFromCurrent.getIndex()); + parameterFromCurrent.addOverriddenDescriptor(parameterFromSupertype); + } + } + public static class OverrideCompatibilityInfo { public enum Result {