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()),
|
||||
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 {} " +
|
||||
"}"
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user