LR: Delegation supported

This commit is contained in:
Andrey Breslav
2012-07-19 16:52:39 +04:00
parent 67900e9dfa
commit 4c71624997
2 changed files with 88 additions and 5 deletions
@@ -23,10 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -42,6 +39,28 @@ import java.util.*;
*/
public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescriptor, ClassMemberDeclarationProvider> {
private interface MemberExtractor<T extends CallableMemberDescriptor> {
MemberExtractor<FunctionDescriptor> EXTRACT_FUNCTIONS = new MemberExtractor<FunctionDescriptor>() {
@NotNull
@Override
public Collection<FunctionDescriptor> extract(@NotNull JetType extractFrom, @NotNull Name name) {
return extractFrom.getMemberScope().getFunctions(name);
}
};
MemberExtractor<PropertyDescriptor> EXTRACT_PROPERTIES = new MemberExtractor<PropertyDescriptor>() {
@NotNull
@Override
public Collection<PropertyDescriptor> extract(@NotNull JetType extractFrom, @NotNull Name name) {
//noinspection unchecked
return (Collection) extractFrom.getMemberScope().getProperties(name);
}
};
@NotNull
Collection<T> extract(@NotNull JetType extractFrom, @NotNull Name name);
}
private ConstructorDescriptor primaryConstructor;
private boolean primaryConstructorResolved = false;
@@ -118,6 +137,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
}
generateDelegatingDescriptors(name, MemberExtractor.EXTRACT_FUNCTIONS, result);
generateFakeOverrides(name, fromSupertypes, result, FunctionDescriptor.class);
}
@@ -178,15 +198,37 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
}
// Members from supertypes
Collection<PropertyDescriptor> fromSupertypes = Lists.newArrayList();
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
fromSupertypes.addAll((Set) supertype.getMemberScope().getProperties(name));
}
generateDelegatingDescriptors(name, MemberExtractor.EXTRACT_PROPERTIES, result);
generateFakeOverrides(name, fromSupertypes, (Set) result, PropertyDescriptor.class);
}
private <T extends CallableMemberDescriptor> void generateDelegatingDescriptors(
@NotNull Name name,
@NotNull MemberExtractor<T> extractor,
@NotNull Set<? super T> result
) {
for (JetDelegationSpecifier delegationSpecifier : declarationProvider.getOwnerInfo().getDelegationSpecifiers()) {
if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) {
JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier;
JetTypeReference typeReference = specifier.getTypeReference();
if (typeReference != null) {
JetType supertype = resolveSession.getInjector().getTypeResolver().resolveType(
thisDescriptor.getScopeForClassHeaderResolution(),
typeReference,
resolveSession.getTrace(),
false);
Collection<T> descriptors =
DelegationResolver.generateDelegatedMembers(thisDescriptor, extractor.extract(supertype, name));
result.addAll(descriptors);
}
}
}
}
@Override
protected void addExtraDescriptors() {
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
@@ -0,0 +1,41 @@
namespace <root>
internal open class Br : T {
public final /*constructor*/ fun <init>(/*0*/ t: T): Br
internal abstract override /*1*/ fun foo(): jet.Tuple0
internal abstract override /*1*/ val v: jet.Int
}
internal open class Br1 : T {
public final /*constructor*/ fun <init>(/*0*/ t: T): Br1
internal open override /*1*/ fun foo(): jet.Tuple0
internal open override /*1*/ val v: jet.Int
}
internal final class Br2 : Br1 {
public final /*constructor*/ fun <init>(/*0*/ t: T): Br2
internal open override /*1*/ fun foo(): jet.Tuple0
internal open override /*1*/ val v: jet.Int
}
internal final class Br3 : Br {
public final /*constructor*/ fun <init>(/*0*/ t: T): Br3
internal abstract override /*1*/ fun foo(): jet.Tuple0
internal abstract override /*1*/ val v: jet.Int
}
internal abstract trait G</*0*/ T : jet.Any?> : jet.Any {
internal abstract fun foo(/*0*/ t: T): T
}
internal final class GC : G<jet.Int> {
public final /*constructor*/ fun <init>(): GC
internal abstract override /*1*/ fun foo(/*0*/ t: jet.Int): jet.Int
}
internal open class GC1 : G<jet.Int> {
public final /*constructor*/ fun <init>(/*0*/ g: G<jet.Int>): GC1
internal open override /*1*/ fun foo(/*0*/ t: jet.Int): jet.Int
}
internal open class GC2 : GC1 {
public final /*constructor*/ fun <init>(/*0*/ g: G<jet.Int>): GC2
internal open override /*1*/ fun foo(/*0*/ t: jet.Int): jet.Int
}
internal abstract trait T : jet.Any {
internal abstract fun foo(): jet.Tuple0
internal abstract val v: jet.Int
}