Support && and || in ConstantExpressionEvaluator

This commit is contained in:
Natalia Ukhorskaya
2013-11-08 15:51:45 +04:00
parent f8f55799b9
commit 210899af22
5 changed files with 63 additions and 2 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.evaluate;
import com.google.common.collect.Lists;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl;
@@ -30,8 +31,9 @@ import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.List;
import java.util.Map;
@@ -137,7 +139,34 @@ public class ConstantExpressionEvaluator extends JetVisitor<CompileTimeConstant<
if (leftExpression == null) {
return null;
}
return getCallConstant(expression.getOperationReference(), leftExpression);
IElementType operationToken = expression.getOperationToken();
if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationToken)) {
JetType booleanType = KotlinBuiltIns.getInstance().getBooleanType();
CompileTimeConstant<?> leftConstant = leftExpression.accept(new ConstantExpressionEvaluator(trace, booleanType), null);
if (leftConstant == null) {
return null;
}
JetExpression rightExpression = expression.getRight();
if (rightExpression == null) {
return null;
}
CompileTimeConstant<?> rightConstant = rightExpression.accept(new ConstantExpressionEvaluator(trace, booleanType), null);
if (rightConstant == null) {
return null;
}
Name operationName = operationToken == JetTokens.ANDAND ? Name.identifier("andand") : Name.identifier("oror");
Object result = EvaluatePackage.evaluateBinaryExpression(leftConstant, rightConstant, operationName);
if (result == null) {
return null;
}
return createCompileTimeConstant(result, expectedType);
}
else {
return getCallConstant(expression.getOperationReference(), leftExpression);
}
}
@Nullable
@@ -65,6 +65,8 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
bOp(BOOLEAN, BOOLEAN, "and", { a, b -> a and b }),
bOp(BOOLEAN, BOOLEAN, "or", { a, b -> a or b }),
bOp(BOOLEAN, BOOLEAN, "xor", { a, b -> a xor b }),
bOp(BOOLEAN, BOOLEAN, "andand", { a, b -> a && b }),
bOp(BOOLEAN, BOOLEAN, "oror", { a, b -> a || b }),
// Byte
bOp(BYTE, DOUBLE, "plus", { a, b -> a + b }),
@@ -0,0 +1,10 @@
package test
annotation class Ann(
val b1: Boolean,
val b2: Boolean
)
Ann(true && false, true && true) class MyClass
// EXPECTED: Ann[b1 = false: jet.Boolean, b2 = true: jet.Boolean]
@@ -0,0 +1,10 @@
package test
annotation class Ann(
val b1: Boolean,
val b2: Boolean
)
Ann(true || false, true || true) class MyClass
// EXPECTED: Ann[b1 = true: jet.Boolean, b2 = true: jet.Boolean]
@@ -78,6 +78,11 @@ public class AnnotationParameterTestGenerated extends AbstractAnnotationParamete
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolveAnnotations/parameters/expressions"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("andAnd.kt")
public void testAndAnd() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/andAnd.kt");
}
@TestMetadata("boolean.kt")
public void testBoolean() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/boolean.kt");
@@ -188,6 +193,11 @@ public class AnnotationParameterTestGenerated extends AbstractAnnotationParamete
doTest("compiler/testData/resolveAnnotations/parameters/expressions/multilineString.kt");
}
@TestMetadata("orOr.kt")
public void testOrOr() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/orOr.kt");
}
@TestMetadata("plus.kt")
public void testPlus() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/plus.kt");