is, ===, !==, &&, ||
This commit is contained in:
@@ -99,7 +99,7 @@ public interface JetNodeTypes {
|
|||||||
JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class);
|
JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class);
|
||||||
JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class);
|
JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class);
|
||||||
JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.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 PREFIX_EXPRESSION = new JetNodeType("PREFIX_EXPRESSION", JetPrefixExpression.class);
|
||||||
JetNodeType POSTFIX_EXPRESSION = new JetNodeType("POSTFIX_EXPRESSION", JetPostfixExpression.class);
|
JetNodeType POSTFIX_EXPRESSION = new JetNodeType("POSTFIX_EXPRESSION", JetPostfixExpression.class);
|
||||||
JetNodeType CALL_EXPRESSION = new JetNodeType("CALL_EXPRESSION", JetCallExpression.class);
|
JetNodeType CALL_EXPRESSION = new JetNodeType("CALL_EXPRESSION", JetCallExpression.class);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -345,4 +345,8 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
public void visitWhenEntry(JetWhenEntry jetWhenEntry) {
|
public void visitWhenEntry(JetWhenEntry jetWhenEntry) {
|
||||||
visitJetElement(jetWhenEntry);
|
visitJetElement(jetWhenEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitIsExpression(JetIsExpression expression) {
|
||||||
|
visitExpression(expression);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
@Override
|
||||||
public void visitUnaryExpression(JetUnaryExpression expression) {
|
public void visitUnaryExpression(JetUnaryExpression expression) {
|
||||||
JetSimpleNameExpression operationSign = expression.getOperationSign();
|
JetSimpleNameExpression operationSign = expression.getOperationSign();
|
||||||
@@ -607,6 +614,9 @@ public class JetTypeInferrer {
|
|||||||
public void visitBinaryExpression(JetBinaryExpression expression) {
|
public void visitBinaryExpression(JetBinaryExpression expression) {
|
||||||
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
||||||
|
|
||||||
|
JetExpression left = expression.getLeft();
|
||||||
|
JetExpression right = expression.getRight();
|
||||||
|
|
||||||
IElementType operationType = operationSign.getReferencedNameElementType();
|
IElementType operationType = operationSign.getReferencedNameElementType();
|
||||||
if (operationType == JetTokens.IDENTIFIER) {
|
if (operationType == JetTokens.IDENTIFIER) {
|
||||||
result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope, true);
|
result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope, true);
|
||||||
@@ -615,7 +625,6 @@ public class JetTypeInferrer {
|
|||||||
result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope, true);
|
result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope, true);
|
||||||
}
|
}
|
||||||
else if (operationType == JetTokens.EQ) {
|
else if (operationType == JetTokens.EQ) {
|
||||||
JetExpression left = expression.getLeft();
|
|
||||||
JetExpression deparenthesized = deparenthesize(left);
|
JetExpression deparenthesized = deparenthesize(left);
|
||||||
if (deparenthesized instanceof JetArrayAccessExpression) {
|
if (deparenthesized instanceof JetArrayAccessExpression) {
|
||||||
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized;
|
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized;
|
||||||
@@ -656,7 +665,6 @@ public class JetTypeInferrer {
|
|||||||
assureBooleanResult(operationSign, name, equalsType);
|
assureBooleanResult(operationSign, name, equalsType);
|
||||||
}
|
}
|
||||||
else if (inOperations.contains(operationType)) {
|
else if (inOperations.contains(operationType)) {
|
||||||
JetExpression right = expression.getRight();
|
|
||||||
if (right == null) {
|
if (right == null) {
|
||||||
result = ErrorType.createErrorType("No right argument"); // TODO
|
result = ErrorType.createErrorType("No right argument"); // TODO
|
||||||
return;
|
return;
|
||||||
@@ -665,6 +673,24 @@ public class JetTypeInferrer {
|
|||||||
JetType containsType = getTypeForBinaryCall(scope, right, expression.getOperationReference(), expression.getLeft(), name, true);
|
JetType containsType = getTypeForBinaryCall(scope, right, expression.getOperationReference(), expression.getLeft(), name, true);
|
||||||
result = assureBooleanResult(operationSign, name, containsType);
|
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 {
|
else {
|
||||||
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Unknown operation");
|
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Unknown operation");
|
||||||
}
|
}
|
||||||
@@ -722,7 +748,7 @@ public class JetTypeInferrer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitJetElement(JetElement elem) {
|
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) {
|
private JetType getTypeForBinaryCall(JetBinaryExpression expression, @NotNull String name, JetScope scope, boolean reportUnresolved) {
|
||||||
|
|||||||
@@ -400,6 +400,11 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
|
|
||||||
public void testBinaryOperations() throws Exception {
|
public void testBinaryOperations() throws Exception {
|
||||||
assertType("1 as Any", "Any");
|
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) {
|
private void assertSubtype(String type1, String type2) {
|
||||||
|
|||||||
Reference in New Issue
Block a user