Callable descriptors store expected this object

This commit is contained in:
Andrey Breslav
2011-10-12 21:14:37 +04:00
parent 883020f068
commit cb6fbe990a
21 changed files with 132 additions and 46 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import java.util.*; import java.util.*;
@@ -327,6 +328,7 @@ public class JavaDescriptorResolver {
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), field), resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), field),
!isFinal, !isFinal,
null, null,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
field.getName(), field.getName(),
isFinal ? null : type, isFinal ? null : type,
type); type);
@@ -401,6 +403,7 @@ public class JavaDescriptorResolver {
methodDescriptorCache.put(method, functionDescriptorImpl); methodDescriptorCache.put(method, functionDescriptorImpl);
functionDescriptorImpl.initialize( functionDescriptorImpl.initialize(
null, null,
DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
resolveTypeParameters(functionDescriptorImpl, method.getTypeParameters()), resolveTypeParameters(functionDescriptorImpl, method.getTypeParameters()),
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters), semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
semanticServices.getTypeTransformer().transformToType(returnType), semanticServices.getTypeTransformer().transformToType(returnType),
@@ -15,6 +15,9 @@ public interface CallableDescriptor extends DeclarationDescriptor {
@NotNull @NotNull
ReceiverDescriptor getReceiverParameter(); ReceiverDescriptor getReceiverParameter();
@NotNull
ReceiverDescriptor getExpectedThisObject();
@NotNull @NotNull
List<TypeParameterDescriptor> getTypeParameters(); List<TypeParameterDescriptor> getTypeParameters();
@@ -3,6 +3,8 @@ package org.jetbrains.jet.lang.descriptors;
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.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import java.util.Collections; import java.util.Collections;
@@ -28,16 +30,27 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
@Override @Override
@Deprecated @Deprecated
public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, Modality modality, @NotNull Visibility visibility) { public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull ReceiverDescriptor expectedThisObject, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, Modality modality, @NotNull Visibility visibility) {
assert receiverType == null; assert receiverType == null;
return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modality, visibility); return super.initialize(null, expectedThisObject, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modality, visibility);
} }
public ConstructorDescriptorImpl initialize(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, Modality modality, Visibility visibility) { public ConstructorDescriptorImpl initialize(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, Modality modality, Visibility visibility) {
super.initialize(null, typeParameters, unsubstitutedValueParameters, null, modality, visibility); super.initialize(null, getExpectedThisObject(getContainingDeclaration()), typeParameters, unsubstitutedValueParameters, null, modality, visibility);
return this; return this;
} }
@NotNull
private static ReceiverDescriptor getExpectedThisObject(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor) {
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) descriptor;
ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration();
return getExpectedThisObject(classDescriptor);
}
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
return DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration);
}
@NotNull @NotNull
@Override @Override
public ClassDescriptor getContainingDeclaration() { public ClassDescriptor getContainingDeclaration() {
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; 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.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.jet.lang.types.DescriptorSubstitutor; import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeSubstitutor;
@@ -27,6 +28,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
private List<ValueParameterDescriptor> unsubstitutedValueParameters; private List<ValueParameterDescriptor> unsubstitutedValueParameters;
private JetType unsubstitutedReturnType; private JetType unsubstitutedReturnType;
private ReceiverDescriptor receiver; private ReceiverDescriptor receiver;
private ReceiverDescriptor expectedThisObject;
private Modality modality; private Modality modality;
private Visibility visibility; private Visibility visibility;
@@ -51,6 +53,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
public FunctionDescriptorImpl initialize( public FunctionDescriptorImpl initialize(
@Nullable JetType receiverType, @Nullable JetType receiverType,
@NotNull ReceiverDescriptor expectedThisObject,
@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
@Nullable JetType unsubstitutedReturnType, @Nullable JetType unsubstitutedReturnType,
@@ -62,6 +65,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
this.modality = modality; this.modality = modality;
this.visibility = visibility; this.visibility = visibility;
this.receiver = receiverType == null ? NO_RECEIVER : new ExtensionReceiver(this, receiverType); this.receiver = receiverType == null ? NO_RECEIVER : new ExtensionReceiver(this, receiverType);
this.expectedThisObject = expectedThisObject;
return this; return this;
} }
@@ -75,6 +79,12 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
return receiver; return receiver;
} }
@NotNull
@Override
public ReceiverDescriptor getExpectedThisObject() {
return expectedThisObject;
}
@NotNull @NotNull
@Override @Override
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() { public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
@@ -139,6 +149,15 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
} }
} }
ReceiverDescriptor substitutedExpectedThis = NO_RECEIVER;
if (expectedThisObject.exists()) {
JetType substitutedType = substitutor.substitute(expectedThisObject.getType(), Variance.IN_VARIANCE);
if (substitutedType == null) {
return null;
}
substitutedExpectedThis = new TransientReceiver(substitutedType);
}
List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(substitutedDescriptor, this, substitutor); List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
if (substitutedValueParameters == null) { if (substitutedValueParameters == null) {
return null; return null;
@@ -151,6 +170,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
substitutedDescriptor.initialize( substitutedDescriptor.initialize(
substitutedReceiverType, substitutedReceiverType,
substitutedExpectedThis,
substitutedTypeParameters, substitutedTypeParameters,
substitutedValueParameters, substitutedValueParameters,
substitutedReturnType, substitutedReturnType,
@@ -182,6 +202,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
FunctionDescriptorImpl copy = new FunctionDescriptorImpl(newOwner, Lists.newArrayList(getAnnotations()), getName()); FunctionDescriptorImpl copy = new FunctionDescriptorImpl(newOwner, Lists.newArrayList(getAnnotations()), getName());
copy.initialize( copy.initialize(
getReceiverParameter().exists() ? getReceiverParameter().getType() : null, getReceiverParameter().exists() ? getReceiverParameter().getType() : null,
expectedThisObject,
DescriptorUtils.copyTypeParameters(copy, typeParameters), DescriptorUtils.copyTypeParameters(copy, typeParameters),
DescriptorUtils.copyValueParameters(copy, unsubstitutedValueParameters), DescriptorUtils.copyValueParameters(copy, unsubstitutedValueParameters),
unsubstitutedReturnType, unsubstitutedReturnType,
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.Collections; import java.util.Collections;
@@ -77,6 +78,18 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
return correspondingProperty; return correspondingProperty;
} }
@NotNull
@Override
public ReceiverDescriptor getReceiverParameter() {
return getCorrespondingProperty().getReceiverParameter();
}
@NotNull
@Override
public ReceiverDescriptor getExpectedThisObject() {
return getCorrespondingProperty().getExpectedThisObject();
}
@NotNull @NotNull
@Override @Override
public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) { public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; 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.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.lang.types.Variance;
@@ -24,6 +25,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
private final Visibility visibility; private final Visibility visibility;
private final boolean isVar; private final boolean isVar;
private final ReceiverDescriptor receiver; private final ReceiverDescriptor receiver;
private final ReceiverDescriptor expectedThisObject;
private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet(); private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet();
private final List<TypeParameterDescriptor> typeParemeters = Lists.newArrayListWithCapacity(0); private final List<TypeParameterDescriptor> typeParemeters = Lists.newArrayListWithCapacity(0);
private final PropertyDescriptor original; private final PropertyDescriptor original;
@@ -38,6 +40,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
@NotNull Visibility visibility, @NotNull Visibility visibility,
boolean isVar, boolean isVar,
@Nullable JetType receiverType, @Nullable JetType receiverType,
@NotNull ReceiverDescriptor expectedThisObject,
@NotNull String name, @NotNull String name,
@Nullable JetType inType, @Nullable JetType inType,
@NotNull JetType outType) { @NotNull JetType outType) {
@@ -48,6 +51,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
this.modality = modality; this.modality = modality;
this.visibility = visibility; this.visibility = visibility;
this.receiver = receiverType == null ? ReceiverDescriptor.NO_RECEIVER : new ExtensionReceiver(this, receiverType); this.receiver = receiverType == null ? ReceiverDescriptor.NO_RECEIVER : new ExtensionReceiver(this, receiverType);
this.expectedThisObject = expectedThisObject;
this.original = original == null ? this : original.getOriginal(); this.original = original == null ? this : original.getOriginal();
} }
@@ -58,15 +62,17 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
@NotNull Visibility visibility, @NotNull Visibility visibility,
boolean isVar, boolean isVar,
@Nullable JetType receiverType, @Nullable JetType receiverType,
@NotNull ReceiverDescriptor expectedThisObject,
@NotNull String name, @NotNull String name,
@Nullable JetType inType, @Nullable JetType inType,
@NotNull JetType outType) { @NotNull JetType outType) {
this(null, containingDeclaration, annotations, modality, visibility, isVar, receiverType, name, inType, outType); this(null, containingDeclaration, annotations, modality, visibility, isVar, receiverType, expectedThisObject, name, inType, outType);
} }
private PropertyDescriptor( private PropertyDescriptor(
@NotNull PropertyDescriptor original, @NotNull PropertyDescriptor original,
@Nullable JetType receiverType, @Nullable JetType receiverType,
@NotNull ReceiverDescriptor expectedThisObject,
@Nullable JetType inType, @Nullable JetType inType,
@NotNull JetType outType) { @NotNull JetType outType) {
this( this(
@@ -77,6 +83,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
original.getVisibility(), original.getVisibility(),
original.isVar, original.isVar,
receiverType, receiverType,
expectedThisObject,
original.getName(), original.getName(),
inType, inType,
outType); outType);
@@ -99,6 +106,12 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
return receiver; return receiver;
} }
@NotNull
@Override
public ReceiverDescriptor getExpectedThisObject() {
return expectedThisObject;
}
@NotNull @NotNull
@Override @Override
public JetType getReturnType() { public JetType getReturnType() {
@@ -132,7 +145,6 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
return setter; return setter;
} }
@NotNull
@Override @Override
public PropertyDescriptor substitute(TypeSubstitutor substitutor) { public PropertyDescriptor substitute(TypeSubstitutor substitutor) {
JetType originalInType = getInType(); JetType originalInType = getInType();
@@ -142,9 +154,18 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
if (inType == null && outType == null) { if (inType == null && outType == null) {
return null; // TODO : tell the user that the property was projected out return null; // TODO : tell the user that the property was projected out
} }
JetType substitutedReceiverType;
if (receiver.exists()) {
substitutedReceiverType = substitutor.substitute(receiver.getType(), Variance.IN_VARIANCE);
if (substitutedReceiverType == null) return null;
}
else {
substitutedReceiverType = null;
}
return new PropertyDescriptor( return new PropertyDescriptor(
this, this,
receiver.exists() ? substitutor.substitute(receiver.getType(), Variance.IN_VARIANCE) : null, substitutedReceiverType,
expectedThisObject.exists() ? new TransientReceiver(substitutor.substitute(expectedThisObject.getType(), Variance.IN_VARIANCE)) : expectedThisObject,
inType, inType,
outType outType
); );
@@ -171,6 +192,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
return overriddenProperties; return overriddenProperties;
} }
@NotNull @NotNull
@Override @Override
public PropertyDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) { public PropertyDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
@@ -178,7 +200,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
newOwner, newOwner,
Lists.newArrayList(getAnnotations()), Lists.newArrayList(getAnnotations()),
DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar, DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar,
receiver.exists() ? receiver.getType() : null, getName(), getInType(), getOutType()); receiver.exists() ? receiver.getType() : null,
expectedThisObject,
getName(), getInType(), getOutType());
PropertyGetterDescriptor newGetter = getter == null ? null : new PropertyGetterDescriptor( PropertyGetterDescriptor newGetter = getter == null ? null : new PropertyGetterDescriptor(
propertyDescriptor, Lists.newArrayList(getter.getAnnotations()), propertyDescriptor, Lists.newArrayList(getter.getAnnotations()),
DescriptorUtils.convertModality(getter.getModality(), makeNonAbstract), getter.getVisibility(), DescriptorUtils.convertModality(getter.getModality(), makeNonAbstract), getter.getVisibility(),
@@ -33,12 +33,6 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
overriddenGetters.add(overriddenGetter); overriddenGetters.add(overriddenGetter);
} }
@NotNull
@Override
public ReceiverDescriptor getReceiverParameter() {
return getCorrespondingProperty().getReceiverParameter();
}
@NotNull @NotNull
@Override @Override
public List<ValueParameterDescriptor> getValueParameters() { public List<ValueParameterDescriptor> getValueParameters() {
@@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -42,12 +41,6 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
overriddenSetters.add(overriddenSetter); overriddenSetters.add(overriddenSetter);
} }
@NotNull
@Override
public ReceiverDescriptor getReceiverParameter() {
return getCorrespondingProperty().getReceiverParameter();
}
@NotNull @NotNull
@Override @Override
public List<ValueParameterDescriptor> getValueParameters() { public List<ValueParameterDescriptor> getValueParameters() {
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -16,7 +17,7 @@ public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl {
assert outType != null; assert outType != null;
assert JetStandardClasses.isFunctionType(outType); assert JetStandardClasses.isFunctionType(outType);
VariableAsFunctionDescriptor result = new VariableAsFunctionDescriptor(variableDescriptor); VariableAsFunctionDescriptor result = new VariableAsFunctionDescriptor(variableDescriptor);
result.initialize(JetStandardClasses.getReceiverType(outType), Collections.<TypeParameterDescriptor>emptyList(), JetStandardClasses.getValueParameters(result, outType), JetStandardClasses.getReturnType(outType), Modality.FINAL, Visibility.LOCAL); result.initialize(JetStandardClasses.getReceiverType(outType), ReceiverDescriptor.NO_RECEIVER, Collections.<TypeParameterDescriptor>emptyList(), JetStandardClasses.getValueParameters(result, outType), JetStandardClasses.getReturnType(outType), Modality.FINAL, Visibility.LOCAL);
return result; return result;
} }
@@ -26,7 +26,6 @@ public interface VariableDescriptor extends CallableDescriptor {
@NotNull @NotNull
DeclarationDescriptor getContainingDeclaration(); DeclarationDescriptor getContainingDeclaration();
@NotNull
@Override @Override
VariableDescriptor substitute(TypeSubstitutor substitutor); VariableDescriptor substitute(TypeSubstitutor substitutor);
@@ -78,6 +78,12 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
return ReceiverDescriptor.NO_RECEIVER; return ReceiverDescriptor.NO_RECEIVER;
} }
@NotNull
@Override
public ReceiverDescriptor getExpectedThisObject() {
return ReceiverDescriptor.NO_RECEIVER;
}
@NotNull @NotNull
@Override @Override
public JetType getReturnType() { public JetType getReturnType() {
@@ -195,6 +195,7 @@ public class ClassDescriptorResolver {
Visibility visibility = resolveVisibilityFromModifiers(function.getModifierList()); Visibility visibility = resolveVisibilityFromModifiers(function.getModifierList());
functionDescriptor.initialize( functionDescriptor.initialize(
receiverType, receiverType,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDescriptor),
typeParameterDescriptors, typeParameterDescriptors,
valueParameterDescriptors, valueParameterDescriptors,
returnType, returnType,
@@ -438,6 +439,7 @@ public class ClassDescriptorResolver {
resolveVisibilityFromModifiers(objectDeclaration.getModifierList()), resolveVisibilityFromModifiers(objectDeclaration.getModifierList()),
false, false,
null, null,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
JetPsiUtil.safeName(objectDeclaration.getName()), JetPsiUtil.safeName(objectDeclaration.getName()),
null, null,
classDescriptor.getDefaultType()); classDescriptor.getDefaultType());
@@ -490,6 +492,7 @@ public class ClassDescriptorResolver {
resolveVisibilityFromModifiers(property.getModifierList()), resolveVisibilityFromModifiers(property.getModifierList()),
isVar, isVar,
receiverType, receiverType,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
JetPsiUtil.safeName(property.getName()), JetPsiUtil.safeName(property.getName()),
isVar ? type : null, isVar ? type : null,
type); type);
@@ -761,6 +764,7 @@ public class ClassDescriptorResolver {
resolveVisibilityFromModifiers(parameter.getModifierList()), resolveVisibilityFromModifiers(parameter.getModifierList()),
isMutable, isMutable,
null, null,
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
name == null ? "<no name>" : name, name == null ? "<no name>" : name,
isMutable ? type : null, isMutable ? type : null,
type); type);
@@ -116,13 +116,7 @@ public class DescriptorUtils {
} }
@NotNull @NotNull
public static ReceiverDescriptor getExpectedThisObject(@NotNull DeclarationDescriptor descriptor) { public static ReceiverDescriptor getExpectedThisObjectIfNeeded(@NotNull DeclarationDescriptor containingDeclaration) {
if (descriptor instanceof ConstructorDescriptor) {
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) descriptor;
ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration();
return getExpectedThisObject(classDescriptor);
}
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof ClassDescriptor) { if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
return classDescriptor.getImplicitReceiver(); return classDescriptor.getImplicitReceiver();
@@ -557,7 +557,7 @@ public class CallResolver {
boolean result = checkValueArgumentTypes(scope, candidateCall); boolean result = checkValueArgumentTypes(scope, candidateCall);
result &= checkReceiver(tracing, candidateCall, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument(), task); result &= checkReceiver(tracing, candidateCall, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument(), task);
result &= checkReceiver(tracing, candidateCall, DescriptorUtils.getExpectedThisObject(candidateCall.getResultingDescriptor()), candidateCall.getThisObject(), task); result &= checkReceiver(tracing, candidateCall, candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(), task);
return result; return result;
} }
@@ -4,8 +4,9 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.intellij.util.Function; import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -132,9 +133,4 @@ public class ResolvedCall<D extends CallableDescriptor> {
public boolean isDirty() { public boolean isDirty() {
return someArgumentHasNoType; return someArgumentHasNoType;
} }
@NotNull
public ReceiverDescriptor getExpectedThisObject() {
return DescriptorUtils.getExpectedThisObject(getResultingDescriptor());
}
} }
@@ -2,10 +2,12 @@ package org.jetbrains.jet.lang.resolve.calls;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.psi.Call;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.DataFlowInfo; import org.jetbrains.jet.lang.types.DataFlowInfo;
@@ -89,7 +91,6 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
DataFlowInfo dataFlowInfo = autoCastService.getDataFlowInfo(); DataFlowInfo dataFlowInfo = autoCastService.getDataFlowInfo();
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList(); List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
scope.getImplicitReceiversHierarchy(implicitReceivers); scope.getImplicitReceiversHierarchy(implicitReceivers);
// AutoCastUtils.getAutoCastVariants(bindingContext, dataFlowInfo, receiverToCast)
if (receiver.exists()) { if (receiver.exists()) {
List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver); List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
@@ -170,7 +171,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
} }
private static <D extends CallableDescriptor> boolean setImpliedThis(@NotNull JetScope scope, ResolvedCall<D> resolvedCall) { private static <D extends CallableDescriptor> boolean setImpliedThis(@NotNull JetScope scope, ResolvedCall<D> resolvedCall) {
ReceiverDescriptor expectedThisObject = DescriptorUtils.getExpectedThisObject(resolvedCall.getCandidateDescriptor()); ReceiverDescriptor expectedThisObject = resolvedCall.getCandidateDescriptor().getExpectedThisObject();
if (!expectedThisObject.exists()) return true; if (!expectedThisObject.exists()) return true;
List<ReceiverDescriptor> receivers = Lists.newArrayList(); List<ReceiverDescriptor> receivers = Lists.newArrayList();
scope.getImplicitReceiversHierarchy(receivers); scope.getImplicitReceiversHierarchy(receivers);
@@ -177,7 +177,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
error = true; error = true;
} }
assert candidateCall.getThisObject().exists() == candidateCall.getExpectedThisObject().exists() : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor(); assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
return error; return error;
} }
@@ -2,14 +2,28 @@ package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.types.JetType;
/** /**
* @author abreslav * @author abreslav
*/ */
public class ClassReceiver extends ImplicitReceiverDescriptor { public class ClassReceiver implements ReceiverDescriptor {
public ClassReceiver(ClassDescriptor classDescriptor) { private final ClassDescriptor classDescriptor;
super(classDescriptor, classDescriptor.getDefaultType());
public ClassReceiver(@NotNull ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
}
@Override
public boolean exists() {
return true;
}
@NotNull
@Override
public JetType getType() {
return classDescriptor.getDefaultType();
} }
@Override @Override
@@ -186,6 +186,10 @@ public class DataFlowInfo {
return new DataFlowInfo(ImmutableMap.copyOf(builder), newTypeInfo); return new DataFlowInfo(ImmutableMap.copyOf(builder), newTypeInfo);
} }
public DataFlowInfo nullabilityOnly() {
return new DataFlowInfo(nullabilityInfo, EMPTY.copyTypeInfo());
}
private static class NullabilityFlags { private static class NullabilityFlags {
private final boolean canBeNull; private final boolean canBeNull;
private final boolean canBeNonNull; private final boolean canBeNonNull;
@@ -105,6 +105,7 @@ public class ErrorUtils {
Visibility.INTERNAL, Visibility.INTERNAL,
true, true,
null, null,
ReceiverDescriptor.NO_RECEIVER,
"<ERROR PROPERTY>", "<ERROR PROPERTY>",
ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE); ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE);
@@ -112,6 +113,7 @@ public class ErrorUtils {
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>"); FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>");
return functionDescriptor.initialize( return functionDescriptor.initialize(
null, null,
ReceiverDescriptor.NO_RECEIVER,
typeParameters, typeParameters,
getValueParameters(functionDescriptor, positionedValueArgumentTypes), getValueParameters(functionDescriptor, positionedValueArgumentTypes),
createErrorType("<ERROR FUNCTION RETURN>"), createErrorType("<ERROR FUNCTION RETURN>"),
@@ -123,6 +125,7 @@ public class ErrorUtils {
public static FunctionDescriptor createErrorFunction(int typeParameterCount, List<JetType> positionedValueParameterTypes) { public static FunctionDescriptor createErrorFunction(int typeParameterCount, List<JetType> positionedValueParameterTypes) {
return new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>").initialize( return new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>").initialize(
null, null,
ReceiverDescriptor.NO_RECEIVER,
Collections.<TypeParameterDescriptor>emptyList(), // TODO Collections.<TypeParameterDescriptor>emptyList(), // TODO
Collections.<ValueParameterDescriptor>emptyList(), // TODO Collections.<ValueParameterDescriptor>emptyList(), // TODO
createErrorType("<ERROR FUNCTION RETURN TYPE>"), createErrorType("<ERROR FUNCTION RETURN TYPE>"),
@@ -1014,7 +1014,7 @@ public class JetTypeInferrer {
else { else {
effectiveReceiverType = receiverType; effectiveReceiverType = receiverType;
} }
functionDescriptor.initialize(effectiveReceiverType, Collections.<TypeParameterDescriptor>emptyList(), valueParameterDescriptors, null, Modality.FINAL, Visibility.LOCAL); functionDescriptor.initialize(effectiveReceiverType, NO_RECEIVER, Collections.<TypeParameterDescriptor>emptyList(), valueParameterDescriptors, null, Modality.FINAL, Visibility.LOCAL);
context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor); context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor);
JetType returnType = NO_EXPECTED_TYPE; JetType returnType = NO_EXPECTED_TYPE;