Supporting fake overrides for properties and constructors for class objects
This commit is contained in:
@@ -46,6 +46,7 @@ import javax.inject.Inject;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -346,6 +347,25 @@ public class DescriptorResolver {
|
|||||||
return typeParameterDescriptor;
|
return typeParameterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ConstructorDescriptorImpl createPrimaryConstructorForObject(
|
||||||
|
@NotNull PsiElement object,
|
||||||
|
@NotNull ClassDescriptor classDescriptor,
|
||||||
|
@NotNull BindingTrace trace
|
||||||
|
) {
|
||||||
|
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(classDescriptor, Collections
|
||||||
|
.<AnnotationDescriptor>emptyList(), true);
|
||||||
|
|
||||||
|
// TODO : make the constructor private?
|
||||||
|
// TODO check set classDescriptor.getVisibility()
|
||||||
|
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
|
Collections.<ValueParameterDescriptor>emptyList(), Visibilities.INTERNAL);
|
||||||
|
|
||||||
|
if (object != null) {
|
||||||
|
trace.record(CONSTRUCTOR, object, constructorDescriptor);
|
||||||
|
}
|
||||||
|
return constructorDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
final class UpperBoundCheckerTask {
|
final class UpperBoundCheckerTask {
|
||||||
JetTypeReference upperBound;
|
JetTypeReference upperBound;
|
||||||
JetType upperBoundType;
|
JetType upperBoundType;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import com.intellij.psi.PsiNameIdentifierOwner;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
@@ -329,17 +328,9 @@ public class TypeHierarchyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createPrimaryConstructorForObject(@Nullable PsiElement object, MutableClassDescriptor mutableClassDescriptor) {
|
private void createPrimaryConstructorForObject(@Nullable PsiElement object, MutableClassDescriptor mutableClassDescriptor) {
|
||||||
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
|
ConstructorDescriptor constructorDescriptor = DescriptorResolver
|
||||||
|
.createPrimaryConstructorForObject(object, mutableClassDescriptor, trace);
|
||||||
// TODO check set mutableClassDescriptor.getVisibility()
|
|
||||||
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
|
|
||||||
Collections.<ValueParameterDescriptor>emptyList(), Visibilities.INTERNAL);
|
|
||||||
|
|
||||||
// TODO : make the constructor private?
|
|
||||||
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, trace);
|
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, trace);
|
||||||
if (object != null) {
|
|
||||||
trace.record(CONSTRUCTOR, object, constructorDescriptor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareForDeferredCall(@NotNull JetScope outerScope,
|
private void prepareForDeferredCall(@NotNull JetScope outerScope,
|
||||||
@@ -356,7 +347,6 @@ public class TypeHierarchyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static ClassKind getClassKind(@NotNull JetClass jetClass) {
|
private static ClassKind getClassKind(@NotNull JetClass jetClass) {
|
||||||
if (jetClass.isTrait()) return ClassKind.TRAIT;
|
if (jetClass.isTrait()) return ClassKind.TRAIT;
|
||||||
|
|||||||
+46
-23
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
|||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
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.OverrideResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
@@ -61,12 +62,12 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
return thisDescriptor.getScopeForMemberDeclarationResolution();
|
return thisDescriptor.getScopeForMemberDeclarationResolution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private <D extends CallableMemberDescriptor> void generateFakeOverrides(
|
||||||
protected void getNonDeclaredFunctions(@NotNull Name name, @NotNull final Set<FunctionDescriptor> result) {
|
@NotNull Name name,
|
||||||
Collection<FunctionDescriptor> fromSupertypes = Lists.newArrayList();
|
@NotNull Collection<D> fromSupertypes,
|
||||||
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
@NotNull final Collection<D> result,
|
||||||
fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
|
@NotNull final Class<? extends D> exactDescriptorClass
|
||||||
}
|
) {
|
||||||
OverrideResolver.generateOverridesInFunctionGroup(
|
OverrideResolver.generateOverridesInFunctionGroup(
|
||||||
name,
|
name,
|
||||||
fromSupertypes,
|
fromSupertypes,
|
||||||
@@ -75,9 +76,9 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
new OverrideResolver.DescriptorSink() {
|
new OverrideResolver.DescriptorSink() {
|
||||||
@Override
|
@Override
|
||||||
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
||||||
assert fakeOverride instanceof FunctionDescriptor : "A non-function overrides a function";
|
assert exactDescriptorClass.isInstance(fakeOverride) : "Wrong descriptor type in an override: " + fakeOverride + " while expecting " + exactDescriptorClass.getSimpleName();
|
||||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) fakeOverride;
|
//noinspection unchecked
|
||||||
result.add(functionDescriptor);
|
result.add((D) fakeOverride);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -90,16 +91,28 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
protected void getNonDeclaredFunctions(@NotNull Name name, @NotNull final Set<FunctionDescriptor> result) {
|
||||||
System.err.println("getNonDeclaredProperties() should generate fake overrides for a class");
|
Collection<FunctionDescriptor> fromSupertypes = Lists.newArrayList();
|
||||||
|
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||||
|
fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
|
||||||
|
}
|
||||||
|
generateFakeOverrides(name, fromSupertypes, result, FunctionDescriptor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull final Set<VariableDescriptor> result) {
|
||||||
|
System.err.println("Parameter of the primary constructor");
|
||||||
|
|
||||||
// Inherited fake overrides
|
// Inherited fake overrides
|
||||||
// Parameters of the primary constructor
|
Collection<PropertyDescriptor> fromSupertypes = Lists.newArrayList();
|
||||||
|
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
fromSupertypes.addAll((Set) supertype.getMemberScope().getProperties(name));
|
||||||
|
}
|
||||||
|
generateFakeOverrides(name, fromSupertypes, (Set) result, PropertyDescriptor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -137,25 +150,35 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
@Nullable
|
@Nullable
|
||||||
public ConstructorDescriptor getPrimaryConstructor() {
|
public ConstructorDescriptor getPrimaryConstructor() {
|
||||||
if (!primaryConstructorResolved) {
|
if (!primaryConstructorResolved) {
|
||||||
if (EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS).contains(thisDescriptor.getKind())) {
|
if (EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT).contains(thisDescriptor.getKind())) {
|
||||||
JetClassOrObject classOrObject = declarationProvider.getOwnerClassOrObject();
|
JetClassOrObject classOrObject = declarationProvider.getOwnerClassOrObject();
|
||||||
if (classOrObject instanceof JetClass) {
|
if (classOrObject instanceof JetClass) {
|
||||||
JetClass jetClass = (JetClass) classOrObject;
|
JetClass jetClass = (JetClass) classOrObject;
|
||||||
ConstructorDescriptorImpl descriptor = resolveSession.getInjector().getDescriptorResolver()
|
ConstructorDescriptorImpl constructor = resolveSession.getInjector().getDescriptorResolver()
|
||||||
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor,
|
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor,
|
||||||
jetClass,
|
jetClass,
|
||||||
resolveSession.getTrace());
|
resolveSession.getTrace());
|
||||||
primaryConstructor = descriptor;
|
primaryConstructor = constructor;
|
||||||
descriptor.setReturnType(DeferredType.create(resolveSession.getTrace(), new LazyValue<JetType>() {
|
setDeferredReturnType(constructor);
|
||||||
@Override
|
}
|
||||||
protected JetType compute() {
|
else {
|
||||||
return thisDescriptor.getDefaultType();
|
ConstructorDescriptorImpl constructor =
|
||||||
}
|
DescriptorResolver.createPrimaryConstructorForObject(classOrObject, thisDescriptor, resolveSession.getTrace());
|
||||||
}));
|
setDeferredReturnType(constructor);
|
||||||
|
primaryConstructor = constructor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
primaryConstructorResolved = true;
|
primaryConstructorResolved = true;
|
||||||
}
|
}
|
||||||
return primaryConstructor;
|
return primaryConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setDeferredReturnType(@NotNull ConstructorDescriptorImpl descriptor) {
|
||||||
|
descriptor.setReturnType(DeferredType.create(resolveSession.getTrace(), new LazyValue<JetType>() {
|
||||||
|
@Override
|
||||||
|
protected JetType compute() {
|
||||||
|
return thisDescriptor.getDefaultType();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -181,13 +182,21 @@ public class ResolveSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parent instanceof JetClassBody) {
|
if (parent instanceof JetClassBody) {
|
||||||
JetClassBody classBody = (JetClassBody) parent;
|
return getEnclosingLazyClass(element).getScopeForMemberDeclarationResolution();
|
||||||
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(classBody, JetClassOrObject.class);
|
}
|
||||||
ClassDescriptor classDescriptor = getClassDescriptor(classOrObject);
|
|
||||||
assert classDescriptor instanceof LazyClassDescriptor : "Trying to resolve a member of a non-lazily loaded class: " + element;
|
if (parent instanceof JetClassObject) {
|
||||||
return ((LazyClassDescriptor) classDescriptor).getScopeForMemberDeclarationResolution();
|
return new InnerClassesScopeWrapper(getEnclosingLazyClass(element).getScopeForMemberDeclarationResolution());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("Unsupported PSI element: " + element);
|
throw new IllegalArgumentException("Unsupported PSI element: " + element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LazyClassDescriptor getEnclosingLazyClass(PsiElement element) {
|
||||||
|
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(element.getParent(), JetClassOrObject.class);
|
||||||
|
assert classOrObject != null : "Called for an element that is not a class member: " + element;
|
||||||
|
ClassDescriptor classDescriptor = getClassDescriptor(classOrObject);
|
||||||
|
assert classDescriptor instanceof LazyClassDescriptor : "Trying to resolve a member of a non-lazily loaded class: " + element;
|
||||||
|
return (LazyClassDescriptor) classDescriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user