Very simple cases of function resolution are supported
This commit is contained in:
@@ -122,7 +122,8 @@ public class ClassDescriptorResolver {
|
|||||||
AttributeResolver.INSTANCE.resolveAttributes(valueParameter.getModifierList()),
|
AttributeResolver.INSTANCE.resolveAttributes(valueParameter.getModifierList()),
|
||||||
valueParameter.getName(),
|
valueParameter.getName(),
|
||||||
TypeResolver.INSTANCE.resolveType(parameterScope, typeReference),
|
TypeResolver.INSTANCE.resolveType(parameterScope, typeReference),
|
||||||
valueParameter.getDefaultValue() != null
|
valueParameter.getDefaultValue() != null,
|
||||||
|
false // TODO : varargs
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO : Default values???
|
// TODO : Default values???
|
||||||
|
|||||||
@@ -29,5 +29,5 @@ public interface JetScope {
|
|||||||
Type getThisType();
|
Type getThisType();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
OverloadDomain getOverloadDomain(Type receiverType, String referencedName);
|
OverloadDomain getOverloadDomain(@Nullable Type receiverType, @NotNull String referencedName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class JetScopeAdapter implements JetScope {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
|
||||||
return scope.getOverloadDomain(receiverType, referencedName);
|
return scope.getOverloadDomain(receiverType, referencedName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public abstract class JetScopeImpl implements JetScope {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
|
||||||
return OverloadDomain.EMPTY;
|
return receiverType.getMemberScope().getOverloadDomain(null, referencedName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ public class SubstitutingScope implements JetScope {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
final OverloadDomain workerDomain = workerScope.getOverloadDomain(receiverType, referencedName);
|
||||||
|
// TODO: !!!
|
||||||
|
return workerDomain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class WritableFunctionGroup implements FunctionGroup {
|
|||||||
|
|
||||||
private FunctionDescriptor substituteFunctionDescriptor(List<Type> typeArguments, FunctionDescriptor functionDescriptor) {
|
private FunctionDescriptor substituteFunctionDescriptor(List<Type> typeArguments, FunctionDescriptor functionDescriptor) {
|
||||||
return new FunctionDescriptor(
|
return new FunctionDescriptor(
|
||||||
// TODO : substitute
|
// TODO : substitute
|
||||||
functionDescriptor.getAttributes(),
|
functionDescriptor.getAttributes(),
|
||||||
functionDescriptor.getName(),
|
functionDescriptor.getName(),
|
||||||
Collections.<TypeParameterDescriptor>emptyList(), // TODO : questionable
|
Collections.<TypeParameterDescriptor>emptyList(), // TODO : questionable
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -71,7 +68,7 @@ public class WritableScope implements JetScope {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
|
||||||
final FunctionGroup functionGroup = getFunctionGroups().get(referencedName);
|
final FunctionGroup functionGroup = getFunctionGroups().get(referencedName);
|
||||||
if (functionGroup == null) {
|
if (functionGroup == null) {
|
||||||
return OverloadDomain.EMPTY;
|
return OverloadDomain.EMPTY;
|
||||||
@@ -85,7 +82,55 @@ public class WritableScope implements JetScope {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException();
|
List<FunctionDescriptor> applicable = new ArrayList<FunctionDescriptor>();
|
||||||
|
|
||||||
|
descLoop:
|
||||||
|
for (FunctionDescriptor descriptor : possiblyApplicableFunctions) {
|
||||||
|
// ASSERT: type arguments are figured out and substituted by this time!!!
|
||||||
|
assert descriptor.getTypeParameters().isEmpty();
|
||||||
|
|
||||||
|
List<ValueParameterDescriptor> parameters = descriptor.getUnsubstitutedValueParameters();
|
||||||
|
if (parameters.size() >= positionedValueArgumentTypes.size()) {
|
||||||
|
// possibly, some default values
|
||||||
|
// possibly, nothing passed to a vararg
|
||||||
|
// possibly, a single value passed to a vararg
|
||||||
|
// possibly an array/list/etc passed as a whole vararg
|
||||||
|
for (int i = 0, positionedValueArgumentTypesSize = positionedValueArgumentTypes.size(); i < positionedValueArgumentTypesSize; i++) {
|
||||||
|
Type argumentType = positionedValueArgumentTypes.get(i);
|
||||||
|
Type parameterType = parameters.get(i).getType();
|
||||||
|
// TODO : handle vararg cases here
|
||||||
|
if (!JetTypeChecker.INSTANCE.isConvertibleTo(argumentType, parameterType)) {
|
||||||
|
continue descLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// vararg
|
||||||
|
int nonVarargs = parameters.size() - 1;
|
||||||
|
for (int i = 0; i < nonVarargs; i++) {
|
||||||
|
Type argumentType = positionedValueArgumentTypes.get(i);
|
||||||
|
Type parameterType = parameters.get(i).getType();
|
||||||
|
if (!JetTypeChecker.INSTANCE.isConvertibleTo(argumentType, parameterType)) {
|
||||||
|
continue descLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Type varArgType = parameters.get(nonVarargs).getType();
|
||||||
|
for (int i = nonVarargs, args = positionedValueArgumentTypes.size(); i < args; i++) {
|
||||||
|
Type argumentType = positionedValueArgumentTypes.get(i);
|
||||||
|
if (!JetTypeChecker.INSTANCE.isConvertibleTo(argumentType, varArgType)) {
|
||||||
|
continue descLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
applicable.add(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (applicable.size() == 0) {
|
||||||
|
return null;
|
||||||
|
} else if (applicable.size() == 1) {
|
||||||
|
return applicable.get(0).getUnsubstitutedReturnType();
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class ErrorType {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -84,7 +83,8 @@ public class FunctionDescriptor extends MemberDescriptorImpl {
|
|||||||
unsubstitutedValueParameter.getAttributes(),
|
unsubstitutedValueParameter.getAttributes(),
|
||||||
unsubstitutedValueParameter.getName(),
|
unsubstitutedValueParameter.getName(),
|
||||||
TypeSubstitutor.INSTANCE.substitute(context, unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE),
|
TypeSubstitutor.INSTANCE.substitute(context, unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE),
|
||||||
unsubstitutedValueParameter.hasDefaultValue()
|
unsubstitutedValueParameter.hasDefaultValue(),
|
||||||
|
unsubstitutedValueParameter.isVararg()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -303,13 +303,24 @@ public class JetTypeChecker {
|
|||||||
|
|
||||||
// result[0] = overloadDomain.getReturnTypeForNamedArguments(typeArguments, valueArguments, functionLiteralArgument);
|
// result[0] = overloadDomain.getReturnTypeForNamedArguments(typeArguments, valueArguments, functionLiteralArgument);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
List<JetExpression> positionedValueArguments = new ArrayList<JetExpression>();
|
||||||
// List<JetExpression> positionedValueArguments = new ArrayList<JetExpression>();
|
for (JetArgument argument : valueArguments) {
|
||||||
// for (JetArgument argument : valueArguments) {
|
positionedValueArguments.add(argument.getArgumentExpression());
|
||||||
// positionedValueArguments.add(argument.getArgumentExpression());
|
}
|
||||||
// }
|
positionedValueArguments.addAll(functionLiteralArguments);
|
||||||
// positionedValueArguments.addAll(functionLiteralArguments);
|
|
||||||
// result[0] = overloadDomain.getReturnTypeForPositionedArguments(typeArguments, positionedValueArguments);
|
List<Type> types = new ArrayList<Type>();
|
||||||
|
for (JetTypeProjection projection : typeArguments) {
|
||||||
|
// TODO : check that there's no projection
|
||||||
|
types.add(TypeResolver.INSTANCE.resolveType(scope, projection.getTypeReference()));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Type> valueArgumentTypes = new ArrayList<Type>();
|
||||||
|
for (JetExpression valueArgument : positionedValueArguments) {
|
||||||
|
valueArgumentTypes.add(getType(scope, valueArgument, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
result[0] = overloadDomain.getReturnTypeForPositionedArguments(types, valueArgumentTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,6 +633,11 @@ public class JetTypeChecker {
|
|||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isConvertibleTo(Type actual, Type expected) {
|
||||||
|
// TODO
|
||||||
|
return isSubtypeOf(actual, expected);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
||||||
if (!supertype.isNullable() && subtype.isNullable()) {
|
if (!supertype.isNullable() && subtype.isNullable()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl implements ValueParameterDescriptor {
|
public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl implements ValueParameterDescriptor {
|
||||||
private final boolean hasDefaultValue;
|
private final boolean hasDefaultValue;
|
||||||
|
private final boolean isVararg;
|
||||||
|
|
||||||
public ValueParameterDescriptorImpl(List<Attribute> attributes, String name, Type type, boolean hasDefaultValue) {
|
public ValueParameterDescriptorImpl(List<Attribute> attributes, String name, Type type, boolean hasDefaultValue, boolean isVararg) {
|
||||||
super(attributes, name, type);
|
super(attributes, name, type);
|
||||||
this.hasDefaultValue = hasDefaultValue;
|
this.hasDefaultValue = hasDefaultValue;
|
||||||
|
this.isVararg = isVararg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -25,6 +27,6 @@ public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isVararg() {
|
public boolean isVararg() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
return isVararg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,7 +320,9 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
public void testOverloads() throws Exception {
|
public void testOverloads() throws Exception {
|
||||||
assertType("new Functions<String>().f()", "Unit");
|
assertType("new Functions<String>().f()", "Unit");
|
||||||
assertType("new Functions<String>().f(1)", "Int");
|
assertType("new Functions<String>().f(1)", "Int");
|
||||||
assertType("new Functions<String>().f(1d)", "Any");
|
assertType("new Functions<String>().f(1d)", (String) null);
|
||||||
|
assertType("new Functions<Double>().f(())", "Double");
|
||||||
|
assertType("new Functions<Double>().f(1d)", "Any");
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void testImplicitConversions() throws Exception {
|
// public void testImplicitConversions() throws Exception {
|
||||||
@@ -402,8 +404,8 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
Project project = getProject();
|
Project project = getProject();
|
||||||
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||||
Type type = JetTypeChecker.INSTANCE.getType(scope, jetExpression, false);
|
Type type = JetTypeChecker.INSTANCE.getType(scope, jetExpression, false);
|
||||||
Type expectedType = makeType(expectedTypeStr);
|
Type expectedType = expectedTypeStr == null ? null : makeType(expectedTypeStr);
|
||||||
assertTrue(type + " != " + expectedType, TypeImpl.equalTypes(type, expectedType));
|
assertEquals(expectedType, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Type makeType(String typeStr) {
|
private static Type makeType(String typeStr) {
|
||||||
@@ -431,6 +433,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
"fun f() : Unit {} " +
|
"fun f() : Unit {} " +
|
||||||
"fun f(a : Int) : Int {} " +
|
"fun f(a : Int) : Int {} " +
|
||||||
"fun f(a : T) : Any {} " +
|
"fun f(a : T) : Any {} " +
|
||||||
|
"fun f(a : Unit) : T {} " +
|
||||||
"}"
|
"}"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user