Very simple cases of function resolution are supported

This commit is contained in:
Andrey Breslav
2011-02-21 15:30:55 +03:00
parent 986e703fad
commit 0dd7118678
12 changed files with 98 additions and 29 deletions
@@ -122,7 +122,8 @@ public class ClassDescriptorResolver {
AttributeResolver.INSTANCE.resolveAttributes(valueParameter.getModifierList()),
valueParameter.getName(),
TypeResolver.INSTANCE.resolveType(parameterScope, typeReference),
valueParameter.getDefaultValue() != null
valueParameter.getDefaultValue() != null,
false // TODO : varargs
);
// TODO : Default values???
@@ -29,5 +29,5 @@ public interface JetScope {
Type getThisType();
@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
@Override
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
return scope.getOverloadDomain(receiverType, referencedName);
}
}
@@ -40,7 +40,7 @@ public abstract class JetScopeImpl implements JetScope {
@NotNull
@Override
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
return OverloadDomain.EMPTY;
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
return receiverType.getMemberScope().getOverloadDomain(null, referencedName);
}
}
@@ -55,7 +55,9 @@ public class SubstitutingScope implements JetScope {
@NotNull
@Override
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
throw new UnsupportedOperationException(); // TODO
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
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) {
return new FunctionDescriptor(
// TODO : substitute
// TODO : substitute
functionDescriptor.getAttributes(),
functionDescriptor.getName(),
Collections.<TypeParameterDescriptor>emptyList(), // TODO : questionable
@@ -4,10 +4,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.types.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* @author abreslav
@@ -71,7 +68,7 @@ public class WritableScope implements JetScope {
@NotNull
@Override
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
final FunctionGroup functionGroup = getFunctionGroups().get(referencedName);
if (functionGroup == null) {
return OverloadDomain.EMPTY;
@@ -85,7 +82,55 @@ public class WritableScope implements JetScope {
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
@@ -45,7 +45,7 @@ public class ErrorType {
@NotNull
@Override
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
public OverloadDomain getOverloadDomain(Type receiverType, @NotNull String referencedName) {
throw new UnsupportedOperationException(); // TODO
}
};
@@ -1,7 +1,6 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import java.util.ArrayList;
import java.util.HashMap;
@@ -84,7 +83,8 @@ public class FunctionDescriptor extends MemberDescriptorImpl {
unsubstitutedValueParameter.getAttributes(),
unsubstitutedValueParameter.getName(),
TypeSubstitutor.INSTANCE.substitute(context, unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE),
unsubstitutedValueParameter.hasDefaultValue()
unsubstitutedValueParameter.hasDefaultValue(),
unsubstitutedValueParameter.isVararg()
));
}
return result;
@@ -303,13 +303,24 @@ public class JetTypeChecker {
// result[0] = overloadDomain.getReturnTypeForNamedArguments(typeArguments, valueArguments, functionLiteralArgument);
} else {
throw new UnsupportedOperationException(); // TODO
// List<JetExpression> positionedValueArguments = new ArrayList<JetExpression>();
// for (JetArgument argument : valueArguments) {
// positionedValueArguments.add(argument.getArgumentExpression());
// }
// positionedValueArguments.addAll(functionLiteralArguments);
// result[0] = overloadDomain.getReturnTypeForPositionedArguments(typeArguments, positionedValueArguments);
List<JetExpression> positionedValueArguments = new ArrayList<JetExpression>();
for (JetArgument argument : valueArguments) {
positionedValueArguments.add(argument.getArgumentExpression());
}
positionedValueArguments.addAll(functionLiteralArguments);
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
}
public boolean isConvertibleTo(Type actual, Type expected) {
// TODO
return isSubtypeOf(actual, expected);
}
public boolean isSubtypeOf(Type subtype, Type supertype) {
if (!supertype.isNullable() && subtype.isNullable()) {
return false;
@@ -7,10 +7,12 @@ import java.util.List;
*/
public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl implements ValueParameterDescriptor {
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);
this.hasDefaultValue = hasDefaultValue;
this.isVararg = isVararg;
}
@Override
@@ -25,6 +27,6 @@ public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl impleme
@Override
public boolean isVararg() {
throw new UnsupportedOperationException(); // TODO
return isVararg;
}
}
@@ -320,7 +320,9 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
public void testOverloads() throws Exception {
assertType("new Functions<String>().f()", "Unit");
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 {
@@ -402,8 +404,8 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
Project project = getProject();
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
Type type = JetTypeChecker.INSTANCE.getType(scope, jetExpression, false);
Type expectedType = makeType(expectedTypeStr);
assertTrue(type + " != " + expectedType, TypeImpl.equalTypes(type, expectedType));
Type expectedType = expectedTypeStr == null ? null : makeType(expectedTypeStr);
assertEquals(expectedType, type);
}
private static Type makeType(String typeStr) {
@@ -431,6 +433,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
"fun f() : Unit {} " +
"fun f(a : Int) : Int {} " +
"fun f(a : T) : Any {} " +
"fun f(a : Unit) : T {} " +
"}"
};