Overload resolution is factored out as an independent module CallResolver.java
This commit is contained in:
@@ -117,10 +117,10 @@ public interface JetNodeTypes {
|
|||||||
JetNodeType CALL_EXPRESSION = new JetNodeType("CALL_EXPRESSION", JetCallExpression.class);
|
JetNodeType CALL_EXPRESSION = new JetNodeType("CALL_EXPRESSION", JetCallExpression.class);
|
||||||
JetNodeType ARRAY_ACCESS_EXPRESSION = new JetNodeType("ARRAY_ACCESS_EXPRESSION", JetArrayAccessExpression.class);
|
JetNodeType ARRAY_ACCESS_EXPRESSION = new JetNodeType("ARRAY_ACCESS_EXPRESSION", JetArrayAccessExpression.class);
|
||||||
JetNodeType INDICES = new JetNodeType("INDICES", JetContainerNode.class);
|
JetNodeType INDICES = new JetNodeType("INDICES", JetContainerNode.class);
|
||||||
JetNodeType DOT_QUALIFIED_EXPRESSION = new JetNodeType("DOT_QUALIFIED_EXPRESSION", JetDotQualifiedExpression.class);
|
JetNodeType DOT_QUALIFIED_EXPRESSION = new JetNodeType("DOT_QUALIFIED_EXPRESSION", JetDotQualifiedExpression.class);
|
||||||
JetNodeType HASH_QUALIFIED_EXPRESSION = new JetNodeType("HASH_QUALIFIED_EXPRESSION", JetHashQualifiedExpression.class);
|
JetNodeType HASH_QUALIFIED_EXPRESSION = new JetNodeType("HASH_QUALIFIED_EXPRESSION", JetHashQualifiedExpression.class);
|
||||||
JetNodeType SAFE_ACCESS_EXPRESSION = new JetNodeType("SAFE_ACCESS_EXPRESSION", JetSafeQualifiedExpression.class);
|
JetNodeType SAFE_ACCESS_EXPRESSION = new JetNodeType("SAFE_ACCESS_EXPRESSION", JetSafeQualifiedExpression.class);
|
||||||
JetNodeType PREDICATE_EXPRESSION = new JetNodeType("PREDICATE_EXPRESSION", JetPredicateExpression.class);
|
JetNodeType PREDICATE_EXPRESSION = new JetNodeType("PREDICATE_EXPRESSION", JetPredicateExpression.class);
|
||||||
|
|
||||||
JetNodeType OBJECT_LITERAL = new JetNodeType("OBJECT_LITERAL", JetObjectLiteralExpression.class);
|
JetNodeType OBJECT_LITERAL = new JetNodeType("OBJECT_LITERAL", JetObjectLiteralExpression.class);
|
||||||
JetNodeType ROOT_NAMESPACE = new JetNodeType("ROOT_NAMESPACE", JetRootNamespaceExpression.class);
|
JetNodeType ROOT_NAMESPACE = new JetNodeType("ROOT_NAMESPACE", JetRootNamespaceExpression.class);
|
||||||
|
|||||||
@@ -828,7 +828,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else {
|
else {
|
||||||
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
||||||
List<JetExpression> args = new ArrayList<JetExpression>();
|
List<JetExpression> args = new ArrayList<JetExpression>();
|
||||||
for (JetValueArgument argument : expression.getValueArguments()) {
|
for (ValueArgument argument : expression.getValueArguments()) {
|
||||||
args.add(argument.getArgumentExpression());
|
args.add(argument.getArgumentExpression());
|
||||||
}
|
}
|
||||||
return intrinsic.generate(this, v, expressionType(expression), expression, args, receiver);
|
return intrinsic.generate(this, v, expressionType(expression), expression, args, receiver);
|
||||||
@@ -876,11 +876,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return funDescriptor;
|
return funDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invokeMethodWithArguments(CallableMethod callableMethod, JetCall expression) {
|
public void invokeMethodWithArguments(CallableMethod callableMethod, JetCallElement expression) {
|
||||||
invokeMethodWithArguments(callableMethod, expression, StackValue.none());
|
invokeMethodWithArguments(callableMethod, expression, StackValue.none());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invokeMethodWithArguments(CallableMethod callableMethod, JetCall expression, StackValue receiver) {
|
public void invokeMethodWithArguments(CallableMethod callableMethod, JetCallElement expression, StackValue receiver) {
|
||||||
final Type calleeType = callableMethod.getGenerateCalleeType();
|
final Type calleeType = callableMethod.getGenerateCalleeType();
|
||||||
if (calleeType != null && expression instanceof JetCallExpression) {
|
if (calleeType != null && expression instanceof JetCallExpression) {
|
||||||
gen(expression.getCalleeExpression(), calleeType);
|
gen(expression.getCalleeExpression(), calleeType);
|
||||||
@@ -901,7 +901,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
callableMethod.invoke(v);
|
callableMethod.invoke(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOwnerFromCall(CallableMethod callableMethod, JetCall expression) {
|
private void setOwnerFromCall(CallableMethod callableMethod, JetCallElement expression) {
|
||||||
if (expression.getParent() instanceof JetQualifiedExpression) {
|
if (expression.getParent() instanceof JetQualifiedExpression) {
|
||||||
final JetExpression receiver = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
|
final JetExpression receiver = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
|
||||||
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiver);
|
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiver);
|
||||||
@@ -993,10 +993,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushMethodArguments(JetCall expression, List<Type> valueParameterTypes) {
|
private void pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
||||||
List<JetValueArgument> args = expression.getValueArguments();
|
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||||
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
||||||
JetValueArgument arg = args.get(i);
|
ValueArgument arg = args.get(i);
|
||||||
gen(arg.getArgumentExpression(), valueParameterTypes.get(i));
|
gen(arg.getArgumentExpression(), valueParameterTypes.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1430,7 +1430,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return StackValue.onStack(type);
|
return StackValue.onStack(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushTypeArguments(JetCall expression) {
|
private void pushTypeArguments(JetCallElement expression) {
|
||||||
for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
|
for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
|
||||||
pushTypeArgument(jetTypeArgument);
|
pushTypeArgument(jetTypeArgument);
|
||||||
}
|
}
|
||||||
@@ -1458,7 +1458,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateNewArray(JetCallExpression expression, Type type) {
|
private void generateNewArray(JetCallExpression expression, Type type) {
|
||||||
List<JetValueArgument> args = expression.getValueArguments();
|
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||||
if (args.size() != 1) {
|
if (args.size() != 1) {
|
||||||
throw new CompilationException("array constructor requires one value argument");
|
throw new CompilationException("array constructor requires one value argument");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
return outerDescriptor instanceof ClassDescriptor ? (ClassDescriptor) outerDescriptor : null;
|
return outerDescriptor instanceof ClassDescriptor ? (ClassDescriptor) outerDescriptor : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCall constructorCall,
|
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
||||||
ConstructorDescriptor constructorDescriptor, boolean isJavaSuperclass,
|
ConstructorDescriptor constructorDescriptor, boolean isJavaSuperclass,
|
||||||
ConstructorFrameMap frameMap) {
|
ConstructorFrameMap frameMap) {
|
||||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||||
|
|||||||
@@ -25,13 +25,11 @@ public class JetSemanticServices {
|
|||||||
|
|
||||||
private final JetStandardLibrary standardLibrary;
|
private final JetStandardLibrary standardLibrary;
|
||||||
private final JetTypeChecker typeChecker;
|
private final JetTypeChecker typeChecker;
|
||||||
private final OverloadResolver overloadResolver;
|
|
||||||
private final JetControlFlowDataTraceFactory flowDataTraceFactory;
|
private final JetControlFlowDataTraceFactory flowDataTraceFactory;
|
||||||
|
|
||||||
private JetSemanticServices(JetStandardLibrary standardLibrary, JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
private JetSemanticServices(JetStandardLibrary standardLibrary, JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
||||||
this.standardLibrary = standardLibrary;
|
this.standardLibrary = standardLibrary;
|
||||||
this.typeChecker = new JetTypeChecker(standardLibrary);
|
this.typeChecker = new JetTypeChecker(standardLibrary);
|
||||||
this.overloadResolver = new OverloadResolver(typeChecker);
|
|
||||||
this.flowDataTraceFactory = flowDataTraceFactory;
|
this.flowDataTraceFactory = flowDataTraceFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,10 +52,4 @@ public class JetSemanticServices {
|
|||||||
public JetTypeChecker getTypeChecker() {
|
public JetTypeChecker getTypeChecker() {
|
||||||
return typeChecker;
|
return typeChecker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public OverloadResolver getOverloadResolver() {
|
|
||||||
return overloadResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -530,8 +530,8 @@ public class JetControlFlowProcessor {
|
|||||||
builder.read(expression);
|
builder.read(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitCall(JetCall call) {
|
private void visitCall(JetCallElement call) {
|
||||||
for (JetValueArgument argument : call.getValueArguments()) {
|
for (ValueArgument argument : call.getValueArguments()) {
|
||||||
JetExpression argumentExpression = argument.getArgumentExpression();
|
JetExpression argumentExpression = argument.getArgumentExpression();
|
||||||
if (argumentExpression != null) {
|
if (argumentExpression != null) {
|
||||||
value(argumentExpression, false, false);
|
value(argumentExpression, false, false);
|
||||||
|
|||||||
@@ -73,13 +73,10 @@ public class FunctionDescriptorUtil {
|
|||||||
if (substitutedType == null) return null;
|
if (substitutedType == null) return null;
|
||||||
result.add(new ValueParameterDescriptorImpl(
|
result.add(new ValueParameterDescriptorImpl(
|
||||||
substitutedDescriptor,
|
substitutedDescriptor,
|
||||||
i,
|
unsubstitutedValueParameter,
|
||||||
unsubstitutedValueParameter.getAnnotations(),
|
unsubstitutedValueParameter.getAnnotations(),
|
||||||
unsubstitutedValueParameter.getName(),
|
|
||||||
unsubstitutedValueParameter.getInType() == null ? null : substitutedType,
|
unsubstitutedValueParameter.getInType() == null ? null : substitutedType,
|
||||||
substitutedType,
|
substitutedType
|
||||||
unsubstitutedValueParameter.hasDefaultValue(),
|
|
||||||
unsubstitutedValueParameter.isVararg()
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -64,9 +64,17 @@ public class LazySubstitutingFunctionGroup implements FunctionGroup {
|
|||||||
@Override
|
@Override
|
||||||
public Set<FunctionDescriptor> getFunctionDescriptors() {
|
public Set<FunctionDescriptor> getFunctionDescriptors() {
|
||||||
if (functionDescriptors == null) {
|
if (functionDescriptors == null) {
|
||||||
functionDescriptors = Sets.newHashSet();
|
if (substitutor.isEmpty()) {
|
||||||
for (FunctionDescriptor descriptor : functionGroup.getFunctionDescriptors()) {
|
functionDescriptors = functionGroup.getFunctionDescriptors();
|
||||||
functionDescriptors.add(descriptor.substitute(substitutor));
|
}
|
||||||
|
else {
|
||||||
|
functionDescriptors = Sets.newHashSet();
|
||||||
|
for (FunctionDescriptor descriptor : functionGroup.getFunctionDescriptors()) {
|
||||||
|
FunctionDescriptor substitute = descriptor.substitute(substitutor);
|
||||||
|
if (substitute != null) {
|
||||||
|
functionDescriptors.add(substitute);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return functionDescriptors;
|
return functionDescriptors;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
|
|||||||
private final boolean isVararg;
|
private final boolean isVararg;
|
||||||
private final boolean isVar;
|
private final boolean isVar;
|
||||||
private final int index;
|
private final int index;
|
||||||
|
private final ValueParameterDescriptor original;
|
||||||
|
|
||||||
public ValueParameterDescriptorImpl(
|
public ValueParameterDescriptorImpl(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@@ -27,6 +28,7 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
|
|||||||
boolean hasDefaultValue,
|
boolean hasDefaultValue,
|
||||||
boolean isVararg) {
|
boolean isVararg) {
|
||||||
super(containingDeclaration, annotations, name, inType, outType);
|
super(containingDeclaration, annotations, name, inType, outType);
|
||||||
|
this.original = this;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.hasDefaultValue = hasDefaultValue;
|
this.hasDefaultValue = hasDefaultValue;
|
||||||
this.isVararg = isVararg;
|
this.isVararg = isVararg;
|
||||||
@@ -35,17 +37,17 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
|
|||||||
|
|
||||||
public ValueParameterDescriptorImpl(
|
public ValueParameterDescriptorImpl(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
int index,
|
@NotNull ValueParameterDescriptor original,
|
||||||
@NotNull List<AnnotationDescriptor> annotations,
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
@NotNull String name,
|
@Nullable JetType inType,
|
||||||
boolean isVar,
|
@NotNull JetType outType
|
||||||
boolean hasDefaultValue,
|
) {
|
||||||
boolean isVararg) {
|
super(containingDeclaration, annotations, original.getName(), inType, outType);
|
||||||
super(containingDeclaration, annotations, name, null, null);
|
this.original = original;
|
||||||
this.index = index;
|
this.index = original.getIndex();
|
||||||
this.hasDefaultValue = hasDefaultValue;
|
this.hasDefaultValue = original.hasDefaultValue();
|
||||||
this.isVararg = isVararg;
|
this.isVararg = original.isVararg();
|
||||||
this.isVar = isVar;
|
this.isVar = inType != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -61,12 +63,6 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
|
|||||||
@Override
|
@Override
|
||||||
public int getIndex() {
|
public int getIndex() {
|
||||||
return index;
|
return index;
|
||||||
// final JetDeclaration element = getPsiElement();
|
|
||||||
// final PsiElement parent = element.getParent();
|
|
||||||
// if (parent instanceof JetParameterList) {
|
|
||||||
// return ((JetParameterList) parent).getParameters().indexOf(element);
|
|
||||||
// }
|
|
||||||
// throw new IllegalStateException("couldn't find index for parameter");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -86,7 +82,13 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public VariableDescriptor substitute(TypeSubstitutor substitutor) {
|
public ValueParameterDescriptor getOriginal() {
|
||||||
|
return original == this ? this : original.getOriginal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ValueParameterDescriptor substitute(TypeSubstitutor substitutor) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -1,6 +1,5 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -9,7 +8,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public interface JetCall extends PsiElement {
|
public interface Call {
|
||||||
@Nullable
|
@Nullable
|
||||||
JetExpression getCalleeExpression();
|
JetExpression getCalleeExpression();
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ public interface JetCall extends PsiElement {
|
|||||||
JetValueArgumentList getValueArgumentList();
|
JetValueArgumentList getValueArgumentList();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<JetValueArgument> getValueArguments();
|
List<? extends ValueArgument> getValueArguments();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<JetExpression> getFunctionLiteralArguments();
|
List<JetExpression> getFunctionLiteralArguments();
|
||||||
@@ -25,6 +24,6 @@ public interface JetCall extends PsiElement {
|
|||||||
@NotNull
|
@NotNull
|
||||||
List<JetTypeProjection> getTypeArguments();
|
List<JetTypeProjection> getTypeArguments();
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
JetElement asElement();
|
JetTypeArgumentList getTypeArgumentList();
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class JetAnnotationEntry extends JetElement implements JetCall {
|
public class JetAnnotationEntry extends JetElement implements JetCallElement {
|
||||||
public JetAnnotationEntry(@NotNull ASTNode node) {
|
public JetAnnotationEntry(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ public class JetAnnotationEntry extends JetElement implements JetCall {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<JetValueArgument> getValueArguments() {
|
public List<? extends ValueArgument> getValueArguments() {
|
||||||
JetValueArgumentList list = getValueArgumentList();
|
JetValueArgumentList list = getValueArgumentList();
|
||||||
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
||||||
}
|
}
|
||||||
@@ -62,20 +62,25 @@ public class JetAnnotationEntry extends JetElement implements JetCall {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<JetTypeProjection> getTypeArguments() {
|
public List<JetTypeProjection> getTypeArguments() {
|
||||||
JetTypeReference typeReference = getTypeReference();
|
JetTypeArgumentList typeArgumentList = getTypeArgumentList();
|
||||||
if (typeReference != null) {
|
if (typeArgumentList == null) {
|
||||||
JetTypeElement typeElement = typeReference.getTypeElement();
|
return Collections.emptyList();
|
||||||
if (typeElement instanceof JetUserType) {
|
|
||||||
JetUserType userType = (JetUserType) typeElement;
|
|
||||||
return userType.getTypeArguments();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return typeArgumentList.getArguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public JetElement asElement() {
|
public JetTypeArgumentList getTypeArgumentList() {
|
||||||
return this;
|
JetTypeReference typeReference = getTypeReference();
|
||||||
|
if (typeReference == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||||
|
if (typeElement instanceof JetUserType) {
|
||||||
|
JetUserType userType = (JetUserType) typeElement;
|
||||||
|
return userType.getTypeArgumentList();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,5 +54,4 @@ public class JetBinaryExpression extends JetExpression {
|
|||||||
public IElementType getOperationToken() {
|
public IElementType getOperationToken() {
|
||||||
return getOperationReference().getReferencedNameElementType();
|
return getOperationReference().getReferencedNameElementType();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface JetCallElement extends PsiElement, Call {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class JetCallExpression extends JetExpression implements JetCall {
|
public class JetCallExpression extends JetExpression implements JetCallElement {
|
||||||
public JetCallExpression(@NotNull ASTNode node) {
|
public JetCallExpression(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
@@ -49,15 +49,9 @@ public class JetCallExpression extends JetExpression implements JetCall {
|
|||||||
return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL_EXPRESSION);
|
return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL_EXPRESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public JetElement asElement() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetValueArgument> getValueArguments() {
|
public List<? extends ValueArgument> getValueArguments() {
|
||||||
JetValueArgumentList list = getValueArgumentList();
|
JetValueArgumentList list = getValueArgumentList();
|
||||||
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class JetDelegatorToSuperCall extends JetDelegationSpecifier implements JetCall {
|
public class JetDelegatorToSuperCall extends JetDelegationSpecifier implements JetCallElement {
|
||||||
public JetDelegatorToSuperCall(@NotNull ASTNode node) {
|
public JetDelegatorToSuperCall(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ public class JetDelegatorToSuperCall extends JetDelegationSpecifier implements J
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetValueArgument> getValueArguments() {
|
public List<? extends ValueArgument> getValueArguments() {
|
||||||
JetValueArgumentList list = getValueArgumentList();
|
JetValueArgumentList list = getValueArgumentList();
|
||||||
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
||||||
}
|
}
|
||||||
@@ -57,20 +57,25 @@ public class JetDelegatorToSuperCall extends JetDelegationSpecifier implements J
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<JetTypeProjection> getTypeArguments() {
|
public List<JetTypeProjection> getTypeArguments() {
|
||||||
JetTypeReference typeReference = getTypeReference();
|
JetTypeArgumentList typeArgumentList = getTypeArgumentList();
|
||||||
if (typeReference != null) {
|
if (typeArgumentList == null) {
|
||||||
JetTypeElement typeElement = typeReference.getTypeElement();
|
return Collections.emptyList();
|
||||||
if (typeElement instanceof JetUserType) {
|
|
||||||
JetUserType userType = (JetUserType) typeElement;
|
|
||||||
return userType.getTypeArguments();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return typeArgumentList.getArguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public JetElement asElement() {
|
public JetTypeArgumentList getTypeArgumentList() {
|
||||||
return this;
|
JetTypeReference typeReference = getTypeReference();
|
||||||
|
if (typeReference == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||||
|
if (typeElement instanceof JetUserType) {
|
||||||
|
JetUserType userType = (JetUserType) typeElement;
|
||||||
|
return userType.getTypeArgumentList();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class JetDelegatorToThisCall extends JetDelegationSpecifier implements JetCall {
|
public class JetDelegatorToThisCall extends JetDelegationSpecifier implements JetCallElement {
|
||||||
|
|
||||||
public JetDelegatorToThisCall(@NotNull ASTNode node) {
|
public JetDelegatorToThisCall(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
@@ -38,7 +38,7 @@ public class JetDelegatorToThisCall extends JetDelegationSpecifier implements Je
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetValueArgument> getValueArguments() {
|
public List<? extends ValueArgument> getValueArguments() {
|
||||||
JetValueArgumentList list = getValueArgumentList();
|
JetValueArgumentList list = getValueArgumentList();
|
||||||
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
return list != null ? list.getArguments() : Collections.<JetValueArgument>emptyList();
|
||||||
}
|
}
|
||||||
@@ -49,18 +49,17 @@ public class JetDelegatorToThisCall extends JetDelegationSpecifier implements Je
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public JetElement asElement() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<JetTypeProjection> getTypeArguments() {
|
public List<JetTypeProjection> getTypeArguments() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetTypeArgumentList getTypeArgumentList() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public JetReferenceExpression getThisReference() {
|
public JetReferenceExpression getThisReference() {
|
||||||
return findChildByClass(JetThisReferenceExpression.class);
|
return findChildByClass(JetThisReferenceExpression.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.psi;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
//public class JetNewExpression extends JetExpression implements JetCall {
|
//public class JetNewExpression extends JetExpression implements JetCallElement {
|
||||||
// public JetNewExpression(@NotNull ASTNode node) {
|
// public JetNewExpression(@NotNull ASTNode node) {
|
||||||
// super(node);
|
// super(node);
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
@@ -9,7 +10,7 @@ import org.jetbrains.jet.lexer.JetTokens;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class JetValueArgument extends JetElement {
|
public class JetValueArgument extends JetElement implements ValueArgument {
|
||||||
public JetValueArgument(@NotNull ASTNode node) {
|
public JetValueArgument(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
@@ -23,25 +24,36 @@ public class JetValueArgument extends JetElement {
|
|||||||
return visitor.visitArgument(this, data);
|
return visitor.visitArgument(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Nullable @IfNotParsed
|
@Nullable @IfNotParsed
|
||||||
public JetExpression getArgumentExpression() {
|
public JetExpression getArgumentExpression() {
|
||||||
return findChildByClass(JetExpression.class);
|
return findChildByClass(JetExpression.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public JetValueArgumentName getArgumentName() {
|
public JetValueArgumentName getArgumentName() {
|
||||||
return (JetValueArgumentName) findChildByType(JetNodeTypes.VALUE_ARGUMENT_NAME);
|
return (JetValueArgumentName) findChildByType(JetNodeTypes.VALUE_ARGUMENT_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isNamed() {
|
public boolean isNamed() {
|
||||||
return getArgumentName() != null;
|
return getArgumentName() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isOut() {
|
public boolean isOut() {
|
||||||
return findChildByType(JetTokens.OUT_KEYWORD) != null;
|
return findChildByType(JetTokens.OUT_KEYWORD) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isRef() {
|
public boolean isRef() {
|
||||||
return findChildByType(JetTokens.REF_KEYWORD) != null;
|
return findChildByType(JetTokens.REF_KEYWORD) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public PsiElement asElement() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface ValueArgument {
|
||||||
|
@Nullable
|
||||||
|
@JetElement.IfNotParsed
|
||||||
|
JetExpression getArgumentExpression();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
JetValueArgumentName getArgumentName();
|
||||||
|
|
||||||
|
boolean isNamed();
|
||||||
|
|
||||||
|
boolean isOut();
|
||||||
|
|
||||||
|
boolean isRef();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
PsiElement asElement();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,55 +1,48 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public interface OverloadDomain {
|
//public interface OverloadDomain {
|
||||||
|
//
|
||||||
OverloadDomain EMPTY = new OverloadDomain() {
|
// OverloadDomain EMPTY = new OverloadDomain() {
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
|
// public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
|
||||||
return OverloadResolutionResult.nameNotFound();
|
// return OverloadResolutionResult.nameNotFound();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
|
// public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
|
||||||
return OverloadResolutionResult.nameNotFound();
|
// return OverloadResolutionResult.nameNotFound();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean isEmpty() {
|
// public boolean isEmpty() {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code
|
// * @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code
|
||||||
*/
|
// */
|
||||||
@NotNull
|
// @NotNull
|
||||||
OverloadResolutionResult getFunctionDescriptorForNamedArguments(
|
// OverloadResolutionResult getFunctionDescriptorForNamedArguments(
|
||||||
@NotNull List<JetType> typeArguments,
|
// @NotNull List<JetType> typeArguments,
|
||||||
@NotNull Map<String, JetType> valueArgumentTypes,
|
// @NotNull Map<String, JetType> valueArgumentTypes,
|
||||||
@Nullable JetType functionLiteralArgumentType);
|
// @Nullable JetType functionLiteralArgumentType);
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code
|
// * @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code
|
||||||
*/
|
// */
|
||||||
@NotNull
|
// @NotNull
|
||||||
OverloadResolutionResult getFunctionDescriptorForPositionedArguments(
|
// OverloadResolutionResult getFunctionDescriptorForPositionedArguments(
|
||||||
@NotNull List<JetType> typeArguments,
|
// @NotNull List<JetType> typeArguments,
|
||||||
@NotNull List<JetType> positionedValueArgumentTypes);
|
// @NotNull List<JetType> positionedValueArgumentTypes);
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* @return true if the domain is empty
|
// * @return true if the domain is empty
|
||||||
*/
|
// */
|
||||||
boolean isEmpty();
|
// boolean isEmpty();
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -1,173 +1,159 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionGroup;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class OverloadResolver {
|
//public class OverloadResolver {
|
||||||
|
//
|
||||||
private final JetTypeChecker typeChecker;
|
// private final JetTypeChecker typeChecker;
|
||||||
|
//
|
||||||
public OverloadResolver(JetTypeChecker typeChecker) {
|
// public OverloadResolver(JetTypeChecker typeChecker) {
|
||||||
this.typeChecker = typeChecker;
|
// this.typeChecker = typeChecker;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
public OverloadDomain getOverloadDomain(@Nullable JetType receiverType, @NotNull JetScope outerScope, @NotNull String name) {
|
// public OverloadDomain getOverloadDomain(@Nullable JetType receiverType, @NotNull JetScope outerScope, @NotNull String name) {
|
||||||
// TODO : extension lookup
|
// // TODO : extension lookup
|
||||||
JetScope scope = receiverType == null ? outerScope : new ScopeWithReceiver(outerScope, receiverType, typeChecker);
|
// JetScope scope = receiverType == null ? outerScope : new ScopeWithReceiver(outerScope, receiverType, typeChecker);
|
||||||
|
//
|
||||||
final FunctionGroup functionGroup = scope.getFunctionGroup(name);
|
// final FunctionGroup functionGroup = scope.getFunctionGroup(name);
|
||||||
|
//
|
||||||
return getOverloadDomain(receiverType, functionGroup);
|
// return getOverloadDomain(receiverType, functionGroup);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
public OverloadDomain getOverloadDomain(@Nullable final JetType receiverType, @NotNull final FunctionGroup functionGroup) {
|
// public OverloadDomain getOverloadDomain(@Nullable final JetType receiverType, @NotNull final FunctionGroup functionGroup) {
|
||||||
if (functionGroup.isEmpty()) {
|
// if (functionGroup.isEmpty()) {
|
||||||
return OverloadDomain.EMPTY;
|
// return OverloadDomain.EMPTY;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return new OverloadDomain() {
|
// return new OverloadDomain() {
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull final List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
|
// public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull final List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
|
||||||
OverloadResolutionResult resolutionResult = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes);
|
// OverloadResolutionResult resolutionResult = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes);
|
||||||
if (!resolutionResult.isAmbiguity() && !resolutionResult.isSuccess()) return resolutionResult;
|
// if (!resolutionResult.isAmbiguity() && !resolutionResult.isSuccess()) return resolutionResult;
|
||||||
|
//
|
||||||
Collection<FunctionDescriptor> possiblyApplicableFunctions = resolutionResult.getFunctionDescriptors();
|
// Collection<FunctionDescriptor> possiblyApplicableFunctions = resolutionResult.getFunctionDescriptors();
|
||||||
|
//
|
||||||
if (possiblyApplicableFunctions.isEmpty()) {
|
// if (possiblyApplicableFunctions.isEmpty()) {
|
||||||
return OverloadResolutionResult.nameNotFound(); // TODO : it may be found, only the number of params did not match
|
// return OverloadResolutionResult.nameNotFound(); // TODO : it may be found, only the number of params did not match
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
List<FunctionDescriptor> applicable = new ArrayList<FunctionDescriptor>();
|
// List<FunctionDescriptor> applicable = new ArrayList<FunctionDescriptor>();
|
||||||
|
//
|
||||||
descLoop:
|
// descLoop:
|
||||||
for (FunctionDescriptor descriptor : possiblyApplicableFunctions) {
|
// for (FunctionDescriptor descriptor : possiblyApplicableFunctions) {
|
||||||
// ASSERT: type arguments are figured out and substituted by this time!!!
|
// // ASSERT: type arguments are figured out and substituted by this time!!!
|
||||||
assert descriptor.getTypeParameters().isEmpty();
|
// assert descriptor.getTypeParameters().isEmpty();
|
||||||
|
//
|
||||||
if (receiverType != null) {
|
// if (receiverType != null) {
|
||||||
// ASSERT : either the receiver in not present or we are in a scope with no top-level functions
|
// // ASSERT : either the receiver in not present or we are in a scope with no top-level functions
|
||||||
JetType functionReceiverType = descriptor.getReceiverType();
|
// JetType functionReceiverType = descriptor.getReceiverType();
|
||||||
if (functionReceiverType != null) {
|
// if (functionReceiverType != null) {
|
||||||
functionReceiverType = TypeUtils.makeNullable(functionReceiverType); // Too look things up in T for T?, and later check receiver's nullability
|
// functionReceiverType = TypeUtils.makeNullable(functionReceiverType); // Too look things up in T for T?, and later check receiver's nullability
|
||||||
if (!typeChecker.isSubtypeOf(receiverType, functionReceiverType)) {
|
// if (!typeChecker.isSubtypeOf(receiverType, functionReceiverType)) {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else if (descriptor.getReceiverType() != null) {
|
// else if (descriptor.getReceiverType() != null) {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
|
// List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
|
||||||
if (parameters.size() >= positionedValueArgumentTypes.size()) {
|
// if (parameters.size() >= positionedValueArgumentTypes.size()) {
|
||||||
// possibly, some default values
|
// // possibly, some default values
|
||||||
// possibly, nothing passed to a vararg
|
// // possibly, nothing passed to a vararg
|
||||||
// possibly, a single value passed to a vararg
|
// // possibly, a single value passed to a vararg
|
||||||
// possibly an array/list/etc passed as a whole vararg
|
// // possibly an array/list/etc passed as a whole vararg
|
||||||
for (int i = 0, positionedValueArgumentTypesSize = positionedValueArgumentTypes.size(); i < positionedValueArgumentTypesSize; i++) {
|
// for (int i = 0, positionedValueArgumentTypesSize = positionedValueArgumentTypes.size(); i < positionedValueArgumentTypesSize; i++) {
|
||||||
JetType argumentType = positionedValueArgumentTypes.get(i);
|
// JetType argumentType = positionedValueArgumentTypes.get(i);
|
||||||
JetType parameterType = parameters.get(i).getOutType();
|
// JetType parameterType = parameters.get(i).getOutType();
|
||||||
// TODO : handle vararg cases here
|
// // TODO : handle vararg cases here
|
||||||
if (!typeChecker.isConvertibleTo(argumentType, parameterType)) {
|
// if (!typeChecker.isConvertibleTo(argumentType, parameterType)) {
|
||||||
continue descLoop;
|
// continue descLoop;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
// vararg
|
// // vararg
|
||||||
int nonVarargs = parameters.size() - 1;
|
// int nonVarargs = parameters.size() - 1;
|
||||||
for (int i = 0; i < nonVarargs; i++) {
|
// for (int i = 0; i < nonVarargs; i++) {
|
||||||
JetType argumentType = positionedValueArgumentTypes.get(i);
|
// JetType argumentType = positionedValueArgumentTypes.get(i);
|
||||||
JetType parameterType = parameters.get(i).getOutType();
|
// JetType parameterType = parameters.get(i).getOutType();
|
||||||
if (!typeChecker.isConvertibleTo(argumentType, parameterType)) {
|
// if (!typeChecker.isConvertibleTo(argumentType, parameterType)) {
|
||||||
continue descLoop;
|
// continue descLoop;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
JetType varArgType = parameters.get(nonVarargs).getOutType();
|
// JetType varArgType = parameters.get(nonVarargs).getOutType();
|
||||||
for (int i = nonVarargs, args = positionedValueArgumentTypes.size(); i < args; i++) {
|
// for (int i = nonVarargs, args = positionedValueArgumentTypes.size(); i < args; i++) {
|
||||||
JetType argumentType = positionedValueArgumentTypes.get(i);
|
// JetType argumentType = positionedValueArgumentTypes.get(i);
|
||||||
if (!typeChecker.isConvertibleTo(argumentType, varArgType)) {
|
// if (!typeChecker.isConvertibleTo(argumentType, varArgType)) {
|
||||||
continue descLoop;
|
// continue descLoop;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
applicable.add(descriptor);
|
// applicable.add(descriptor);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (applicable.size() == 0) {
|
// if (applicable.size() == 0) {
|
||||||
if (resolutionResult.singleFunction()) {
|
// if (resolutionResult.singleFunction()) {
|
||||||
return OverloadResolutionResult.singleFunctionArgumentMismatch(resolutionResult.getFunctionDescriptor());
|
// return OverloadResolutionResult.singleFunctionArgumentMismatch(resolutionResult.getFunctionDescriptor());
|
||||||
}
|
// }
|
||||||
return OverloadResolutionResult.nameNotFound();
|
// return OverloadResolutionResult.nameNotFound();
|
||||||
} else if (applicable.size() == 1) {
|
// } else if (applicable.size() == 1) {
|
||||||
return OverloadResolutionResult.success(applicable.get(0));
|
// return OverloadResolutionResult.success(applicable.get(0));
|
||||||
} else {
|
// } else {
|
||||||
// TODO : varargs
|
// // TODO : varargs
|
||||||
|
//
|
||||||
List<FunctionDescriptor> maximallySpecific = new ArrayList<FunctionDescriptor>();
|
// List<FunctionDescriptor> maximallySpecific = new ArrayList<FunctionDescriptor>();
|
||||||
meLoop:
|
// meLoop:
|
||||||
for (FunctionDescriptor me : applicable) {
|
// for (FunctionDescriptor me : applicable) {
|
||||||
for (FunctionDescriptor other : applicable) {
|
// for (FunctionDescriptor other : applicable) {
|
||||||
if (other == me) continue;
|
// if (other == me) continue;
|
||||||
if (!moreSpecific(me, other) || moreSpecific(other, me)) continue meLoop;
|
// if (!moreSpecific(me, other) || moreSpecific(other, me)) continue meLoop;
|
||||||
}
|
// }
|
||||||
maximallySpecific.add(me);
|
// maximallySpecific.add(me);
|
||||||
}
|
// }
|
||||||
if (maximallySpecific.isEmpty()) {
|
// if (maximallySpecific.isEmpty()) {
|
||||||
return OverloadResolutionResult.ambiguity(applicable);
|
// return OverloadResolutionResult.ambiguity(applicable);
|
||||||
}
|
// }
|
||||||
if (maximallySpecific.size() == 1) {
|
// if (maximallySpecific.size() == 1) {
|
||||||
return OverloadResolutionResult.success(maximallySpecific.get(0));
|
// return OverloadResolutionResult.success(maximallySpecific.get(0));
|
||||||
}
|
// }
|
||||||
throw new UnsupportedOperationException();
|
// throw new UnsupportedOperationException();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean isEmpty() {
|
// public boolean isEmpty() {
|
||||||
return functionGroup.isEmpty();
|
// return functionGroup.isEmpty();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NotNull
|
// @NotNull
|
||||||
@Override
|
// @Override
|
||||||
public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
|
// public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
// throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private boolean moreSpecific(FunctionDescriptor f, FunctionDescriptor g) {
|
// private boolean moreSpecific(FunctionDescriptor f, FunctionDescriptor g) {
|
||||||
List<ValueParameterDescriptor> fParams = f.getValueParameters();
|
// List<ValueParameterDescriptor> fParams = f.getValueParameters();
|
||||||
List<ValueParameterDescriptor> gParams = g.getValueParameters();
|
// List<ValueParameterDescriptor> gParams = g.getValueParameters();
|
||||||
|
//
|
||||||
int fSize = fParams.size();
|
// int fSize = fParams.size();
|
||||||
if (fSize != gParams.size()) return false;
|
// if (fSize != gParams.size()) return false;
|
||||||
for (int i = 0; i < fSize; i++) {
|
// for (int i = 0; i < fSize; i++) {
|
||||||
JetType fParamType = fParams.get(i).getOutType();
|
// JetType fParamType = fParams.get(i).getOutType();
|
||||||
JetType gParamType = gParams.get(i).getOutType();
|
// JetType gParamType = gParams.get(i).getOutType();
|
||||||
|
//
|
||||||
// TODO : maybe isSubtypeOf is sufficient?
|
// // TODO : maybe isSubtypeOf is sufficient?
|
||||||
if (!typeChecker.isConvertibleTo(fParamType, gParamType)) {
|
// if (!typeChecker.isConvertibleTo(fParamType, gParamType)) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -94,7 +94,9 @@ public class SubstitutingScope implements JetScope {
|
|||||||
if (allDescriptors == null) {
|
if (allDescriptors == null) {
|
||||||
allDescriptors = Sets.newHashSet();
|
allDescriptors = Sets.newHashSet();
|
||||||
for (DeclarationDescriptor descriptor : workerScope.getAllDescriptors()) {
|
for (DeclarationDescriptor descriptor : workerScope.getAllDescriptors()) {
|
||||||
allDescriptors.add(descriptor.substitute(substitutor));
|
DeclarationDescriptor substitute = descriptor.substitute(substitutor);
|
||||||
|
assert substitute != null;
|
||||||
|
allDescriptors.add(substitute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allDescriptors;
|
return allDescriptors;
|
||||||
|
|||||||
@@ -11,15 +11,14 @@ import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
|||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.util.WritableSlice;
|
import org.jetbrains.jet.util.WritableSlice;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
@@ -568,7 +567,7 @@ public class TopDownAnalyzer {
|
|||||||
JetExpression delegateExpression = specifier.getDelegateExpression();
|
JetExpression delegateExpression = specifier.getDelegateExpression();
|
||||||
if (delegateExpression != null) {
|
if (delegateExpression != null) {
|
||||||
JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor;
|
JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor;
|
||||||
JetType type = typeInferrer.getType(scope, delegateExpression, false, JetTypeInferrer.NO_EXPECTED_TYPE);
|
JetType type = typeInferrer.getType(scope, delegateExpression, false, NO_EXPECTED_TYPE);
|
||||||
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||||
if (type != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) { // TODO : Convertible?
|
if (type != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) { // TODO : Convertible?
|
||||||
trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type);
|
trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type);
|
||||||
@@ -581,7 +580,7 @@ public class TopDownAnalyzer {
|
|||||||
JetTypeReference typeReference = call.getTypeReference();
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||||
typeInferrer.checkTypeInitializerCall(scopeForConstructor, typeReference, call);
|
typeInferrer.getCallResolver().resolveCall(scopeForConstructor, call, NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||||
@@ -644,7 +643,7 @@ public class TopDownAnalyzer {
|
|||||||
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
||||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||||
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true, JetTypeInferrer.NO_EXPECTED_TYPE);
|
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true, NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -686,7 +685,7 @@ public class TopDownAnalyzer {
|
|||||||
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
||||||
JetTypeReference typeReference = call.getTypeReference();
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
typeInferrerForInitializers.checkTypeInitializerCall(functionInnerScope, typeReference, call);
|
typeInferrerForInitializers.getCallResolver().resolveCall(functionInnerScope, call, NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,13 +693,14 @@ public class TopDownAnalyzer {
|
|||||||
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
||||||
// TODO : check that there's no recursion in this() calls
|
// TODO : check that there's no recursion in this() calls
|
||||||
// TODO : check: if a this() call is present, no other initializers are allowed
|
// TODO : check: if a this() call is present, no other initializers are allowed
|
||||||
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
// ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||||
typeInferrerForInitializers.checkClassConstructorCall(
|
// typeInferrerForInitializers.checkClassConstructorCall(
|
||||||
functionInnerScope,
|
// functionInnerScope,
|
||||||
call.getThisReference(),
|
// call.getThisReference(),
|
||||||
classDescriptor,
|
// classDescriptor,
|
||||||
classDescriptor.getDefaultType(),
|
// classDescriptor.getDefaultType(),
|
||||||
call);
|
// call);
|
||||||
|
trace.getErrorHandler().genericError(call.getNode(), "this-calls are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -859,7 +859,7 @@ public class TopDownAnalyzer {
|
|||||||
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
|
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
|
||||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(property, initializer); // TODO : flow JET-15
|
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(property, initializer); // TODO : flow JET-15
|
||||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
||||||
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, false, JetTypeInferrer.NO_EXPECTED_TYPE);
|
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, false, NO_EXPECTED_TYPE);
|
||||||
|
|
||||||
JetType expectedType;
|
JetType expectedType;
|
||||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class CallMaker {
|
||||||
|
|
||||||
|
private static class ExpressionValueArgument implements ValueArgument {
|
||||||
|
|
||||||
|
private final JetExpression expression;
|
||||||
|
|
||||||
|
private ExpressionValueArgument(JetExpression expression) {
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetExpression getArgumentExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetValueArgumentName getArgumentName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNamed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOut() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRef() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public PsiElement asElement() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static abstract class CallStub implements Call {
|
||||||
|
@Override
|
||||||
|
public JetValueArgumentList getValueArgumentList() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<JetExpression> getFunctionLiteralArguments() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<JetTypeProjection> getTypeArguments() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetTypeArgumentList getTypeArgumentList() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Call makeCallWithArguments(final JetExpression calleeExpression, final List<? extends ValueArgument> valueArguments) {
|
||||||
|
return new CallStub() {
|
||||||
|
@Override
|
||||||
|
public JetExpression getCalleeExpression() {
|
||||||
|
return calleeExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<? extends ValueArgument> getValueArguments() {
|
||||||
|
return valueArguments;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Call makeCall(final JetExpression calleeExpression, final List<JetExpression> argumentExpressions) {
|
||||||
|
List<ExpressionValueArgument> arguments = Lists.newArrayList();
|
||||||
|
for (JetExpression argumentExpression : argumentExpressions) {
|
||||||
|
arguments.add(new ExpressionValueArgument(argumentExpression));
|
||||||
|
}
|
||||||
|
return makeCallWithArguments(calleeExpression, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Call makeCall(final JetBinaryExpression expression) {
|
||||||
|
return makeCall(expression.getOperationReference(), Collections.singletonList(expression.getRight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Call makeCall(final JetUnaryExpression expression) {
|
||||||
|
return makeCallWithArguments(expression.getOperationSign(), Collections.<ValueArgument>emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Call makeCall(final JetArrayAccessExpression arrayAccessExpression, final JetExpression rightHandSide) {
|
||||||
|
List<JetExpression> arguments = Lists.newArrayList(arrayAccessExpression.getIndexExpressions());
|
||||||
|
arguments.add(rightHandSide);
|
||||||
|
return makeCall(arrayAccessExpression, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,515 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
|
import org.jetbrains.jet.lang.types.inference.ConstraintSystem;
|
||||||
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||||
|
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class CallResolver {
|
||||||
|
|
||||||
|
private static abstract class ResolutionTask {
|
||||||
|
private final Collection<FunctionDescriptor> candidates;
|
||||||
|
private final JetExpression receiver;
|
||||||
|
private final List<JetTypeProjection> typeArguments;
|
||||||
|
private final List<? extends ValueArgument> valueArguments;
|
||||||
|
|
||||||
|
protected ResolutionTask(
|
||||||
|
@NotNull Collection<FunctionDescriptor> candidates,
|
||||||
|
@Nullable JetExpression receiver,
|
||||||
|
@NotNull List<JetTypeProjection> typeArguments,
|
||||||
|
@NotNull List<? extends ValueArgument> valueArguments) {
|
||||||
|
this.candidates = candidates;
|
||||||
|
this.receiver = receiver;
|
||||||
|
this.typeArguments = typeArguments;
|
||||||
|
this.valueArguments = valueArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Collection<FunctionDescriptor> getCandidates() {
|
||||||
|
return candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JetExpression getReceiver() {
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<JetTypeProjection> getTypeArguments() {
|
||||||
|
return typeArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<? extends ValueArgument> getValueArguments() {
|
||||||
|
return valueArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void bindFunctionReference(@NotNull BindingTrace trace, @NotNull FunctionDescriptor functionDescriptor);
|
||||||
|
|
||||||
|
public abstract void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message);
|
||||||
|
|
||||||
|
public abstract void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message);
|
||||||
|
|
||||||
|
public abstract void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message);
|
||||||
|
|
||||||
|
public abstract void reportUnresolvedFunctionReference(@NotNull BindingTrace trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BindingTrace trace;
|
||||||
|
private final TypeResolver typeResolver;
|
||||||
|
private final JetTypeInferrer typeInferrer;
|
||||||
|
private final JetSemanticServices semanticServices;
|
||||||
|
private final ClassDescriptorResolver classDescriptorResolver;
|
||||||
|
|
||||||
|
public CallResolver(JetSemanticServices semanticServices, BindingTrace trace, JetTypeInferrer typeInferrer) {
|
||||||
|
this.trace = trace;
|
||||||
|
this.typeInferrer = typeInferrer;
|
||||||
|
this.typeResolver = new TypeResolver(semanticServices, trace, true);
|
||||||
|
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
||||||
|
this.semanticServices = semanticServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JetType resolveCall(
|
||||||
|
@NotNull JetScope scope,
|
||||||
|
@NotNull JetCallElement call,
|
||||||
|
@NotNull JetType expectedType
|
||||||
|
) {
|
||||||
|
FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(scope, null, call, expectedType);
|
||||||
|
return functionDescriptor == null ? null : functionDescriptor.getReturnType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public FunctionDescriptor resolveCallWithGivenName(
|
||||||
|
@NotNull JetScope scope,
|
||||||
|
@NotNull final Call call,
|
||||||
|
@NotNull final JetReferenceExpression functionReference,
|
||||||
|
@NotNull String name,
|
||||||
|
@Nullable JetExpression receiver,
|
||||||
|
@NotNull JetType expectedType) {
|
||||||
|
Collection<FunctionDescriptor> candidates;
|
||||||
|
if (receiver != null) {
|
||||||
|
JetType type = typeInferrer.getServices(trace).getType(scope, receiver, false, NO_EXPECTED_TYPE);
|
||||||
|
if (type == null) {
|
||||||
|
return null; // TODO : check parameter types anyway?
|
||||||
|
}
|
||||||
|
// TODO : autocasts
|
||||||
|
// TODO : nullability
|
||||||
|
candidates = type.getMemberScope().getFunctionGroup(name).getFunctionDescriptors();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
candidates = scope.getFunctionGroup(name).getFunctionDescriptors();
|
||||||
|
}
|
||||||
|
return resolveCallToFunctionDescriptor(scope, receiver, call, functionReference.getNode(), expectedType, candidates, functionReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public FunctionDescriptor resolveSimpleCallToFunctionDescriptor(
|
||||||
|
@NotNull JetScope scope,
|
||||||
|
@Nullable JetExpression receiver,
|
||||||
|
@NotNull final JetCallElement call,
|
||||||
|
@NotNull JetType expectedType
|
||||||
|
) {
|
||||||
|
JetExpression calleeExpression = call.getCalleeExpression();
|
||||||
|
Collection<FunctionDescriptor> candidates;
|
||||||
|
final JetReferenceExpression functionReference;
|
||||||
|
if (calleeExpression instanceof JetSimpleNameExpression) {
|
||||||
|
JetSimpleNameExpression expression = (JetSimpleNameExpression) calleeExpression;
|
||||||
|
functionReference = expression;
|
||||||
|
candidates = scope.getFunctionGroup(expression.getReferencedName()).getFunctionDescriptors();
|
||||||
|
}
|
||||||
|
else if (calleeExpression instanceof JetConstructorCalleeExpression) {
|
||||||
|
JetConstructorCalleeExpression expression = (JetConstructorCalleeExpression) calleeExpression;
|
||||||
|
functionReference = expression.getConstructorReferenceExpression();
|
||||||
|
JetType constructedType = typeResolver.resolveType(scope, expression.getTypeReference());
|
||||||
|
DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor();
|
||||||
|
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||||
|
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||||
|
candidates = classDescriptor.getConstructors().getFunctionDescriptors();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException("Type argument inference not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolveCallToFunctionDescriptor(scope, receiver, call, call.getNode(), expectedType, candidates, functionReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private FunctionDescriptor resolveCallToFunctionDescriptor(
|
||||||
|
JetScope scope,
|
||||||
|
final JetExpression receiver,
|
||||||
|
final Call call,
|
||||||
|
final ASTNode callNode,
|
||||||
|
JetType expectedType,
|
||||||
|
final Collection<FunctionDescriptor> candidates,
|
||||||
|
final JetReferenceExpression functionReference) {
|
||||||
|
ResolutionTask task = new ResolutionTask(candidates, receiver, call.getTypeArguments(), call.getValueArguments()) {
|
||||||
|
@Override
|
||||||
|
public void bindFunctionReference(@NotNull BindingTrace trace, @NotNull FunctionDescriptor functionDescriptor) {
|
||||||
|
trace.record(BindingContext.REFERENCE_TARGET, functionReference, functionDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message) {
|
||||||
|
trace.getErrorHandler().genericError(callNode, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportUnresolvedFunctionReference(@NotNull BindingTrace trace) {
|
||||||
|
trace.getErrorHandler().unresolvedReference(functionReference);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return performResolution(scope, expectedType, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private boolean mapValueArgumentsToParameters(
|
||||||
|
@NotNull ResolutionTask task,
|
||||||
|
@NotNull FunctionDescriptor candidate,
|
||||||
|
@NotNull BindingTrace temporaryTrace,
|
||||||
|
@NotNull Map<ValueArgument, ValueParameterDescriptor> argumentsToParameters
|
||||||
|
) {
|
||||||
|
Set<ValueParameterDescriptor> usedParameters = Sets.newHashSet();
|
||||||
|
|
||||||
|
List<ValueParameterDescriptor> valueParameters = candidate.getValueParameters();
|
||||||
|
Map<String, ValueParameterDescriptor> parameterByName = Maps.newHashMap();
|
||||||
|
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
||||||
|
parameterByName.put(valueParameter.getName(), valueParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<? extends ValueArgument> valueArguments = task.getValueArguments();
|
||||||
|
|
||||||
|
boolean someNamed = false;
|
||||||
|
boolean somePositioned = false;
|
||||||
|
boolean error = false;
|
||||||
|
for (int i = 0; i < valueArguments.size(); i++) {
|
||||||
|
ValueArgument valueArgument = valueArguments.get(i);
|
||||||
|
if (valueArgument.isNamed()) {
|
||||||
|
someNamed = true;
|
||||||
|
if (somePositioned) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.getArgumentName().getNode(), "Mixing named and positioned arguments in not allowed");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getName());
|
||||||
|
usedParameters.add(valueParameterDescriptor);
|
||||||
|
if (valueParameterDescriptor == null) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.getArgumentName().getNode(), "Cannot find a parameter with this name");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temporaryTrace.record(REFERENCE_TARGET, valueArgument.getArgumentName().getReferenceExpression(), valueParameterDescriptor);
|
||||||
|
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
somePositioned = true;
|
||||||
|
if (someNamed) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (i < valueParameters.size()) {
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(i);
|
||||||
|
usedParameters.add(valueParameterDescriptor);
|
||||||
|
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
else if (!valueParameters.isEmpty()) {
|
||||||
|
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||||
|
if (valueParameterDescriptor.isVararg()) {
|
||||||
|
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||||
|
usedParameters.add(valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Too many arguments");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Too many arguments");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
||||||
|
if (!usedParameters.contains(valueParameter)) {
|
||||||
|
if (!valueParameter.hasDefaultValue()) {
|
||||||
|
task.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private FunctionDescriptor performResolution(@NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task) {
|
||||||
|
Map<FunctionDescriptor, FunctionDescriptor> successfulCandidates = Maps.newHashMap();
|
||||||
|
Set<FunctionDescriptor> failedCandidates = Sets.newHashSet();
|
||||||
|
Map<FunctionDescriptor, ConstraintSystem.Solution> solutions = Maps.newHashMap();
|
||||||
|
Map<FunctionDescriptor, TemporaryBindingTrace> traces = Maps.newHashMap();
|
||||||
|
|
||||||
|
for (FunctionDescriptor candidate : task.getCandidates()) {
|
||||||
|
TemporaryBindingTrace temporaryTrace = new TemporaryBindingTrace(trace.getBindingContext());
|
||||||
|
traces.put(candidate, temporaryTrace);
|
||||||
|
JetTypeInferrer.Services temporaryServices = typeInferrer.getServices(temporaryTrace);
|
||||||
|
|
||||||
|
task.bindFunctionReference(temporaryTrace, candidate);
|
||||||
|
|
||||||
|
Map<ValueArgument, ValueParameterDescriptor> argumentsToParameters = Maps.newHashMap();
|
||||||
|
boolean error = mapValueArgumentsToParameters(task, candidate, temporaryTrace, argumentsToParameters);
|
||||||
|
|
||||||
|
if (error) continue;
|
||||||
|
|
||||||
|
if (task.getTypeArguments().isEmpty()) {
|
||||||
|
// Type argument inference
|
||||||
|
|
||||||
|
ConstraintSystem constraintSystem = new ConstraintSystem();
|
||||||
|
for (TypeParameterDescriptor typeParameterDescriptor : candidate.getTypeParameters()) {
|
||||||
|
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<ValueArgument, ValueParameterDescriptor> entry : argumentsToParameters.entrySet()) {
|
||||||
|
ValueArgument valueArgument = entry.getKey();
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = entry.getValue();
|
||||||
|
|
||||||
|
JetExpression expression = valueArgument.getArgumentExpression();
|
||||||
|
// TODO : more attempts, with different expected types
|
||||||
|
JetType type = temporaryServices.getType(scope, expression, false, NO_EXPECTED_TYPE);
|
||||||
|
if (type != null) {
|
||||||
|
constraintSystem.addSubtypingConstraint(type, valueParameterDescriptor.getOutType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedType != NO_EXPECTED_TYPE) {
|
||||||
|
constraintSystem.addSubtypingConstraint(candidate.getReturnType(), expectedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintSystem.Solution solution = constraintSystem.solve();
|
||||||
|
solutions.put(candidate, solution);
|
||||||
|
if (solution.isSuccessful()) {
|
||||||
|
FunctionDescriptor substitute = candidate.substitute(solution.getSubstitutor());
|
||||||
|
assert substitute != null;
|
||||||
|
successfulCandidates.put(candidate, substitute);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
task.reportOverallResolutionError(temporaryTrace, "Type inference failed");
|
||||||
|
failedCandidates.add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Explicit type arguments passed
|
||||||
|
|
||||||
|
final List<JetTypeProjection> jetTypeArguments = task.getTypeArguments();
|
||||||
|
|
||||||
|
for (JetTypeProjection typeArgument : jetTypeArguments) {
|
||||||
|
if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(typeArgument.getNode(), "Projections are not allowed on type parameters for methods"); // TODO : better positioning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<JetType> typeArguments = new ArrayList<JetType>();
|
||||||
|
for (JetTypeProjection projection : jetTypeArguments) {
|
||||||
|
// TODO : check that there's no projection
|
||||||
|
JetTypeReference typeReference = projection.getTypeReference();
|
||||||
|
if (typeReference != null) {
|
||||||
|
typeArguments.add(new TypeResolver(semanticServices, temporaryTrace, true).resolveType(scope, typeReference));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate);
|
||||||
|
|
||||||
|
int typeArgCount = typeArguments.size();
|
||||||
|
if (candidate.getTypeParameters().size() == typeArgCount) {
|
||||||
|
FunctionDescriptor substitutedFunctionDescriptor = FunctionDescriptorUtil.substituteFunctionDescriptor(typeArguments, candidate);
|
||||||
|
|
||||||
|
assert substitutedFunctionDescriptor != null;
|
||||||
|
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
||||||
|
for (ValueParameterDescriptor valueParameterDescriptor : substitutedFunctionDescriptor.getValueParameters()) {
|
||||||
|
parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean localError = false;
|
||||||
|
for (Map.Entry<ValueArgument, ValueParameterDescriptor> entry : argumentsToParameters.entrySet()) {
|
||||||
|
ValueArgument valueArgument = entry.getKey();
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = entry.getValue();
|
||||||
|
|
||||||
|
ValueParameterDescriptor substitutedParameter = parameterMap.get(valueParameterDescriptor.getOriginal());
|
||||||
|
|
||||||
|
assert substitutedParameter != null;
|
||||||
|
|
||||||
|
JetType parameterType = substitutedParameter.getOutType();
|
||||||
|
JetType type = temporaryServices.getType(scope, valueArgument.getArgumentExpression(), false, parameterType);
|
||||||
|
if (type == null) {
|
||||||
|
localError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (localError) {
|
||||||
|
failedCandidates.add(candidate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
successfulCandidates.put(candidate, substitutedFunctionDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
failedCandidates.add(candidate);
|
||||||
|
task.reportWrongTypeArguments(temporaryTrace, "Number of type arguments does not match " + DescriptorRenderer.TEXT.render(candidate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (successfulCandidates.size() > 0) {
|
||||||
|
if (successfulCandidates.size() == 1) {
|
||||||
|
Map.Entry<FunctionDescriptor, FunctionDescriptor> entry = successfulCandidates.entrySet().iterator().next();
|
||||||
|
FunctionDescriptor functionDescriptor = entry.getKey();
|
||||||
|
FunctionDescriptor result = entry.getValue();
|
||||||
|
|
||||||
|
TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor);
|
||||||
|
temporaryTrace.addAllMyDataTo(trace);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Map<FunctionDescriptor, TemporaryBindingTrace> maximallySpecific = Maps.newHashMap();
|
||||||
|
meLoop:
|
||||||
|
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> myEntry : successfulCandidates.entrySet()) {
|
||||||
|
FunctionDescriptor me = myEntry.getValue();
|
||||||
|
TemporaryBindingTrace myTrace = traces.get(myEntry.getKey());
|
||||||
|
for (FunctionDescriptor other : successfulCandidates.values()) {
|
||||||
|
if (other == me) continue;
|
||||||
|
if (!moreSpecific(me, other) || moreSpecific(other, me)) continue meLoop;
|
||||||
|
}
|
||||||
|
maximallySpecific.put(me, myTrace);
|
||||||
|
}
|
||||||
|
if (maximallySpecific.size() == 1) {
|
||||||
|
Map.Entry<FunctionDescriptor, TemporaryBindingTrace> result = maximallySpecific.entrySet().iterator().next();
|
||||||
|
result.getValue().addAllMyDataTo(trace);
|
||||||
|
return result.getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (FunctionDescriptor functionDescriptor : successfulCandidates.keySet()) {
|
||||||
|
stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
task.reportOverallResolutionError(trace, "Overload resolution ambiguity: " + stringBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!failedCandidates.isEmpty()) {
|
||||||
|
if (failedCandidates.size() == 1) {
|
||||||
|
FunctionDescriptor functionDescriptor = failedCandidates.iterator().next();
|
||||||
|
TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor);
|
||||||
|
temporaryTrace.addAllMyDataTo(trace);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (FunctionDescriptor functionDescriptor : failedCandidates) {
|
||||||
|
stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
task.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: " + stringBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
task.reportUnresolvedFunctionReference(trace);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean moreSpecific(FunctionDescriptor f, FunctionDescriptor g) {
|
||||||
|
List<ValueParameterDescriptor> fParams = f.getValueParameters();
|
||||||
|
List<ValueParameterDescriptor> gParams = g.getValueParameters();
|
||||||
|
|
||||||
|
int fSize = fParams.size();
|
||||||
|
if (fSize != gParams.size()) return false;
|
||||||
|
for (int i = 0; i < fSize; i++) {
|
||||||
|
JetType fParamType = fParams.get(i).getOutType();
|
||||||
|
JetType gParamType = gParams.get(i).getOutType();
|
||||||
|
|
||||||
|
if (!JetTypeChecker.INSTANCE.isSubtypeOf(fParamType, gParamType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkGenericBoundsInAFunctionCall(List<JetTypeProjection> jetTypeArguments, List<JetType> typeArguments, FunctionDescriptor functionDescriptor) {
|
||||||
|
Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
|
||||||
|
|
||||||
|
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
|
||||||
|
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
||||||
|
TypeParameterDescriptor typeParameter = typeParameters.get(i);
|
||||||
|
JetType typeArgument = typeArguments.get(i);
|
||||||
|
context.put(typeParameter.getTypeConstructor(), new TypeProjection(typeArgument));
|
||||||
|
}
|
||||||
|
TypeSubstitutor substitutor = TypeSubstitutor.create(context);
|
||||||
|
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||||
|
JetType typeArgument = typeArguments.get(i);
|
||||||
|
JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
|
||||||
|
assert typeReference != null;
|
||||||
|
classDescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public OverloadResolutionResult resolveExactSignature(@NotNull JetScope scope, @NotNull JetType receiver, @NotNull String name, @NotNull List<JetType> jetTypes) {
|
||||||
|
// TODO
|
||||||
|
return OverloadResolutionResult.nameNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -194,12 +194,12 @@ public class ConstraintSystem {
|
|||||||
private UnknownType getTypeVariable(TypeParameterDescriptor typeParameterDescriptor) {
|
private UnknownType getTypeVariable(TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
UnknownType unknownType = unknownTypes.get(typeParameterDescriptor);
|
UnknownType unknownType = unknownTypes.get(typeParameterDescriptor);
|
||||||
if (unknownType == null) {
|
if (unknownType == null) {
|
||||||
throw new IllegalArgumentException("This type parameter is not an unknown in this constraint system");
|
throw new IllegalArgumentException("This type parameter is not an unknown in this constraint system: " + typeParameterDescriptor);
|
||||||
}
|
}
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSubtypingConstraint(JetType lower, JetType upper) {
|
public void addSubtypingConstraint(@NotNull JetType lower, @NotNull JetType upper) {
|
||||||
TypeValue typeValueForLower = getTypeValueFor(lower);
|
TypeValue typeValueForLower = getTypeValueFor(lower);
|
||||||
TypeValue typeValueForUpper = getTypeValueFor(upper);
|
TypeValue typeValueForUpper = getTypeValueFor(upper);
|
||||||
addSubtypingConstraintOnTypeValues(typeValueForLower, typeValueForUpper);
|
addSubtypingConstraintOnTypeValues(typeValueForLower, typeValueForUpper);
|
||||||
|
|||||||
Reference in New Issue
Block a user