Support && and || in ConstantExpressionEvaluator
This commit is contained in:
+31
-2
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.evaluate;
|
package org.jetbrains.jet.lang.evaluate;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl;
|
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.constants.StringValue;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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.lang.types.lang.KotlinBuiltIns;
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -137,7 +139,34 @@ public class ConstantExpressionEvaluator extends JetVisitor<CompileTimeConstant<
|
|||||||
if (leftExpression == null) {
|
if (leftExpression == null) {
|
||||||
return 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
|
@Nullable
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
|||||||
bOp(BOOLEAN, BOOLEAN, "and", { a, b -> a and b }),
|
bOp(BOOLEAN, BOOLEAN, "and", { a, b -> a and b }),
|
||||||
bOp(BOOLEAN, BOOLEAN, "or", { a, b -> a or b }),
|
bOp(BOOLEAN, BOOLEAN, "or", { a, b -> a or b }),
|
||||||
bOp(BOOLEAN, BOOLEAN, "xor", { a, b -> a xor 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
|
// Byte
|
||||||
bOp(BYTE, DOUBLE, "plus", { a, b -> a + b }),
|
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]
|
||||||
+10
@@ -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);
|
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")
|
@TestMetadata("boolean.kt")
|
||||||
public void testBoolean() throws Exception {
|
public void testBoolean() throws Exception {
|
||||||
doTest("compiler/testData/resolveAnnotations/parameters/expressions/boolean.kt");
|
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");
|
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")
|
@TestMetadata("plus.kt")
|
||||||
public void testPlus() throws Exception {
|
public void testPlus() throws Exception {
|
||||||
doTest("compiler/testData/resolveAnnotations/parameters/expressions/plus.kt");
|
doTest("compiler/testData/resolveAnnotations/parameters/expressions/plus.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user