diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java index 1b8889a40b3..db805687a7b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java @@ -11,4 +11,7 @@ public interface CallableMemberDescriptor extends CallableDescriptor, MemberDesc @NotNull @Override Set getOverriddenDescriptors(); + + @NotNull + CallableMemberDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java index 0f00d025056..5afac7ed85c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java @@ -28,7 +28,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements @Override @Deprecated - public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull List typeParameters, @NotNull List unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, Modality modality, Visibility visibility) { + public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull List typeParameters, @NotNull List unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, Modality modality, @NotNull Visibility visibility) { assert receiverType == null; return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modality, visibility); } @@ -78,4 +78,10 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements Collections.emptyList(), // TODO isPrimary); } + + @NotNull + @Override + public ConstructorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) { + throw new UnsupportedOperationException("Constructors should not be copied for overriding"); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java index ecfe2a80bc5..e69f6d3cbe2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptor.java @@ -23,4 +23,8 @@ public interface FunctionDescriptor extends CallableMemberDescriptor { @Override @NotNull Set getOverriddenDescriptors(); + + @NotNull + @Override + FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract); } 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 c087c90fdd5..a6c3f0b9872 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java @@ -5,6 +5,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.DescriptorUtils; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.DescriptorSubstitutor; @@ -175,24 +176,18 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements return visitor.visitFunctionDescriptor(this, data); } -// @Override -// public boolean equals(Object obj) { -// if (obj == null) return false; -// if (obj.getClass() != FunctionDescriptorImpl.class) return false; -// FunctionDescriptorImpl other = (FunctionDescriptorImpl) obj; -// if (!eq(this.getName(), other.getName())) return false; -// if (!eq(this.getContainingDeclaration(), other.getContainingDeclaration())) return false; -// -// } -// -// private static boolean eq(Object a, Object b) { -// if (a == null) return b == null; -// if (b == null) return false; -// return a.equals(b); -// } -// -// @Override -// public int hashCode() { -// return super.hashCode(); // TODO -// } + @NotNull + @Override + public FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) { + FunctionDescriptorImpl copy = new FunctionDescriptorImpl(newOwner, Lists.newArrayList(getAnnotations()), getName()); + copy.initialize( + getReceiver().exists() ? getReceiver().getType() : null, + DescriptorUtils.copyTypeParameters(copy, typeParameters), + DescriptorUtils.copyValueParameters(copy, unsubstitutedValueParameters), + unsubstitutedReturnType, + DescriptorUtils.convertModality(modality, makeNonAbstract), + visibility + ); + return copy; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Modality.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Modality.java index e836f719f34..33e2f6e8235 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Modality.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Modality.java @@ -8,14 +8,14 @@ public enum Modality { OPEN(true), ABSTRACT(true); - private final boolean open; + private final boolean overridable; - private Modality(boolean open) { - this.open = open; + private Modality(boolean overridable) { + this.overridable = overridable; } - public boolean isOpen() { - return open; + public boolean isOverridable() { + return overridable; } public static Modality convertFromFlags(boolean _abstract, boolean open) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 39014c9d2fc..2400cad6510 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -172,7 +172,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme this.typeConstructor = new TypeConstructorImpl( this, Collections.emptyList(), // TODO : pass annotations from the class? - !modality.isOpen(), + !modality.isOverridable(), getName(), typeParameters, supertypes); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyAccessorDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyAccessorDescriptor.java index d626a45417d..023a235c3d8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyAccessorDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyAccessorDescriptor.java @@ -76,4 +76,10 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm public PropertyDescriptor getCorrespondingProperty() { return correspondingProperty; } + + @NotNull + @Override + public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) { + throw new UnsupportedOperationException("Accessors must be copied by the corresponding property"); + } } 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 a4c897e05bd..5c6c5212c78 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java @@ -5,6 +5,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.DescriptorUtils; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; @@ -168,5 +169,27 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab @Override public Set getOverriddenDescriptors() { return overriddenProperties; + + } + @NotNull + @Override + public PropertyDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) { + PropertyDescriptor propertyDescriptor = new PropertyDescriptor( + newOwner, + Lists.newArrayList(getAnnotations()), + DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar, + receiver.exists() ? receiver.getType() : null, getName(), getInType(), getOutType()); + PropertyGetterDescriptor newGetter = getter == null ? null : new PropertyGetterDescriptor( + propertyDescriptor, Lists.newArrayList(getter.getAnnotations()), + DescriptorUtils.convertModality(getter.getModality(), makeNonAbstract), getter.getVisibility(), + getter.getReturnType(), + getter.hasBody(), getter.isDefault()); + PropertySetterDescriptor newSetter = setter == null ? null : new PropertySetterDescriptor( + DescriptorUtils.convertModality(setter.getModality(), makeNonAbstract), setter.getVisibility(), + propertyDescriptor, + Lists.newArrayList(setter.getAnnotations()), + setter.hasBody(), setter.isDefault());; + propertyDescriptor.initialize(DescriptorUtils.copyTypeParameters(propertyDescriptor, getTypeParameters()), newGetter, newSetter); + return propertyDescriptor; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java index 677f34481bc..747a27e64a7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java @@ -18,7 +18,7 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor { private final Set overriddenGetters = Sets.newHashSet(); private JetType returnType; - public PropertyGetterDescriptor(@NotNull Modality modality, @NotNull Visibility visibility, @NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, @Nullable JetType returnType, boolean hasBody, boolean isDefault) { + public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, @NotNull Modality modality, @NotNull Visibility visibility, @Nullable JetType returnType, boolean hasBody, boolean isDefault) { super(modality, visibility, correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody, isDefault); this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java index 5381a9e7d85..13752d9743c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java @@ -64,5 +64,4 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor { public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitPropertySetterDescriptor(this, data); } - } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java index d441e8a3756..f67fa35e749 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java @@ -1,5 +1,6 @@ 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.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -157,4 +158,9 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement public int getIndex() { return index; } + + @NotNull + public TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) { + return new TypeParameterDescriptor(newOwner, Lists.newArrayList(getAnnotations()), variance, getName(), index); + } } 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 7ac25d5dc5e..ba7131b36c0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java @@ -23,4 +23,7 @@ public interface ValueParameterDescriptor extends VariableDescriptor { @Override ValueParameterDescriptor getOriginal(); + + @NotNull + ValueParameterDescriptor copy(DeclarationDescriptor newOwner); } 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 12c3be36e8c..8b13a526dc7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.descriptors; +import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -96,9 +97,15 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitValueParameterDescriptor(this, data); } - + @Override public boolean isVar() { return isVar; } + + @NotNull + @Override + public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) { + return new ValueParameterDescriptorImpl(newOwner, index, Lists.newArrayList(getAnnotations()), getName(), getInType(), getOutType(), hasDefaultValue, isVararg); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableAsFunctionDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableAsFunctionDescriptor.java index af1840edf05..88462653cfc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableAsFunctionDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableAsFunctionDescriptor.java @@ -31,4 +31,10 @@ public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl { public VariableDescriptor getVariableDescriptor() { return variableDescriptor; } -} + + @NotNull + @Override + public VariableAsFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) { + throw new UnsupportedOperationException("Should not be copied for overriding"); + } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index ec82ca8b18a..01c4cb717ad 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -40,6 +40,7 @@ public interface BindingContext { WritableSlice VARIABLE_ASSIGNMENT = Slices.createSimpleSlice("VARIABLE_ASSIGNMENT"); WritableSlice PROCESSED = Slices.createSimpleSetSlice("PROCESSED"); WritableSlice STATEMENT = Slices.createRemovableSetSlice("STATEMENT"); + WritableSlice DELEGATED = Slices.createRemovableSetSlice("DELEGATED"); WritableSlice BACKING_FIELD_REQUIRED = new Slices.SetSlice("BACKING_FIELD_REQUIRED", RewritePolicy.DO_NOTHING) { @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index c34fe426683..4690faad394 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -708,16 +708,16 @@ public class ClassDescriptorResolver { } getterDescriptor = new PropertyGetterDescriptor( - resolveModalityFromModifiers(trace, getter.getModifierList(), propertyDescriptor.getModality()), + propertyDescriptor, annotations, resolveModalityFromModifiers(trace, getter.getModifierList(), propertyDescriptor.getModality()), resolveVisibilityFromModifiers(trace, getter.getModifierList(), propertyDescriptor.getVisibility()), - propertyDescriptor, annotations, returnType, getter.getBodyExpression() != null, false); + returnType, getter.getBodyExpression() != null, false); trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor); } else { getterDescriptor = new PropertyGetterDescriptor( - propertyDescriptor.getModality(), + propertyDescriptor, Collections.emptyList(), propertyDescriptor.getModality(), propertyDescriptor.getVisibility(), - propertyDescriptor, Collections.emptyList(), propertyDescriptor.getOutType(), false, true); + propertyDescriptor.getOutType(), false, true); } return getterDescriptor; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegationResolver.java new file mode 100644 index 00000000000..9fb7350d280 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegationResolver.java @@ -0,0 +1,66 @@ +package org.jetbrains.jet.lang.resolve; + +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.MutableClassDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.types.JetType; + +import java.util.Map; + +import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED; + +/** + * @author abreslav + */ +public class DelegationResolver { + private final TopDownAnalysisContext context; + + public DelegationResolver(TopDownAnalysisContext context) { + this.context = context; + } + + public void process() { + addDelegatedMembers(); + } + + private void addDelegatedMembers() { + for (Map.Entry entry : context.getClasses().entrySet()) { + addDelegatedMembers(entry.getKey(), entry.getValue()); + } + for (Map.Entry entry : context.getObjects().entrySet()) { + addDelegatedMembers(entry.getKey(), entry.getValue()); + } + } + + private void addDelegatedMembers(JetClassOrObject jetClass, MutableClassDescriptor classDescriptor) { + for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) { + if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) { + JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier; + JetType type = context.getTrace().get(BindingContext.TYPE, specifier.getTypeReference()); + if (type != null) { + for (DeclarationDescriptor declarationDescriptor : type.getMemberScope().getAllDescriptors()) { + if (declarationDescriptor instanceof PropertyDescriptor) { + PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor; + if (propertyDescriptor.getModality().isOverridable()) { + PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, true); + classDescriptor.addPropertyDescriptor(copy); + context.getTrace().record(DELEGATED, copy); + } + } + else if (declarationDescriptor instanceof FunctionDescriptor) { + FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor; + if (functionDescriptor.getModality().isOverridable()) { + FunctionDescriptor copy = functionDescriptor.copy(classDescriptor, true); + classDescriptor.addFunctionDescriptor(copy); + context.getTrace().record(DELEGATED, copy); + } + } + } + } + } + } + } + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index cd8bdea4078..42fb64620ed 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.resolve; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; @@ -89,4 +90,25 @@ public class DescriptorUtils { } }); } + + public static List copyValueParameters(DeclarationDescriptor newOwner, List parameters) { + List result = Lists.newArrayList(); + for (ValueParameterDescriptor parameter : parameters) { + result.add(parameter.copy(newOwner)); + } + return result; + } + + public static List copyTypeParameters(DeclarationDescriptor newOwner, List parameters) { + List result = Lists.newArrayList(); + for (TypeParameterDescriptor parameter : parameters) { + result.add(parameter.copy(newOwner)); + } + return result; + } + + public static Modality convertModality(Modality modality, boolean makeNonAbstract) { + if (makeNonAbstract && modality == Modality.ABSTRACT) return Modality.OPEN; + return modality; + } } 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 dfd60ff8dd5..67e12a470e7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -17,6 +17,7 @@ import java.util.Map; import java.util.Set; import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED; /** * @author abreslav @@ -104,28 +105,13 @@ public class OverrideResolver { // Check if everything that must be overridden, actually is // Everything from supertypes - Set delegatedByExpression = Sets.newHashSet(); - for (JetDelegationSpecifier delegationSpecifier : klass.getDelegationSpecifiers()) { - if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) { - JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier; - JetType type = context.getTrace().get(BindingContext.TYPE, specifier.getTypeReference()); - if (type != null) { - delegatedByExpression.add(type); - } - } - } - Map implementedWithDelegationBy = Maps.newHashMap(); Set inheritedFunctions = Sets.newLinkedHashSet(); for (JetType supertype : classDescriptor.getSupertypes()) { - boolean delegatedBy = delegatedByExpression.contains(supertype); for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) { if (descriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor; inheritedFunctions.add(memberDescriptor); - if (delegatedBy && memberDescriptor.getModality().isOpen()) { - implementedWithDelegationBy.put(memberDescriptor, createOverridingDescriptor(classDescriptor, memberDescriptor)); - } } } } @@ -230,14 +216,13 @@ public class OverrideResolver { // } } - @Nullable - private CallableMemberDescriptor createOverridingDescriptor(@NotNull MutableClassDescriptor subClass, @NotNull CallableMemberDescriptor superDescriptor) { - return null; - } - private void checkOverride(CallableMemberDescriptor declared) { JetNamedDeclaration member = (JetNamedDeclaration) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declared); - assert member != null; + if (member == null) { + assert context.getTrace().get(DELEGATED, declared); + return; + } + JetModifierList modifierList = member.getModifierList(); ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null; boolean hasOverrideModifier = overrideNode != null; @@ -248,7 +233,7 @@ public class OverrideResolver { for (CallableMemberDescriptor overridden : declared.getOverriddenDescriptors()) { if (overridden != null) { if (hasOverrideModifier) { - if (!overridden.getModality().isOpen() && !finalOverriddenError) { + if (!overridden.getModality().isOverridable() && !finalOverriddenError) { // context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and cannot be overridden"); context.getTrace().report(OVERRIDING_FINAL_MEMBER.on(overrideNode, overridden, overridden.getContainingDeclaration())); finalOverriddenError = true; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 457807e60f0..43d992ed5ce 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -65,6 +65,7 @@ public class TopDownAnalyzer { TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace); new TypeHierarchyResolver(context).process(outerScope, owner, declarations); new DeclarationResolver(context).process(); + new DelegationResolver(context).process(); new OverrideResolver(context).process(); new BodyResolver(context).resolveBehaviorDeclarationBodies(); } @@ -78,6 +79,7 @@ public class TopDownAnalyzer { context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace); new TypeHierarchyResolver(context).process(outerScope, standardLibraryNamespace, namespace.getDeclarations()); new DeclarationResolver(context).process(); + new DelegationResolver(context).process(); OverrideResolver overrideResolver = new OverrideResolver(context) { @Override protected void checkOverridesInAClass(MutableClassDescriptor classDescriptor, JetClassOrObject klass) { diff --git a/idea/testData/checkerWithErrorTypes/quick/DelegationAndOverriding.jet b/idea/testData/checkerWithErrorTypes/quick/DelegationAndOverriding.jet new file mode 100644 index 00000000000..388653da85a --- /dev/null +++ b/idea/testData/checkerWithErrorTypes/quick/DelegationAndOverriding.jet @@ -0,0 +1,38 @@ +//namespace override + +trait T { + fun foo() + val v : Int +} + +open class Br(t : T) : T { + +} + +class Br3(t : T) : Br(t) { + +} + +open class Br1(t : T) : T by t { + +} + +class Br2(t : T) : Br1(t) { + +} + +trait G { + fun foo(t : T) : T +} + +class GC() : G { + +} + +open class GC1(g : G) : G by g { + +} + +open class GC2(g : G) : GC1(g) { + +} \ No newline at end of file