Receivers introduced to descriptors

This commit is contained in:
Andrey Breslav
2011-09-20 06:35:09 -05:00
parent aa2d3a7c3d
commit 6ede1a342f
41 changed files with 431 additions and 324 deletions
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
@@ -72,7 +73,7 @@ public class ClassContext {
thisIdx++;
}
final boolean hasReceiver = descriptor.getReceiverType() != null;
final boolean hasReceiver = descriptor.getReceiver().exists();
if (hasReceiver) {
thisIdx++;
}
@@ -102,12 +103,12 @@ public class ClassContext {
return frameMap;
}
private JetType receiverType() {
return contextType instanceof FunctionDescriptor ? ((FunctionDescriptor) contextType).getReceiverType() : null;
private ReceiverDescriptor receiver() {
return contextType instanceof FunctionDescriptor ? ((FunctionDescriptor) contextType).getReceiver() : ReceiverDescriptor.NO_RECEIVER;
}
private boolean hasReceiver() {
return receiverType() != null;
return receiver().exists();
}
public ClassContext getParentContext() {
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
@@ -41,7 +42,7 @@ public class ClosureCodegen {
}
public static Method erasedInvokeSignature(FunctionDescriptor fd) {
boolean isExtensionFunction = fd.getReceiverType() != null;
boolean isExtensionFunction = fd.getReceiver().exists();
int paramCount = fd.getValueParameters().size();
if (isExtensionFunction) {
paramCount++;
@@ -150,11 +151,11 @@ public class ClosureCodegen {
iv.load(0, Type.getObjectType(className));
final JetType receiverType = funDescriptor.getReceiverType();
final ReceiverDescriptor receiver = funDescriptor.getReceiver();
int count = 1;
if (receiverType != null) {
if (receiver.exists()) {
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(receiverType), iv);
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(receiver.getType()), iv);
count++;
}
@@ -228,7 +229,7 @@ public class ClosureCodegen {
public static String getInternalClassName(FunctionDescriptor descriptor) {
final int paramCount = descriptor.getValueParameters().size();
if (descriptor.getReceiverType() != null) {
if (descriptor.getReceiver().exists()) {
return "jet/ExtensionFunction" + paramCount;
}
else {
@@ -249,7 +250,7 @@ public class ClosureCodegen {
Method descriptor = erasedInvokeSignature(fd);
String owner = getInternalClassName(fd);
final CallableMethod result = new CallableMethod(owner, descriptor, Opcodes.INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
if (fd.getReceiverType() != null) {
if (fd.getReceiver().exists()) {
result.setNeedsReceiver(null);
}
result.requestGenerateCallee(Type.getObjectType(getInternalClassName(fd)));
@@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorRenderer;
@@ -514,11 +515,11 @@ public class JetTypeMapper {
}
public Method mapSignature(String name, FunctionDescriptor f) {
final JetType receiverType = f.getReceiverType();
final ReceiverDescriptor receiver = f.getReceiver();
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
List<Type> parameterTypes = new ArrayList<Type>();
if (receiverType != null) {
parameterTypes.add(mapType(receiverType));
if (receiver.exists()) {
parameterTypes.add(mapType(receiver.getType()));
}
for (ValueParameterDescriptor parameter : parameters) {
parameterTypes.add(mapType(parameter.getOutType()));
@@ -5,6 +5,8 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import java.util.Collections;
@@ -23,6 +25,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
private Modality modality;
private JetType superclassType;
private final ClassKind kind;
private ClassReceiver implicitReceiver;
public JavaClassDescriptor(DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind) {
@@ -155,4 +158,13 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
public String toString() {
return "java class " + typeConstructor;
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
if (implicitReceiver == null) {
implicitReceiver = new ClassReceiver(this);
}
return implicitReceiver;
}
}
@@ -1,7 +1,8 @@
package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
@@ -12,8 +13,8 @@ import java.util.Set;
* @author abreslav
*/
public interface CallableDescriptor extends DeclarationDescriptor {
@Nullable
JetType getReceiverType();
@NotNull
ReceiverDescriptor getReceiver();
@NotNull
List<TypeParameterDescriptor> getTypeParameters();
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
@@ -53,4 +54,7 @@ public interface ClassDescriptor extends ClassifierDescriptor {
@NotNull
Modality getModality();
@NotNull
ReceiverDescriptor getImplicitReceiver();
}
@@ -5,6 +5,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import java.util.Collection;
@@ -21,6 +23,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
private FunctionGroup constructors;
private ConstructorDescriptor primaryConstructor;
private JetType superclassType;
private ReceiverDescriptor implicitReceiver;
public ClassDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@@ -151,4 +154,13 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
public Modality getModality() {
return Modality.FINAL;
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
if (implicitReceiver == null) {
implicitReceiver = new ClassReceiver(this);
}
return implicitReceiver;
}
}
@@ -5,6 +5,8 @@ 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.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
@@ -13,6 +15,8 @@ import org.jetbrains.jet.lang.types.Variance;
import java.util.List;
import java.util.Set;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
/**
* @author abreslav
*/
@@ -21,7 +25,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
private List<TypeParameterDescriptor> typeParameters;
private List<ValueParameterDescriptor> unsubstitutedValueParameters;
private JetType unsubstitutedReturnType;
private JetType receiverType;
private ReceiverDescriptor receiver;
private Modality modality;
private final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet();
@@ -49,11 +53,11 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
@Nullable JetType unsubstitutedReturnType,
@Nullable Modality modality) {
this.receiverType = receiverType;
this.typeParameters = typeParameters;
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
this.unsubstitutedReturnType = unsubstitutedReturnType;
this.modality = modality;
this.receiver = receiverType == null ? NO_RECEIVER : new ExtensionReceiver(this, receiverType);
return this;
}
@@ -61,9 +65,10 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
this.unsubstitutedReturnType = unsubstitutedReturnType;
}
@NotNull
@Override
public JetType getReceiverType() {
return receiverType;
public ReceiverDescriptor getReceiver() {
return receiver;
}
@NotNull
@@ -116,10 +121,9 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
JetType receiverType = getReceiverType();
JetType substitutedReceiverType = null;
if (receiverType != null) {
substitutedReceiverType = substitutor.substitute(receiverType, Variance.IN_VARIANCE);
if (receiver != NO_RECEIVER) {
substitutedReceiverType = substitutor.substitute(getReceiver().getType(), Variance.IN_VARIANCE);
if (substitutedReceiverType == null) {
return null;
}
@@ -5,11 +5,12 @@ import com.google.common.collect.HashBiMap;
import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionCallableReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import java.util.*;
@@ -97,9 +98,9 @@ public class FunctionDescriptorUtil {
@NotNull
public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) {
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function inner scope");
JetType receiverType = descriptor.getReceiverType();
if (receiverType != null) {
parameterScope.setImplicitReceiver(new ExtensionCallableReceiver(descriptor));
ReceiverDescriptor receiver = descriptor.getReceiver();
if (receiver.exists()) {
parameterScope.setImplicitReceiver(receiver);
}
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
parameterScope.addTypeParameterDescriptor(typeParameter);
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import java.util.Collection;
@@ -94,6 +95,12 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public FunctionGroup getConstructors() {
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.resolve.DescriptorRenderer;
@@ -38,6 +39,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
private JetType defaultType;
private final ClassKind kind;
private JetType superclassType;
private ClassReceiver implicitReceiver;
// public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
// this(trace, containingDeclaration, outerScope, ClassKind.CLASS);
@@ -293,4 +295,13 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public Collection<JetType> getSupertypes() {
return supertypes;
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
if (implicitReceiver == null) {
implicitReceiver = new ClassReceiver(this);
}
return implicitReceiver;
}
}
@@ -15,6 +15,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
private final boolean hasBody;
private final boolean isDefault;
private final Modality modality;
private final PropertyDescriptor correspondingProperty;
protected PropertyAccessorDescriptor(
@NotNull Modality modality,
@@ -24,6 +25,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
boolean hasBody,
boolean isDefault) {
super(correspondingProperty.getContainingDeclaration(), annotations, name);
this.correspondingProperty = correspondingProperty;
this.modality = modality;
this.hasBody = hasBody;
this.isDefault = isDefault;
@@ -60,4 +62,9 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
public Modality getModality() {
return modality;
}
@NotNull
public PropertyDescriptor getCorrespondingProperty() {
return correspondingProperty;
}
}
@@ -4,6 +4,8 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
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;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.Variance;
@@ -17,7 +19,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
private final Modality modality;
private final boolean isVar;
private final JetType receiverType;
private final ReceiverDescriptor receiver;
private final List<TypeParameterDescriptor> typeParemeters = Lists.newArrayListWithCapacity(0);
private final PropertyDescriptor original;
private PropertyGetterDescriptor getter;
@@ -38,7 +40,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
// assert outType != null;
this.isVar = isVar;
this.modality = modality;
this.receiverType = receiverType;
this.receiver = receiverType == null ? ReceiverDescriptor.NO_RECEIVER : new ExtensionReceiver(this, receiverType);
this.original = original == null ? this : original.getOriginal();
}
@@ -83,9 +85,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
return typeParemeters;
}
@Nullable
public JetType getReceiverType() {
return receiverType;
@NotNull
public ReceiverDescriptor getReceiver() {
return receiver;
}
@NotNull
@@ -125,10 +127,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
if (inType == null && outType == null) {
return null; // TODO : tell the user that the property was projected out
}
JetType receiverType = getReceiverType();
return new PropertyDescriptor(
this,
receiverType == null ? null : substitutor.substitute(receiverType, Variance.IN_VARIANCE),
receiver.exists() ? substitutor.substitute(receiver.getType(), Variance.IN_VARIANCE) : null,
inType,
outType
);
@@ -4,6 +4,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.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collections;
@@ -32,9 +33,10 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
overriddenGetters.add(overriddenGetter);
}
@NotNull
@Override
public JetType getReceiverType() {
return null; // TODO
public ReceiverDescriptor getReceiver() {
return getCorrespondingProperty().getReceiver();
}
@NotNull
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
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.JetType;
@@ -41,9 +42,10 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
overriddenSetters.add(overriddenSetter);
}
@NotNull
@Override
public JetType getReceiverType() {
return null; // TODO
public ReceiverDescriptor getReceiver() {
return getCorrespondingProperty().getReceiver();
}
@NotNull
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collections;
@@ -71,9 +72,10 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
return Collections.emptyList();
}
@NotNull
@Override
public JetType getReceiverType() {
return null;
public ReceiverDescriptor getReceiver() {
return ReceiverDescriptor.NO_RECEIVER;
}
@NotNull
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetModifierList;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInferrer;
@@ -46,7 +47,7 @@ public class AnnotationResolver {
}
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) {
JetType jetType = typeInferrer.getCallResolver().resolveCall(trace, scope, null, entryElement, NO_EXPECTED_TYPE);
JetType jetType = typeInferrer.getCallResolver().resolveCall(trace, scope, ReceiverDescriptor.NO_RECEIVER, entryElement, NO_EXPECTED_TYPE);
descriptor.setAnnotationType(jetType == null ? ErrorUtils.createErrorType("Unresolved annotation type") : jetType);
}
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.util.slicedmap.*;
@@ -17,6 +18,8 @@ import java.util.Collection;
* @author abreslav
*/
public interface BindingContext {
WritableSlice<JetElement, ReceiverDescriptor> RECEIVER = Slices.createSimpleSlice("RECEIVER");
WritableSlice<JetAnnotationEntry, AnnotationDescriptor> ANNOTATION = Slices.createSimpleSlice("ANNOTATION");
WritableSlice<JetExpression, CompileTimeConstant<?>> COMPILE_TIME_VALUE = Slices.createSimpleSlice("COMPILE_TIME_VALUE");
WritableSlice<JetTypeReference, JetType> TYPE = Slices.createSimpleSlice("TYPE");
@@ -13,8 +13,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionCallableReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
@@ -276,7 +275,7 @@ public class BodyResolver {
JetTypeReference typeReference = call.getTypeReference();
if (typeReference != null) {
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
JetType supertype = typeInferrer.getCallResolver().resolveCall(context.getTrace(), scopeForConstructor, null, call, NO_EXPECTED_TYPE);
JetType supertype = typeInferrer.getCallResolver().resolveCall(context.getTrace(), scopeForConstructor, ReceiverDescriptor.NO_RECEIVER, call, NO_EXPECTED_TYPE);
if (supertype != null) {
recordSupertype(typeReference, supertype);
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
@@ -461,7 +460,7 @@ public class BodyResolver {
typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(),
functionInnerScope,
null, call, NO_EXPECTED_TYPE);
ReceiverDescriptor.NO_RECEIVER, call, NO_EXPECTED_TYPE);
// call.getThisReference(),
// classDescriptor,
// classDescriptor.getDefaultType(),
@@ -576,9 +575,9 @@ public class BodyResolver {
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
result.addTypeParameterDescriptor(typeParameterDescriptor);
}
JetType receiverType = propertyDescriptor.getReceiverType();
if (receiverType != null) {
result.setImplicitReceiver(new ExtensionCallableReceiver(propertyDescriptor));
ReceiverDescriptor receiver = propertyDescriptor.getReceiver();
if (receiver.exists()) {
result.setImplicitReceiver(receiver);
}
return result;
}
@@ -21,7 +21,7 @@ public class DescriptorUtils {
@Override
public Boolean visitFunctionDescriptor(FunctionDescriptor descriptor, Void data) {
return descriptor.getReceiverType() != null;
return descriptor.getReceiver().exists();
}
@Override
@@ -31,7 +31,7 @@ public class DescriptorUtils {
@Override
public Boolean visitPropertyDescriptor(PropertyDescriptor descriptor, Void data) {
return descriptor.getReceiverType() != null;
return descriptor.getReceiver().exists();
}
}, null);
}
@@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.inference.ConstraintSystem;
@@ -20,7 +21,9 @@ import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
import static org.jetbrains.jet.lang.resolve.BindingContext.RECEIVER;
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
/**
@@ -42,11 +45,11 @@ public class CallResolver {
public VariableDescriptor resolveSimpleProperty(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor receiver,
@NotNull final JetSimpleNameExpression nameExpression,
@NotNull JetType expectedType) {
Call call = CallMaker.makePropertyCall(nameExpression);
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, nameExpression.getReferencedName());
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, nameExpression.getReferencedName());
return resolveCallToDescriptor(trace, scope, call, nameExpression.getNode(), expectedType, prioritizedTasks, nameExpression);
}
@@ -55,11 +58,11 @@ public class CallResolver {
public JetType resolveCall(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor receiver,
@NotNull JetCallElement call,
@NotNull JetType expectedType
) {
FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, receiverType, call, expectedType);
FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, receiver, call, expectedType);
return functionDescriptor == null ? null : functionDescriptor.getReturnType();
}
@@ -70,11 +73,11 @@ public class CallResolver {
@NotNull final Call call,
@NotNull final JetReferenceExpression functionReference,
@NotNull String name,
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor receiver,
@NotNull JetType expectedType) {
// TODO : autocasts
// TODO : nullability
List<ResolutionTask<FunctionDescriptor>> tasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, name);
List<ResolutionTask<FunctionDescriptor>> tasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, name);
return resolveCallToDescriptor(trace, scope, call, functionReference.getNode(), expectedType, tasks, functionReference);
}
@@ -82,7 +85,7 @@ public class CallResolver {
public FunctionDescriptor resolveSimpleCallToFunctionDescriptor(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor receiver,
@NotNull final JetCallElement call,
@NotNull JetType expectedType
) {
@@ -97,7 +100,7 @@ public class CallResolver {
String name = expression.getReferencedName();
if (name == null) return checkArgumentTypesAndFail(trace, scope, call);
prioritizedTasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, name);
prioritizedTasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, name);
ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() {
@Override
public <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
@@ -120,7 +123,7 @@ public class CallResolver {
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
ASTNode reportAbsenceOn = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode();
if (calleeExpression instanceof JetConstructorCalleeExpression) {
assert receiverType == null;
assert receiver == NO_RECEIVER;
prioritizedTasks = Lists.newArrayList();
@@ -141,7 +144,7 @@ public class CallResolver {
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(trace, scope, call);
}
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(constructors, NO_RECEIVER, call));
}
else {
// trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
@@ -162,7 +165,7 @@ public class CallResolver {
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(trace, scope, call);
}
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(constructors, NO_RECEIVER, call));
}
else {
throw new UnsupportedOperationException("Type argument inference not implemented for " + call.getText());
@@ -190,45 +193,11 @@ public class CallResolver {
OverloadResolutionResult<D> resultForFirstNonemptyCandidateSet = null;
TracingStrategy tracing = new TracingStrategy() {
@Override
public void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor) {
public void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor) {
trace.record(REFERENCE_TARGET, reference, descriptor);
trace.record(RECEIVER, reference, receiver);
}
// public void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message) {
// trace.getErrorHandler().genericError(callNode, message);
// }
//
// public void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message) {
// JetTypeArgumentList typeArgumentList = call.getTypeArgumentList();
// if (typeArgumentList != null) {
// trace.getErrorHandler().genericError(typeArgumentList.getNode(), message);
// }
// else {
// reportOverallResolutionError(trace, message);
// }
// }
//
// public void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message) {
// ASTNode node;
//
// JetValueArgumentList valueArgumentList = call.getValueArgumentList();
// if (valueArgumentList != null) {
// node = valueArgumentList.getNode();
// }
// else if (!call.getFunctionLiteralArguments().isEmpty()) {
// node = call.getFunctionLiteralArguments().get(0).getNode();
// }
// else {
// node = callNode;
// }
//
// trace.getErrorHandler().genericError(node, message);
// }
//
// public void reportErrorOnReference(BindingTrace trace, String message) {
// trace.getErrorHandler().genericError(reference.getNode(), message);
// }
@Override
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates) {
trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, candidates);
@@ -257,8 +226,8 @@ public class CallResolver {
}
@Override
public void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType) {
trace.report(MISSING_RECEIVER.on(reference, candidateReceiverType));
public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver) {
trace.report(MISSING_RECEIVER.on(reference, expectedReceiver.getType()));
}
@Override
@@ -340,7 +309,7 @@ public class CallResolver {
traces.put(candidate, temporaryTrace);
JetTypeInferrer.Services temporaryServices = typeInferrer.getServices(temporaryTrace);
tracing.bindReference(temporaryTrace, candidate);
tracing.bindReference(temporaryTrace, task.getReceiver(), candidate);
if (ErrorUtils.isError(candidate)) {
successfulCandidates.put(candidate, candidate);
@@ -394,10 +363,10 @@ public class CallResolver {
checkReceiverAbsence(task, tracing, candidate, temporaryTrace);
// Error is already reported if something is missing
JetType receiverType = task.getReceiverType();
JetType candidateReceiverType = candidate.getReceiverType();
if (receiverType != null && candidateReceiverType != null) {
constraintSystem.addSubtypingConstraint(receiverType, candidateReceiverType);
ReceiverDescriptor receiver = task.getReceiver();
ReceiverDescriptor candidateReceiver = candidate.getReceiver();
if (receiver != NO_RECEIVER && candidateReceiver != NO_RECEIVER) {
constraintSystem.addSubtypingConstraint(receiver.getType(), candidateReceiver.getType());
}
if (expectedType != NO_EXPECTED_TYPE) {
@@ -508,28 +477,28 @@ public class CallResolver {
private <D extends CallableDescriptor> boolean checkReceiver(ResolutionTask<D> task, TracingStrategy tracing, D candidate, TemporaryBindingTrace temporaryTrace) {
if (!checkReceiverAbsence(task, tracing, candidate, temporaryTrace)) return false;
JetType receiverType = task.getReceiverType();
JetType candidateReceiverType = candidate.getReceiverType();
if (receiverType != null
&& candidateReceiverType != null
&& !semanticServices.getTypeChecker().isSubtypeOf(receiverType, candidateReceiverType)) {
tracing.missingReceiver(temporaryTrace, candidateReceiverType);
ReceiverDescriptor receiver = task.getReceiver();
ReceiverDescriptor candidateReceiver = candidate.getReceiver();
if (receiver != NO_RECEIVER
&& candidateReceiver != NO_RECEIVER
&& !semanticServices.getTypeChecker().isSubtypeOf(receiver.getType(), candidateReceiver.getType())) {
tracing.missingReceiver(temporaryTrace, candidateReceiver);
return false;
}
return true;
}
private <D extends CallableDescriptor> boolean checkReceiverAbsence(ResolutionTask<D> task, TracingStrategy tracing, D candidate, TemporaryBindingTrace temporaryTrace) {
JetType receiverType = task.getReceiverType();
JetType candidateReceiverType = candidate.getReceiverType();
if (receiverType != null) {
if (candidateReceiverType == null) {
ReceiverDescriptor receiver = task.getReceiver();
ReceiverDescriptor candidateReceiver = candidate.getReceiver();
if (receiver != NO_RECEIVER) {
if (candidateReceiver == NO_RECEIVER) {
tracing.noReceiverAllowed(temporaryTrace);
return false;
}
}
else if (candidateReceiverType != null) {
tracing.missingReceiver(temporaryTrace, candidateReceiverType);
else if (candidateReceiver != NO_RECEIVER) {
tracing.missingReceiver(temporaryTrace, candidateReceiver);
return false;
}
return true;
@@ -658,8 +627,8 @@ public class CallResolver {
}
@NotNull
public OverloadResolutionResult<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @Nullable JetType receiverType, @NotNull String name, @NotNull List<JetType> parameterTypes) {
List<FunctionDescriptor> result = findCandidatesByExactSignature(scope, receiverType, name, parameterTypes);
public OverloadResolutionResult<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
List<FunctionDescriptor> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
BindingTraceContext trace = new BindingTraceContext();
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(trace);
@@ -672,25 +641,25 @@ public class CallResolver {
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.<FunctionDescriptor>emptySet(), Collections.<FunctionDescriptor>emptySet(), traces);
}
private List<FunctionDescriptor> findCandidatesByExactSignature(JetScope scope, JetType receiverType, String name, List<JetType> parameterTypes) {
private List<FunctionDescriptor> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List<JetType> parameterTypes) {
List<FunctionDescriptor> result = Lists.newArrayList();
if (receiverType != null) {
if (receiver != NO_RECEIVER) {
Set<FunctionDescriptor> extensionFunctionDescriptors = scope.getFunctionGroup(name).getFunctionDescriptors();
List<FunctionDescriptor> nonlocal = Lists.newArrayList();
List<FunctionDescriptor> local = Lists.newArrayList();
TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctionDescriptors, scope.getContainingDeclaration(), local, nonlocal);
if (findExtensionFunctions(local, receiverType, parameterTypes, result)) {
if (findExtensionFunctions(local, receiver, parameterTypes, result)) {
return result;
}
Set<FunctionDescriptor> functionDescriptors = receiverType.getMemberScope().getFunctionGroup(name).getFunctionDescriptors();
Set<FunctionDescriptor> functionDescriptors = receiver.getType().getMemberScope().getFunctionGroup(name).getFunctionDescriptors();
if (lookupExactSignature(functionDescriptors, parameterTypes, result)) {
return result;
}
findExtensionFunctions(nonlocal, receiverType, parameterTypes, result);
findExtensionFunctions(nonlocal, receiver, parameterTypes, result);
return result;
}
else {
@@ -702,7 +671,7 @@ public class CallResolver {
private boolean lookupExactSignature(Set<FunctionDescriptor> candidates, List<JetType> parameterTypes, List<FunctionDescriptor> result) {
boolean found = false;
for (FunctionDescriptor functionDescriptor : candidates) {
if (functionDescriptor.getReceiverType() != null) continue;
if (functionDescriptor.getReceiver() != NO_RECEIVER) continue;
if (!functionDescriptor.getTypeParameters().isEmpty()) continue;
if (!checkValueParameters(functionDescriptor, parameterTypes)) continue;
result.add(functionDescriptor);
@@ -711,13 +680,13 @@ public class CallResolver {
return found;
}
private boolean findExtensionFunctions(Collection<FunctionDescriptor> candidates, JetType receiverType, List<JetType> parameterTypes, List<FunctionDescriptor> result) {
private boolean findExtensionFunctions(Collection<FunctionDescriptor> candidates, ReceiverDescriptor receiver, List<JetType> parameterTypes, List<FunctionDescriptor> result) {
boolean found = false;
for (FunctionDescriptor functionDescriptor : candidates) {
JetType functionReceiverType = functionDescriptor.getReceiverType();
if (functionReceiverType == null) continue;
ReceiverDescriptor functionReceiver = functionDescriptor.getReceiver();
if (functionReceiver == NO_RECEIVER) continue;
if (!functionDescriptor.getTypeParameters().isEmpty()) continue;
if (!semanticServices.getTypeChecker().isSubtypeOf(receiverType, functionReceiverType)) continue;
if (!semanticServices.getTypeChecker().isSubtypeOf(receiver.getType(), functionReceiver.getType())) continue;
if (!checkValueParameters(functionDescriptor, parameterTypes))continue;
result.add(functionDescriptor);
found = true;
@@ -744,7 +713,7 @@ public class CallResolver {
Set<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
for (Iterator<FunctionDescriptor> iterator = functions.iterator(); iterator.hasNext(); ) {
FunctionDescriptor functionDescriptor = iterator.next();
if (functionDescriptor.getReceiverType() != null) {
if (functionDescriptor.getReceiver() != NO_RECEIVER) {
iterator.remove();
}
}
@@ -756,10 +725,11 @@ public class CallResolver {
@NotNull
@Override
protected Collection<FunctionDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
Set<FunctionDescriptor> members = Sets.newHashSet(receiverType.getMemberScope().getFunctionGroup(name).getFunctionDescriptors());
addConstructors(receiverType.getMemberScope(), name, members);
addVariableAsFunction(receiverType.getMemberScope(), name, members, false);
protected Collection<FunctionDescriptor> getMembersByName(@NotNull ReceiverDescriptor receiver, String name) {
JetScope receiverScope = receiver.getType().getMemberScope();
Set<FunctionDescriptor> members = Sets.newHashSet(receiverScope.getFunctionGroup(name).getFunctionDescriptors());
addConstructors(receiverScope, name, members);
addVariableAsFunction(receiverScope, name, members, false);
return members;
}
@@ -769,7 +739,7 @@ public class CallResolver {
Set<FunctionDescriptor> extensionFunctions = Sets.newHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
for (Iterator<FunctionDescriptor> iterator = extensionFunctions.iterator(); iterator.hasNext(); ) {
FunctionDescriptor descriptor = iterator.next();
if (descriptor.getReceiverType() == null) {
if (descriptor.getReceiver() == NO_RECEIVER) {
iterator.remove();
}
}
@@ -779,8 +749,8 @@ public class CallResolver {
@NotNull
@Override
protected ResolutionTask<FunctionDescriptor> createTask(JetType receiverType, Call call, Collection<FunctionDescriptor> candidates) {
return new ResolutionTask<FunctionDescriptor>(candidates, receiverType, call);
protected ResolutionTask<FunctionDescriptor> createTask(@NotNull ReceiverDescriptor receiver, Call call, Collection<FunctionDescriptor> candidates) {
return new ResolutionTask<FunctionDescriptor>(candidates, receiver, call);
}
private void addConstructors(JetScope scope, String name, Collection<FunctionDescriptor> functions) {
@@ -793,11 +763,11 @@ public class CallResolver {
private void addVariableAsFunction(JetScope scope, String name, Set<FunctionDescriptor> functions, boolean receiverNeeded) {
VariableDescriptor variable = scope.getVariable(name);
if (variable != null && variable.getReceiverType() == null) {
if (variable != null && variable.getReceiver() == NO_RECEIVER) {
JetType outType = variable.getOutType();
if (outType != null && JetStandardClasses.isFunctionType(outType)) {
VariableAsFunctionDescriptor functionDescriptor = VariableAsFunctionDescriptor.create(variable);
if ((functionDescriptor.getReceiverType() != null) == receiverNeeded) {
if ((functionDescriptor.getReceiver() != NO_RECEIVER) == receiverNeeded) {
functions.add(functionDescriptor);
}
}
@@ -811,7 +781,7 @@ public class CallResolver {
@Override
protected Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
VariableDescriptor variable = scope.getVariable(name);
if (variable != null && variable.getReceiverType() == null) {
if (variable != null && variable.getReceiver() == NO_RECEIVER) {
return Collections.singleton(variable);
}
return Collections.emptyList();
@@ -819,8 +789,8 @@ public class CallResolver {
@NotNull
@Override
protected Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
VariableDescriptor variable = receiverType.getMemberScope().getVariable(name);
protected Collection<VariableDescriptor> getMembersByName(@NotNull ReceiverDescriptor receiver, String name) {
VariableDescriptor variable = receiver.getType().getMemberScope().getVariable(name);
if (variable != null) {
return Collections.singleton(variable);
}
@@ -831,7 +801,7 @@ public class CallResolver {
@Override
protected Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
VariableDescriptor variable = scope.getVariable(name);
if (variable != null && variable.getReceiverType() != null) {
if (variable != null && variable.getReceiver() != NO_RECEIVER) {
return Collections.singleton(variable);
}
return Collections.emptyList();
@@ -839,8 +809,8 @@ public class CallResolver {
@NotNull
@Override
protected ResolutionTask<VariableDescriptor> createTask(JetType receiverType, Call call, Collection<VariableDescriptor> candidates) {
return new ResolutionTask<VariableDescriptor>(candidates, receiverType, call);
protected ResolutionTask<VariableDescriptor> createTask(@NotNull ReceiverDescriptor receiver, Call call, Collection<VariableDescriptor> candidates) {
return new ResolutionTask<VariableDescriptor>(candidates, receiver, call);
}
};
@@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
@@ -59,10 +60,10 @@ import java.util.Set;
if (overrides(f, g)) return true;
if (overrides(g, f)) return false;
JetType receiverTypeOfF = f.getReceiverType();
JetType receiverTypeOfG = g.getReceiverType();
if (receiverTypeOfF != null && receiverTypeOfG != null) {
if (!typeMoreSpecific(receiverTypeOfF, receiverTypeOfG)) return false;
ReceiverDescriptor receiverOfF = f.getReceiver();
ReceiverDescriptor receiverOfG = g.getReceiver();
if (f.getReceiver().exists() && g.getReceiver().exists()) {
if (!typeMoreSpecific(receiverOfF.getType(), receiverOfG.getType())) return false;
}
List<ValueParameterDescriptor> fParams = f.getValueParameters();
@@ -8,9 +8,9 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetTypeProjection;
import org.jetbrains.jet.lang.psi.ValueArgument;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -19,7 +19,7 @@ import java.util.List;
*/
/*package*/ class ResolutionTask<Descriptor extends CallableDescriptor> {
private final Collection<Descriptor> candidates;
private final JetType receiverType;
private final ReceiverDescriptor receiver;
private final List<JetTypeProjection> typeArguments;
private final List<? extends ValueArgument> valueArguments;
private final List<JetExpression> functionLiteralArguments;
@@ -27,12 +27,12 @@ import java.util.List;
public ResolutionTask(
@NotNull Collection<Descriptor> candidates,
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor receiver,
@NotNull List<JetTypeProjection> typeArguments,
@NotNull List<? extends ValueArgument> valueArguments,
@NotNull List<JetExpression> functionLiteralArguments) {
this.candidates = candidates;
this.receiverType = receiverType;
this.receiver = receiver;
this.typeArguments = typeArguments;
this.valueArguments = valueArguments;
this.functionLiteralArguments = functionLiteralArguments;
@@ -40,10 +40,10 @@ import java.util.List;
public ResolutionTask(
@NotNull Collection<Descriptor> candidates,
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor receiver,
@NotNull Call call
) {
this(candidates, receiverType, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
this(candidates, receiver, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
}
@NotNull
@@ -51,9 +51,9 @@ import java.util.List;
return candidates;
}
@Nullable
public JetType getReceiverType() {
return receiverType;
@NotNull
public ReceiverDescriptor getReceiver() {
return receiver;
}
@NotNull
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.resolve.calls;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
@@ -10,7 +9,6 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.Call;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection;
import java.util.List;
@@ -64,33 +62,33 @@ import java.util.List;
return false;
}
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @Nullable JetType receiverType, @NotNull Call call, @NotNull String name) {
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull Call call, @NotNull String name) {
List<ResolutionTask<D>> result = Lists.newArrayList();
doComputeTasks(scope, receiverType, call, name, result);
doComputeTasks(scope, receiver, call, name, result);
return result;
}
private void doComputeTasks(JetScope scope, JetType receiverType, Call call, String name, List<ResolutionTask<D>> result) {
List<ReceiverDescriptor> receivers = Lists.newArrayList();
scope.getImplicitReceiversHierarchy(receivers);
if (receiverType != null) {
private void doComputeTasks(JetScope scope, ReceiverDescriptor receiver, Call call, String name, List<ResolutionTask<D>> result) {
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
scope.getImplicitReceiversHierarchy(implicitReceivers);
if (receiver != ReceiverDescriptor.NO_RECEIVER) {
Collection<D> extensionFunctions = getExtensionsByName(scope, name);
List<D> nonlocals = Lists.newArrayList();
List<D> locals = Lists.newArrayList();
//noinspection unchecked,RedundantTypeArguments
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
Collection<D> members = getMembersByName(receiverType, name);
Collection<D> members = getMembersByName(receiver, name);
addTask(result, receiverType, call, locals);
addTask(result, null, call, members);
addTask(result, receiver, call, locals);
addTask(result, ReceiverDescriptor.NO_RECEIVER, call, members);
for (ReceiverDescriptor receiver : receivers) {
Collection<D> memberExtensions = getExtensionsByName(receiver.getReceiverType().getMemberScope(), name);
addTask(result, receiverType, call, memberExtensions);
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
addTask(result, receiver, call, memberExtensions);
}
addTask(result, receiverType, call, nonlocals);
addTask(result, receiver, call, nonlocals);
}
else {
Collection<D> functions = getNonExtensionsByName(scope, name);
@@ -100,13 +98,13 @@ import java.util.List;
//noinspection unchecked,RedundantTypeArguments
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
addTask(result, receiverType, call, locals);
addTask(result, receiver, call, locals);
for (ReceiverDescriptor receiver : receivers) {
doComputeTasks(scope, receiver.getReceiverType(), call, name, result);
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
doComputeTasks(scope, implicitReceiver, call, name, result);
}
addTask(result, receiverType, call, nonlocals);
addTask(result, receiver, call, nonlocals);
}
}
@@ -114,17 +112,17 @@ import java.util.List;
protected abstract Collection<D> getNonExtensionsByName(JetScope scope, String name);
@NotNull
protected abstract Collection<D> getMembersByName(@NotNull JetType receiverType, String name);
protected abstract Collection<D> getMembersByName(@NotNull ReceiverDescriptor receiver, String name);
@NotNull
protected abstract Collection<D> getExtensionsByName(JetScope scope, String name);
private void addTask(@NotNull List<ResolutionTask<D>> result, @Nullable JetType receiverType, @NotNull Call call, @NotNull Collection<D> candidates) {
private void addTask(@NotNull List<ResolutionTask<D>> result, @NotNull ReceiverDescriptor receiver, @NotNull Call call, @NotNull Collection<D> candidates) {
if (candidates.isEmpty()) return;
result.add(createTask(receiverType, call, candidates));
result.add(createTask(receiver, call, candidates));
}
@NotNull
protected abstract ResolutionTask<D> createTask(JetType receiverType, Call call, Collection<D> candidates);
protected abstract ResolutionTask<D> createTask(ReceiverDescriptor receiver, Call call, Collection<D> candidates);
}
@@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.Collection;
import java.util.Set;
@@ -15,7 +15,7 @@ import java.util.Set;
/*package*/ interface TracingStrategy {
TracingStrategy EMPTY = new TracingStrategy() {
@Override
public void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor) {}
public void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor) {}
@Override
public void unresolvedReference(@NotNull BindingTrace trace) {}
@@ -24,7 +24,7 @@ import java.util.Set;
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates) {}
@Override
public void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType) {}
public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver) {}
@Override
public void noReceiverAllowed(@NotNull BindingTrace trace) {}
@@ -48,13 +48,13 @@ import java.util.Set;
public void typeInferenceFailed(@NotNull BindingTrace trace) {}
};
void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor);
void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor);
void unresolvedReference(@NotNull BindingTrace trace);
<D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates);
void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType);
void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver);
void noReceiverAllowed(@NotNull BindingTrace trace);
@@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.resolve.scopes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
/**
* @author abreslav
@@ -30,5 +30,5 @@ public interface WritableScope extends JetScope {
void importScope(@NotNull JetScope imported);
void setImplicitReceiver(@NotNull ImplicitReceiverDescriptor implicitReceiver);
void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver);
}
@@ -7,7 +7,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.*;
@@ -36,7 +35,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
private Map<String, List<DeclarationDescriptor>> labelsToDescriptors;
@Nullable
private ImplicitReceiverDescriptor implicitReceiver;
private ReceiverDescriptor implicitReceiver;
public WritableScopeImpl(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull RedeclarationHandler redeclarationHandler) {
super(scope, redeclarationHandler);
@@ -275,7 +274,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
}
@Override
public void setImplicitReceiver(@NotNull ImplicitReceiverDescriptor implicitReceiver) {
public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) {
if (this.implicitReceiver != null) {
throw new UnsupportedOperationException("Receiver redeclared");
}
@@ -284,7 +283,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
@Override
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
if (implicitReceiver != null && implicitReceiver != ReceiverDescriptor.NO_RECEIVER) {
if (implicitReceiver != null && implicitReceiver.exists()) {
result.add(implicitReceiver);
}
super.getImplicitReceiversHierarchy(result);
@@ -4,7 +4,6 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.Collection;
@@ -147,7 +146,7 @@ public class WriteThroughScope extends WritableScopeWithImports {
}
@Override
public void setImplicitReceiver(@NotNull ImplicitReceiverDescriptor implicitReceiver) {
public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) {
writableWorker.setImplicitReceiver(implicitReceiver);
}
@@ -0,0 +1,26 @@
package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.JetType;
/**
* @author abreslav
*/
public class AbstractReceiverDescriptor implements ReceiverDescriptor {
protected final JetType receiverType;
public AbstractReceiverDescriptor(@NotNull JetType receiverType) {
this.receiverType = receiverType;
}
@Override
@NotNull
public JetType getType() {
return receiverType;
}
@Override
public boolean exists() {
return true;
}
}
@@ -1,22 +0,0 @@
package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.JetType;
/**
* @author abreslav
*/
public class ExplicitReceiver implements ReceiverDescriptor {
private final JetType type;
public ExplicitReceiver(@NotNull JetType type) {
this.type = type;
}
@NotNull
@Override
public JetType getReceiverType() {
return type;
}
}
@@ -0,0 +1,23 @@
package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.types.JetType;
/**
* @author abreslav
*/
public class ExpressionReceiver extends AbstractReceiverDescriptor implements ReceiverDescriptor {
private final JetExpression expression;
public ExpressionReceiver(@NotNull JetExpression expression, @NotNull JetType type) {
super(type);
this.expression = expression;
}
@NotNull
public JetExpression getExpression() {
return expression;
}
}
@@ -1,13 +0,0 @@
package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
/**
* @author abreslav
*/
public class ExtensionCallableReceiver extends ImplicitReceiverDescriptor {
public ExtensionCallableReceiver(CallableDescriptor callableDescriptor) {
super(callableDescriptor, callableDescriptor.getReceiverType());
}
}
@@ -0,0 +1,15 @@
package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.types.JetType;
/**
* @author abreslav
*/
public class ExtensionReceiver extends ImplicitReceiverDescriptor {
public ExtensionReceiver(@NotNull CallableDescriptor callableDescriptor, @NotNull JetType receiverType) {
super(callableDescriptor, receiverType);
}
}
@@ -9,21 +9,14 @@ import org.jetbrains.jet.lang.types.JetType;
*
* @author abreslav
*/
public abstract class ImplicitReceiverDescriptor implements ReceiverDescriptor {
private final JetType receiverType;
public abstract class ImplicitReceiverDescriptor extends AbstractReceiverDescriptor {
private final DeclarationDescriptor declarationDescriptor;
protected ImplicitReceiverDescriptor(DeclarationDescriptor declarationDescriptor, JetType receiverType) {
this.receiverType = receiverType;
protected ImplicitReceiverDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, @NotNull JetType receiverType) {
super(receiverType);
this.declarationDescriptor = declarationDescriptor;
}
@Override
@NotNull
public JetType getReceiverType() {
return receiverType;
}
@NotNull
public DeclarationDescriptor getDeclarationDescriptor() {
return declarationDescriptor;
@@ -1,7 +1,6 @@
package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
/**
@@ -12,8 +11,13 @@ public interface ReceiverDescriptor {
ReceiverDescriptor NO_RECEIVER = new ReceiverDescriptor() {
@NotNull
@Override
public JetType getReceiverType() {
return JetStandardClasses.getNothingType();
public JetType getType() {
throw new UnsupportedOperationException("NO_RECEIVER.getType()");
}
@Override
public boolean exists() {
return false;
}
@Override
@@ -23,5 +27,7 @@ public interface ReceiverDescriptor {
};
@NotNull
JetType getReceiverType();
JetType getType();
boolean exists();
}
@@ -0,0 +1,16 @@
package org.jetbrains.jet.lang.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.JetType;
/**
* This represents the receiver of hasNext and next() in for-loops
* Cannot be an expression receiver because there is no expression for the iterator() call
*
* @author abreslav
*/
public class TransientReceiver extends AbstractReceiverDescriptor {
public TransientReceiver(@NotNull JetType type) {
super(type);
}
}
@@ -26,6 +26,9 @@ import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
@@ -196,7 +199,7 @@ public class JetTypeInferrer {
}
@NotNull
public JetType safeGetType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) {
public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) {
JetType type = getType(scope, expression, expectedType);
if (type != null) {
return type;
@@ -220,9 +223,9 @@ public class JetTypeInferrer {
private void checkNullSafety(@Nullable JetType receiverType, @NotNull ASTNode operationTokenNode, @Nullable FunctionDescriptor callee) {
if (receiverType != null && callee != null) {
boolean namespaceType = receiverType instanceof NamespaceType;
JetType calleeReceiverType = callee.getReceiverType();
boolean nullableReceiver = !namespaceType && receiverType.isNullable();
boolean calleeForbidsNullableReceiver = calleeReceiverType == null || !calleeReceiverType.isNullable();
ReceiverDescriptor calleeReceiver = callee.getReceiver();
boolean calleeForbidsNullableReceiver = !calleeReceiver.exists() || !calleeReceiver.getType().isNullable();
IElementType operationSign = operationTokenNode.getElementType();
if (nullableReceiver && calleeForbidsNullableReceiver && operationSign == JetTokens.DOT) {
@@ -681,6 +684,20 @@ public class JetTypeInferrer {
}
return ErrorUtils.createErrorType("Type for " + expression.getText());
}
@Nullable
public final ExpressionReceiver getExpressionReceiver(@NotNull JetExpression expression, TypeInferenceContext context) {
JetType type = getType(expression, context);
if (type == null) {
return null;
}
return new ExpressionReceiver(expression, type);
}
@NotNull
public final ExpressionReceiver safeGetExpressionReceiver(@NotNull JetExpression expression, TypeInferenceContext context) {
return new ExpressionReceiver(expression, safeGetType(expression, context));
}
@Nullable
public final JetType getType(@NotNull JetExpression expression, TypeInferenceContext context) {
@@ -761,7 +778,7 @@ public class JetTypeInferrer {
}
}
else {
return getSelectorReturnType(null, expression, context); // TODO : Extensions to this
return getSelectorReturnType(ReceiverDescriptor.NO_RECEIVER, expression, context); // TODO : Extensions to this
// assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType();
// if (referencedName != null) {
// VariableDescriptor variable = context.scope.getVariable(referencedName);
@@ -894,7 +911,8 @@ public class JetTypeInferrer {
if (receiverTypeRef != null) {
receiverType = context.typeResolver.resolveType(context.scope, receiverTypeRef);
} else {
receiverType = context.scope.getImplicitReceiver().getReceiverType();
ReceiverDescriptor implicitReceiver = context.scope.getImplicitReceiver();
receiverType = implicitReceiver.exists() ? implicitReceiver.getType() : null;
}
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
@@ -1216,7 +1234,7 @@ public class JetTypeInferrer {
@Override
public JetType visitThisExpression(JetThisExpression expression, TypeInferenceContext context) {
JetType result = null;
JetType thisType = null;
ReceiverDescriptor thisReceiver = null;
String labelName = expression.getLabelName();
if (labelName != null) {
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
@@ -1227,11 +1245,11 @@ public class JetTypeInferrer {
DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next();
if (declarationDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
thisType = classDescriptor.getDefaultType();
thisReceiver = classDescriptor.getImplicitReceiver();
}
else if (declarationDescriptor instanceof FunctionDescriptor) {
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
thisType = functionDescriptor.getReceiverType();
thisReceiver = functionDescriptor.getReceiver();
}
else {
throw new UnsupportedOperationException(); // TODO
@@ -1245,11 +1263,8 @@ public class JetTypeInferrer {
if (psiElement instanceof JetFunctionLiteralExpression) {
DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement);
if (declarationDescriptor instanceof FunctionDescriptor) {
thisType = ((FunctionDescriptor) declarationDescriptor).getReceiverType();
if (thisType == null) {
thisType = JetStandardClasses.getNothingType();
}
else {
thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiver();
if (thisReceiver.exists()) {
context.trace.record(REFERENCE_TARGET, targetLabel, declarationDescriptor);
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor);
}
@@ -1268,7 +1283,7 @@ public class JetTypeInferrer {
}
}
else {
thisType = context.scope.getImplicitReceiver().getReceiverType();
thisReceiver = context.scope.getImplicitReceiver();
DeclarationDescriptor declarationDescriptorForUnqualifiedThis = context.scope.getDeclarationDescriptorForUnqualifiedThis();
if (declarationDescriptorForUnqualifiedThis != null) {
@@ -1276,8 +1291,8 @@ public class JetTypeInferrer {
}
}
if (thisType != null) {
if (JetStandardClasses.isNothing(thisType)) {
if (thisReceiver != null) {
if (!thisReceiver.exists()) {
// context.trace.getErrorHandler().genericError(expression.getNode(), "'this' is not defined in this context");
context.trace.report(NO_THIS.on(expression));
}
@@ -1293,6 +1308,7 @@ public class JetTypeInferrer {
if (classifierCandidate instanceof ClassDescriptor) {
ClassDescriptor superclass = (ClassDescriptor) classifierCandidate;
JetType thisType = thisReceiver.getType();
Collection<? extends JetType> supertypes = thisType.getConstructor().getSupertypes();
TypeSubstitutor substitutor = TypeSubstitutor.create(thisType);
for (JetType declaredSupertype : supertypes) {
@@ -1307,8 +1323,9 @@ public class JetTypeInferrer {
}
}
}
} else {
result = thisType;
}
else {
result = thisReceiver.getType();
}
if (result != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getThisReference(), result);
@@ -1395,7 +1412,8 @@ public class JetTypeInferrer {
// JetScope compositeScope = new ScopeWithReceiver(context.scope, subjectType, semanticServices.getTypeChecker());
if (callSuffixExpression != null) {
// JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false, context);
JetType selectorReturnType = getSelectorReturnType(subjectType, callSuffixExpression, context);//getType(compositeScope, callSuffixExpression, false, context);
assert subjectExpression != null;
JetType selectorReturnType = getSelectorReturnType(new ExpressionReceiver(subjectExpression, subjectType), callSuffixExpression, context);//getType(compositeScope, callSuffixExpression, false, context);
ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression", context);
context.services.checkNullSafety(subjectType, condition.getOperationTokenNode(), getCalleeFunctionDescriptor(callSuffixExpression, context));
}
@@ -1473,7 +1491,8 @@ public class JetTypeInferrer {
public void visitDecomposerPattern(JetDecomposerPattern pattern) {
JetExpression decomposerExpression = pattern.getDecomposerExpression();
if (decomposerExpression != null) {
JetType selectorReturnType = getSelectorReturnType(subjectType, decomposerExpression, context);
ReceiverDescriptor receiver = new TransientReceiver(subjectType);
JetType selectorReturnType = getSelectorReturnType(receiver, decomposerExpression, context);
result[0] = checkPatternType(pattern.getArgumentList(), selectorReturnType == null ? ErrorUtils.createErrorType("No type") : selectorReturnType, scopeToExtend, context);
}
@@ -1839,13 +1858,12 @@ public class JetTypeInferrer {
TypeInferenceContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
JetParameter loopParameter = expression.getLoopParameter();
JetExpression loopRange = expression.getLoopRange();
JetType loopRangeType = null;
if (loopRange != null) {
loopRangeType = getType(loopRange, context.replaceScope(context.scope));
}
JetType expectedParameterType = null;
if (loopRangeType != null) {
expectedParameterType = checkIterableConvention(loopRangeType, loopRange, context);
if (loopRange != null) {
ExpressionReceiver loopRangeReceiver = getExpressionReceiver(loopRange, context.replaceScope(context.scope));
if (loopRangeReceiver != null) {
expectedParameterType = checkIterableConvention(loopRangeReceiver, context);
}
}
WritableScope loopScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("Scope with for-loop index");
@@ -1881,42 +1899,42 @@ public class JetTypeInferrer {
}
@Nullable
private JetType checkIterableConvention(@NotNull JetType type, @NotNull JetExpression loopRange, TypeInferenceContext context) {
ASTNode reportErrorsOn = loopRange.getNode();
OverloadResolutionResult<FunctionDescriptor> iteratorResolutionResult = callResolver.resolveExactSignature(context.scope, type, "iterator", Collections.<JetType>emptyList());
private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, TypeInferenceContext context) {
JetExpression loopRangeExpression = loopRange.getExpression();
OverloadResolutionResult<FunctionDescriptor> iteratorResolutionResult = callResolver.resolveExactSignature(context.scope, loopRange, "iterator", Collections.<JetType>emptyList());
if (iteratorResolutionResult.isSuccess()) {
FunctionDescriptor iteratorFunction = iteratorResolutionResult.getDescriptor();
context.trace.record(LOOP_RANGE_ITERATOR, loopRange, iteratorFunction);
context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction);
JetType iteratorType = iteratorFunction.getReturnType();
FunctionDescriptor hasNextFunction = checkHasNextFunctionSupport(loopRange, iteratorType, context);
FunctionDescriptor hasNextFunction = checkHasNextFunctionSupport(loopRangeExpression, iteratorType, context);
boolean hasNextFunctionSupported = hasNextFunction != null;
VariableDescriptor hasNextProperty = checkHasNextPropertySupport(loopRange, iteratorType, context);
VariableDescriptor hasNextProperty = checkHasNextPropertySupport(loopRangeExpression, iteratorType, context);
boolean hasNextPropertySupported = hasNextProperty != null;
if (hasNextFunctionSupported && hasNextPropertySupported && !ErrorUtils.isErrorType(iteratorType)) {
// TODO : overload resolution rules impose priorities here???
// context.trace.getErrorHandler().genericError(reportErrorsOn, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property");
context.trace.report(HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY.on(reportErrorsOn));
context.trace.report(HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY.on(loopRangeExpression));
}
else if (!hasNextFunctionSupported && !hasNextPropertySupported) {
// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property");
context.trace.report(HAS_NEXT_MISSING.on(reportErrorsOn));
context.trace.report(HAS_NEXT_MISSING.on(loopRangeExpression));
}
else {
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange, hasNextFunctionSupported ? hasNextFunction : hasNextProperty);
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty);
}
OverloadResolutionResult<FunctionDescriptor> nextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.<JetType>emptyList());
OverloadResolutionResult<FunctionDescriptor> nextResolutionResult = callResolver.resolveExactSignature(context.scope, new TransientReceiver(iteratorType), "next", Collections.<JetType>emptyList());
if (nextResolutionResult.isAmbiguity()) {
// context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression");
context.trace.report(NEXT_AMBIGUITY.on(reportErrorsOn));
context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression));
} else if (nextResolutionResult.isNothing()) {
// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method");
context.trace.report(NEXT_MISSING.on(reportErrorsOn));
context.trace.report(NEXT_MISSING.on(loopRangeExpression));
} else {
FunctionDescriptor nextFunction = nextResolutionResult.getDescriptor();
context.trace.record(LOOP_RANGE_NEXT, loopRange, nextFunction);
context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction);
return nextFunction.getReturnType();
}
}
@@ -1927,11 +1945,11 @@ public class JetTypeInferrer {
// stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
// }
// errorMessage = stringBuffer.toString();
context.trace.report(ITERATOR_AMBIGUITY.on(reportErrorsOn, iteratorResolutionResult.getDescriptors()));
context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResult.getDescriptors()));
}
else {
// context.trace.getErrorHandler().genericError(reportErrorsOn, errorMessage);
context.trace.report(ITERATOR_MISSING.on(reportErrorsOn));
context.trace.report(ITERATOR_MISSING.on(loopRangeExpression));
}
}
return null;
@@ -1939,7 +1957,7 @@ public class JetTypeInferrer {
@Nullable
private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, TypeInferenceContext context) {
OverloadResolutionResult<FunctionDescriptor> hasNextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.<JetType>emptyList());
OverloadResolutionResult<FunctionDescriptor> hasNextResolutionResult = callResolver.resolveExactSignature(context.scope, new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
if (hasNextResolutionResult.isAmbiguity()) {
// context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression");
context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange));
@@ -2001,7 +2019,7 @@ public class JetTypeInferrer {
// Clean resolution: no autocasts
TemporaryBindingTrace cleanResolutionTrace = TemporaryBindingTrace.create(context.trace);
TypeInferenceContext cleanResolutionContext = context.replaceBindingTrace(cleanResolutionTrace);
JetType selectorReturnType = getSelectorReturnType(receiverType, selectorExpression, cleanResolutionContext);
JetType selectorReturnType = getSelectorReturnType(new ExpressionReceiver(receiverExpression, receiverType), selectorExpression, cleanResolutionContext);
//TODO move further
if (expression.getOperationSign() == JetTokens.SAFE_ACCESS) {
@@ -2022,7 +2040,7 @@ public class JetTypeInferrer {
TemporaryBindingTrace autocastResolutionTrace = TemporaryBindingTrace.create(context.trace);
TypeInferenceContext autocastResolutionContext = context.replaceBindingTrace(autocastResolutionTrace);
for (JetType possibleType : possibleTypes) {
selectorReturnType = getSelectorReturnType(possibleType, selectorExpression, autocastResolutionContext);
selectorReturnType = getSelectorReturnType(new ExpressionReceiver(receiverExpression, possibleType), selectorExpression, autocastResolutionContext);
if (selectorReturnType != null) {
context.services.checkAutoCast(receiverExpression, possibleType, variableDescriptor, autocastResolutionTrace);
autocastResolutionTrace.commit();
@@ -2145,20 +2163,20 @@ public class JetTypeInferrer {
}
@Nullable
private JetType getSelectorReturnType(@Nullable JetType receiverType, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
private JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
if (selectorExpression instanceof JetCallExpression) {
return callResolver.resolveCall(context.trace, context.scope, receiverType, (JetCallExpression) selectorExpression, context.expectedType);
return callResolver.resolveCall(context.trace, context.scope, receiver, (JetCallExpression) selectorExpression, context.expectedType);
}
else if (selectorExpression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression;
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
VariableDescriptor variableDescriptor = callResolver.resolveSimpleProperty(temporaryTrace, context.scope, receiverType, nameExpression, context.expectedType);
VariableDescriptor variableDescriptor = callResolver.resolveSimpleProperty(temporaryTrace, context.scope, receiver, nameExpression, context.expectedType);
if (variableDescriptor != null) {
temporaryTrace.commit();
return context.services.checkEnrichedType(variableDescriptor.getOutType(), nameExpression, context);
}
TypeInferenceContext newContext = receiverType == null ? context : context.replaceScope(receiverType.getMemberScope());
TypeInferenceContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context;
JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext);
if (jetType == null) {
context.trace.report(UNRESOLVED_REFERENCE.on(nameExpression));
@@ -2169,10 +2187,11 @@ public class JetTypeInferrer {
}
else if (selectorExpression instanceof JetQualifiedExpression) {
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression;
JetType newReceiverType = getSelectorReturnType(receiverType, qualifiedExpression.getReceiverExpression(), context.replaceExpectedType(NO_EXPECTED_TYPE));
JetExpression newReceiverExpression = qualifiedExpression.getReceiverExpression();
JetType newReceiverType = getSelectorReturnType(receiver, newReceiverExpression, context.replaceExpectedType(NO_EXPECTED_TYPE));
JetExpression newSelectorExpression = qualifiedExpression.getSelectorExpression();
if (newReceiverType != null && newSelectorExpression != null) {
return getSelectorReturnType(newReceiverType, newSelectorExpression, context);
return getSelectorReturnType(new ExpressionReceiver(newReceiverExpression, newReceiverType), newSelectorExpression, context);
}
}
else {
@@ -2185,7 +2204,7 @@ public class JetTypeInferrer {
@Override
public JetType visitCallExpression(JetCallExpression expression, TypeInferenceContext context) {
JetType expressionType = callResolver.resolveCall(context.trace, context.scope, null, expression, context.expectedType);
JetType expressionType = callResolver.resolveCall(context.trace, context.scope, ReceiverDescriptor.NO_RECEIVER, expression, context.expectedType);
return context.services.checkType(expressionType, expression, context);
}
@@ -2219,8 +2238,8 @@ public class JetTypeInferrer {
context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression"));
return null;
}
JetType receiverType = getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
if (receiverType == null) return null;
ExpressionReceiver receiver = getExpressionReceiver(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
if (receiver == null) return null;
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace,
@@ -2228,7 +2247,7 @@ public class JetTypeInferrer {
CallMaker.makeCall(expression),
expression.getOperationSign(),
name,
receiverType,
receiver,
context.expectedType);
if (functionDescriptor == null) return null;
@@ -2239,6 +2258,7 @@ public class JetTypeInferrer {
result = JetStandardClasses.getUnitType();
}
else {
JetType receiverType = receiver.getType();
if (!semanticServices.getTypeChecker().isSubtypeOf(returnType, receiverType)) {
// context.trace.getErrorHandler().genericError(operationSign.getNode(), name + " must return " + receiverType + " but returns " + returnType);
context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name, receiverType, returnType));
@@ -2298,9 +2318,9 @@ public class JetTypeInferrer {
else if (equalsOperations.contains(operationType)) {
String name = "equals";
if (right != null) {
JetType leftType = safeGetType(left, context.replaceScope(context.scope));
ExpressionReceiver receiver = safeGetExpressionReceiver(left, context.replaceScope(context.scope));
OverloadResolutionResult<FunctionDescriptor> resolutionResult = callResolver.resolveExactSignature(
context.scope, leftType, "equals",
context.scope, receiver, "equals",
Collections.singletonList(JetStandardClasses.getNullableAnyType()));
if (resolutionResult.isSuccess()) {
FunctionDescriptor equals = resolutionResult.getDescriptor();
@@ -2379,13 +2399,13 @@ public class JetTypeInferrer {
private void checkInExpression(JetSimpleNameExpression operationSign, JetExpression left, JetExpression right, TypeInferenceContext context) {
String name = "contains";
JetType receiverType = context.services.safeGetType(context.scope, right, NO_EXPECTED_TYPE);
ExpressionReceiver receiver = safeGetExpressionReceiver(right, context.replaceExpectedType(NO_EXPECTED_TYPE));
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace,
context.scope,
CallMaker.makeCall(operationSign, Collections.singletonList(left)),
operationSign,
name, receiverType, context.expectedType);
name, receiver, context.expectedType);
JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null;
ensureBooleanResult(operationSign, name, containsType, context);
}
@@ -2448,16 +2468,16 @@ public class JetTypeInferrer {
public JetType visitArrayAccessExpression(JetArrayAccessExpression expression, TypeInferenceContext contextWithExpectedType) {
TypeInferenceContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
JetExpression arrayExpression = expression.getArrayExpression();
JetType receiverType = getType(arrayExpression, context.replaceScope(context.scope));
ExpressionReceiver receiver = getExpressionReceiver(arrayExpression, context.replaceScope(context.scope));
if (receiverType != null) {
if (receiver != null) {
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace,
context.scope,
CallMaker.makeCall(expression, expression.getIndexExpressions()),
expression,
"get",
receiverType,
receiver,
context.expectedType);
if (functionDescriptor != null) {
return context.services.checkType(functionDescriptor.getReturnType(), expression, contextWithExpectedType);
@@ -2468,17 +2488,17 @@ public class JetTypeInferrer {
@Nullable
protected JetType getTypeForBinaryCall(JetScope scope, String name, TypeInferenceContext context, JetBinaryExpression binaryExpression) {
JetType leftType = getType(binaryExpression.getLeft(), context.replaceScope(scope));
ExpressionReceiver receiver = safeGetExpressionReceiver(binaryExpression.getLeft(), context.replaceScope(scope));
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace,
scope,
CallMaker.makeCall(binaryExpression),
binaryExpression.getOperationReference(),
name,
leftType,
receiver,
context.expectedType);
if (functionDescriptor != null) {
if (leftType != null && leftType.isNullable()) {
if (receiver.getType().isNullable()) {
// TODO : better error message for '1 + nullableVar' case
JetExpression right = binaryExpression.getRight();
String rightText = right == null ? "" : right.getText();
@@ -2718,8 +2738,8 @@ public class JetTypeInferrer {
}
private JetType resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign, TypeInferenceContext context) {
JetType receiverType = getType(arrayAccessExpression.getArrayExpression(), context.replaceScope(scope));
if (receiverType == null) return null;
ExpressionReceiver receiver = getExpressionReceiver(arrayAccessExpression.getArrayExpression(), context.replaceScope(scope));
if (receiver == null) return null;
//
Call call = CallMaker.makeCall(arrayAccessExpression, rightHandSide);
// // TODO : nasty hack: effort is duplicated
@@ -2733,7 +2753,7 @@ public class JetTypeInferrer {
scope,
call,
arrayAccessExpression,
"set", receiverType, NO_EXPECTED_TYPE);
"set", receiver, NO_EXPECTED_TYPE);
if (functionDescriptor == null) return null;
context.trace.record(REFERENCE_TARGET, operationSign, functionDescriptor);
return context.services.checkType(functionDescriptor.getReturnType(), arrayAccessExpression, context);
@@ -3,7 +3,9 @@ package org.jetbrains.jet.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection;
import java.util.Collections;
@@ -128,7 +130,7 @@ public class DescriptorRenderer {
@Override
public Void visitVariableDescriptor(VariableDescriptor descriptor, StringBuilder builder) {
String typeString = renderPropertyPrefixAndComputeTypeString(builder, Collections.<TypeParameterDescriptor>emptyList(), null, descriptor.getOutType(), descriptor.getInType());
String typeString = renderPropertyPrefixAndComputeTypeString(builder, Collections.<TypeParameterDescriptor>emptyList(), ReceiverDescriptor.NO_RECEIVER, descriptor.getOutType(), descriptor.getInType());
renderName(descriptor, builder);
builder.append(" : ").append(escape(typeString));
return super.visitVariableDescriptor(descriptor, builder);
@@ -137,7 +139,7 @@ public class DescriptorRenderer {
private String renderPropertyPrefixAndComputeTypeString(
@NotNull StringBuilder builder,
@NotNull List<TypeParameterDescriptor> typeParameters,
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor receiver,
@Nullable JetType outType,
@Nullable JetType inType) {
String typeString = lt() + "no type>";
@@ -161,8 +163,8 @@ public class DescriptorRenderer {
renderTypeParameters(typeParameters, builder);
if (receiverType != null) {
builder.append(escape(renderType(receiverType))).append(".");
if (receiver.exists()) {
builder.append(escape(renderType(receiver.getType()))).append(".");
}
return typeString;
@@ -172,7 +174,7 @@ public class DescriptorRenderer {
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) {
String typeString = renderPropertyPrefixAndComputeTypeString(
builder, descriptor.getTypeParameters(),
descriptor.getReceiverType(),
descriptor.getReceiver(),
descriptor.getOutType(),
descriptor.getInType());
renderName(descriptor, builder);
@@ -185,9 +187,9 @@ public class DescriptorRenderer {
builder.append(renderKeyword("fun")).append(" ");
renderTypeParameters(descriptor.getTypeParameters(), builder);
JetType receiverType = descriptor.getReceiverType();
if (receiverType != null) {
builder.append(escape(renderType(receiverType))).append(".");
ReceiverDescriptor receiver = descriptor.getReceiver();
if (receiver.exists()) {
builder.append(escape(renderType(receiver.getType()))).append(".");
}
renderName(descriptor, builder);
@@ -3,7 +3,7 @@ fun text() {
"direct:a" on {it.body == "<hello/>"} to "mock:a"
"direct:a" on {it => it.body == "<hello/>"} to "mock:a"
bar <!TYPE_MISMATCH!>{1}<!>
bar <!TYPE_MISMATCH!>{<!UNRESOLVED_REFERENCE!>it<!> <!UNRESOLVED_REFERENCE!>+<!> 1}<!>
bar <!TYPE_MISMATCH!>{<!UNRESOLVED_REFERENCE!>it<!> + 1}<!>
bar {it, it1 => it}
bar1 {1}
@@ -16,6 +16,7 @@ import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResult;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.parsing.JetParsingTest;
@@ -106,7 +107,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
List<JetType> parameterTypeList = Arrays.asList(parameterType);
JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext(), JetFlowInformationProvider.NONE);
OverloadResolutionResult<FunctionDescriptor> functions = typeInferrerServices.getCallResolver().resolveExactSignature(classDescriptor.getMemberScope(typeArguments), null, name, parameterTypeList);
OverloadResolutionResult<FunctionDescriptor> functions = typeInferrerServices.getCallResolver().resolveExactSignature(
classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList);
for (FunctionDescriptor function : functions.getDescriptors()) {
List<ValueParameterDescriptor> unsubstitutedValueParameters = function.getValueParameters();
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
@@ -18,7 +18,7 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExplicitReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
@@ -504,13 +504,13 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
assertTrue("Error type expected but " + type + " returned", ErrorUtils.isErrorType(type));
}
private void assertType(String contextType, String expression, String expectedType) {
private void assertType(String contextType, final String expression, String expectedType) {
final JetType thisType = makeType(contextType);
JetScope scope = new JetScopeAdapter(classDefinitions.BASIC_SCOPE) {
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
return new ExplicitReceiver(thisType);
return new ExpressionReceiver(JetPsiFactory.createExpression(getProject(), expression), thisType);
}
};
assertType(scope, expression, expectedType);