From 6291754d3ac6558efe8c158acddc7752b32448fd Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 25 Mar 2011 17:17:56 +0300 Subject: [PATCH] Equality applicability check for === and !== --- idea/src/jet/lang/Library.jet | 3 +- .../jet/lang/types/JetTypeInferrer.java | 39 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/idea/src/jet/lang/Library.jet b/idea/src/jet/lang/Library.jet index c45ba772091..feb6203270a 100644 --- a/idea/src/jet/lang/Library.jet +++ b/idea/src/jet/lang/Library.jet @@ -19,7 +19,7 @@ class Boolean : Comparable { fun xor(other : Boolean) : Boolean - fun equals(other : Boolean?) : Boolean + fun equals(other : Any?) : Boolean } class String : Comparable { @@ -27,6 +27,7 @@ class String : Comparable { val length : Int fun plus(other : Any?) : String + fun equals(other : Any?) : Boolean } class Range> { diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index d4f3ac10510..40521162a56 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -959,17 +959,13 @@ public class JetTypeInferrer { JetType equalsType = getTypeForBinaryCall(expression, name, scope, true); result = assureBooleanResult(operationSign, name, equalsType); - // Assure that the types on the left and on the right have nonempty intersection - if (right != null) { - // TODO : duplicated effort - JetType leftType = getType(scope, left, false); - JetType rightType = getType(scope, right, false); + ensureNonemptyIntersectionOfOperandTypes(expression); + } + else if (operationType == JetTokens.EQEQEQ || operationType == JetTokens.EXCLEQEQEQ) { + ensureNonemptyIntersectionOfOperandTypes(expression); - JetType intersect = TypeUtils.intersect(semanticServices.getTypeChecker(), new HashSet(Arrays.asList(leftType, rightType))); - if (intersect == null) { - semanticServices.getErrorHandler().genericError(expression.getNode(), "Operator " + operationSign.getReferencedName() + " cannot be applied to " + leftType + " and " + rightType); - } - } + // TODO : Check comparison pointlessness + result = semanticServices.getStandardLibrary().getBooleanType(); } else if (inOperations.contains(operationType)) { if (right == null) { @@ -980,12 +976,6 @@ public class JetTypeInferrer { JetType containsType = getTypeForBinaryCall(scope, right, expression.getOperationReference(), expression.getLeft(), name, true); result = assureBooleanResult(operationSign, name, containsType); } - else if (operationType == JetTokens.EQEQEQ || operationType == JetTokens.EXCLEQEQEQ) { - JetType leftType = getType(scope, left, false); - JetType rightType = right == null ? null : getType(scope, right, false); - // TODO : Check comparison pointlessness - result = semanticServices.getStandardLibrary().getBooleanType(); - } else if (operationType == JetTokens.ANDAND || operationType == JetTokens.OROR) { JetType leftType = getType(scope, left, false); JetType rightType = right == null ? null : getType(scope, right, false); @@ -1015,6 +1005,23 @@ public class JetTypeInferrer { } } + private void ensureNonemptyIntersectionOfOperandTypes(JetBinaryExpression expression) { + JetSimpleNameExpression operationSign = expression.getOperationReference(); + JetExpression left = expression.getLeft(); + JetExpression right = expression.getRight(); + + // TODO : duplicated effort for == and != + JetType leftType = getType(scope, left, false); + if (right != null) { + JetType rightType = getType(scope, right, false); + + JetType intersect = TypeUtils.intersect(semanticServices.getTypeChecker(), new HashSet(Arrays.asList(leftType, rightType))); + if (intersect == null) { + semanticServices.getErrorHandler().genericError(expression.getNode(), "Operator " + operationSign.getReferencedName() + " cannot be applied to " + leftType + " and " + rightType); + } + } + } + protected void visitAssignmentOperation(JetBinaryExpression expression) { assignmentIsNotAnExpressionError(expression); }