Contains (in, !in)

This commit is contained in:
Andrey Breslav
2011-03-15 20:16:27 +03:00
parent 681d979a8d
commit e414413112
3 changed files with 36 additions and 12 deletions
@@ -62,7 +62,7 @@ public class JavaClassMembersScope implements JetScope {
@Override
public FunctionGroup getFunctionGroup(@NotNull String name) {
WritableFunctionGroup writableFunctionGroup = new WritableFunctionGroup(name);
PsiMethod[] allMethods = psiClass.getAllMethods();
PsiMethod[] allMethods = psiClass.getMethods(); // TODO : look into superclasses
for (PsiMethod method : allMethods) {
if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
continue;
@@ -601,22 +601,39 @@ public class JetTypeInferrer {
}
}
else if (equalsOperations.contains(operationType)) {
JetType equalsType = getTypeForBinaryCall(expression, "equals", scope, true);
if (equalsType != null) {
// TODO : Relax?
TypeConstructor booleanTypeConstructor = semanticServices.getStandardLibrary().getBoolean().getTypeConstructor();
if (!equalsType.getConstructor().equals(booleanTypeConstructor)) {
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "'equals' must return Boolean but returns " + equalsType);
} else {
result = equalsType;
}
String name = "equals";
JetType equalsType = getTypeForBinaryCall(expression, name, scope, true);
assureBooleanResult(operationSign, name, equalsType);
}
else if (inOperations.contains(operationType)) {
JetExpression right = expression.getRight();
if (right == null) {
result = ErrorType.createErrorType("No right argument"); // TODO
return;
}
String name = "contains";
JetType containsType = getTypeForBinaryCall(scope, right, expression.getOperationReference(), expression.getLeft(), name, true);
result = assureBooleanResult(operationSign, name, containsType);
}
else {
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Unknown operation");
}
}
private JetType assureBooleanResult(JetSimpleNameExpression operationSign, String name, JetType resultType) {
if (resultType != null) {
// TODO : Relax?
TypeConstructor booleanTypeConstructor = semanticServices.getStandardLibrary().getBoolean().getTypeConstructor();
if (!resultType.getConstructor().equals(booleanTypeConstructor)) {
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "'" + name + "' must return Boolean but returns " + resultType);
return null;
} else {
return resultType;
}
}
return resultType;
}
@Override
public void visitArrayAccessExpression(JetArrayAccessExpression expression) {
JetExpression arrayExpression = expression.getArrayExpression();
@@ -655,13 +672,17 @@ public class JetTypeInferrer {
}
private JetType getTypeForBinaryCall(JetBinaryExpression expression, @NotNull String name, JetScope scope, boolean reportUnresolved) {
JetSimpleNameExpression operationSign = expression.getOperationReference();
JetExpression left = expression.getLeft();
JetType leftType = getType(scope, left, false);
JetExpression right = expression.getRight();
if (right == null) {
return ErrorType.createErrorType("No right argument"); // TODO
}
JetSimpleNameExpression operationSign = expression.getOperationReference();
return getTypeForBinaryCall(scope, left, operationSign, right, name, reportUnresolved);
}
private JetType getTypeForBinaryCall(JetScope scope, JetExpression left, JetSimpleNameExpression operationSign, @NotNull JetExpression right, String name, boolean reportUnresolved) {
JetType leftType = getType(scope, left, false);
JetType rightType = getType(scope, right, false);
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, name, leftType, Collections.singletonList(rightType), reportUnresolved);
if (functionDescriptor != null) {
@@ -10,6 +10,7 @@ import util.*
~mod~fun mod(t : String) : Int {}
~rangeTo~fun rangeTo(t : String) : Int {}
~==~fun equals(a : Any?) : Boolean {}
~contains~fun contains(a : Any?) : Boolean {}
}
~t~fun <~t.T~T> t(~t.t~t : `t.T`T) : `t.T`T {
@@ -29,6 +30,8 @@ import util.*
x `rangeTo`.. ""
x `==`== ""
x `==`!= 1
1 `contains`in x
1 `contains`!in x
}
~Foo~class Foo {