From e414413112078b4739943174f06dcb98ada4c27a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 15 Mar 2011 20:16:27 +0300 Subject: [PATCH] Contains (in, !in) --- .../resolve/java/JavaClassMembersScope.java | 2 +- .../jet/lang/types/JetTypeInferrer.java | 43 ++++++++++++++----- .../resolve/ResolveOfInfixExpressions.jet | 3 ++ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index 8f5b0bab5c5..627bf9a68a6 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -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; diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 65b5f93f25a..5e139e8603e 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -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) { diff --git a/idea/testData/resolve/ResolveOfInfixExpressions.jet b/idea/testData/resolve/ResolveOfInfixExpressions.jet index c8c2f5a82b8..46cee0fd1d3 100644 --- a/idea/testData/resolve/ResolveOfInfixExpressions.jet +++ b/idea/testData/resolve/ResolveOfInfixExpressions.jet @@ -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 {