diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 3c2d11cfa90..42d251e1f68 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -99,7 +99,7 @@ public interface JetNodeTypes { JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class); JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class); JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class); - JetNodeType BINARY_WITH_PATTERN = new JetNodeType("BINARY_WITH_PATTERN", JetExpression.class); // TODO: + JetNodeType BINARY_WITH_PATTERN = new JetNodeType("BINARY_WITH_PATTERN", JetIsExpression.class); // TODO: JetNodeType PREFIX_EXPRESSION = new JetNodeType("PREFIX_EXPRESSION", JetPrefixExpression.class); JetNodeType POSTFIX_EXPRESSION = new JetNodeType("POSTFIX_EXPRESSION", JetPostfixExpression.class); JetNodeType CALL_EXPRESSION = new JetNodeType("CALL_EXPRESSION", JetCallExpression.class); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetIsExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetIsExpression.java new file mode 100644 index 00000000000..e4d7b426aa9 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/psi/JetIsExpression.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.lang.psi; + +import com.intellij.lang.ASTNode; +import org.jetbrains.annotations.NotNull; + +/** + * @author abreslav + */ +public class JetIsExpression extends JetExpression { + public JetIsExpression(@NotNull ASTNode node) { + super(node); + } + + @Override + public void accept(JetVisitor visitor) { + visitor.visitIsExpression(this); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java index 2c88293a238..419c8f801ad 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java @@ -345,4 +345,8 @@ public class JetVisitor extends PsiElementVisitor { public void visitWhenEntry(JetWhenEntry jetWhenEntry) { visitJetElement(jetWhenEntry); } + + public void visitIsExpression(JetIsExpression expression) { + visitExpression(expression); + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index e89d40d46b8..1ee029edb4a 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -585,6 +585,13 @@ public class JetTypeInferrer { } } + @Override + public void visitIsExpression(JetIsExpression expression) { + // TODO : patterns and everything + System.out.println("Pattern matching is not supported yet."); + result = semanticServices.getStandardLibrary().getBooleanType(); + } + @Override public void visitUnaryExpression(JetUnaryExpression expression) { JetSimpleNameExpression operationSign = expression.getOperationSign(); @@ -607,6 +614,9 @@ public class JetTypeInferrer { public void visitBinaryExpression(JetBinaryExpression expression) { JetSimpleNameExpression operationSign = expression.getOperationReference(); + JetExpression left = expression.getLeft(); + JetExpression right = expression.getRight(); + IElementType operationType = operationSign.getReferencedNameElementType(); if (operationType == JetTokens.IDENTIFIER) { result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope, true); @@ -615,7 +625,6 @@ public class JetTypeInferrer { result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope, true); } else if (operationType == JetTokens.EQ) { - JetExpression left = expression.getLeft(); JetExpression deparenthesized = deparenthesize(left); if (deparenthesized instanceof JetArrayAccessExpression) { JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized; @@ -656,7 +665,6 @@ public class JetTypeInferrer { assureBooleanResult(operationSign, name, equalsType); } else if (inOperations.contains(operationType)) { - JetExpression right = expression.getRight(); if (right == null) { result = ErrorType.createErrorType("No right argument"); // TODO return; @@ -665,6 +673,24 @@ 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); + if (leftType != null && !isBoolean(leftType)) { + semanticServices.getErrorHandler().typeMismatch(left, semanticServices.getStandardLibrary().getBooleanType(), leftType); + } + if (rightType != null && !isBoolean(rightType)) { + semanticServices.getErrorHandler().typeMismatch(left, semanticServices.getStandardLibrary().getBooleanType(), rightType); + semanticServices.getErrorHandler().typeMismatch(right, semanticServices.getStandardLibrary().getBooleanType(), rightType); + } + result = semanticServices.getStandardLibrary().getBooleanType(); + } else { semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Unknown operation"); } @@ -722,7 +748,7 @@ public class JetTypeInferrer { @Override public void visitJetElement(JetElement elem) { - throw new IllegalArgumentException("Unsupported element: " + elem); + throw new IllegalArgumentException("Unsupported element: " + elem + " " + elem.getClass().getCanonicalName()); } private JetType getTypeForBinaryCall(JetBinaryExpression expression, @NotNull String name, JetScope scope, boolean reportUnresolved) { diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 6454f0607c7..9671b9309f8 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -400,6 +400,11 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { public void testBinaryOperations() throws Exception { assertType("1 as Any", "Any"); + assertType("1 is Char", "Boolean"); + assertType("1 === null", "Boolean"); + assertType("1 !== null", "Boolean"); + assertType("true && false", "Boolean"); + assertType("true || false", "Boolean"); } private void assertSubtype(String type1, String type2) {