Support compareTo in ConstantExpressionEvaluator
This commit is contained in:
+67
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.evaluate;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -203,15 +204,79 @@ public class ConstantExpressionEvaluator extends JetVisitor<CompileTimeConstant<
|
||||
return null;
|
||||
}
|
||||
List<CompileTimeConstant<?>> arguments = Lists.newArrayList();
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> argumentEntry : resolvedCall.getValueArguments() .entrySet()) {
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> argumentEntry : resolvedCall.getValueArguments().entrySet()) {
|
||||
arguments.addAll(resolveArguments(argumentEntry.getValue().getArguments(), argumentEntry.getKey().getType(), trace));
|
||||
}
|
||||
return ConstantsPackage.resolveCallToCompileTimeValue(resultingDescriptor.getName(), receiverValue, arguments, expectedType);
|
||||
Name resultingDescriptorName = resultingDescriptor.getName();
|
||||
if (arguments.isEmpty()) {
|
||||
Object result = EvaluatePackage.evaluateUnaryExpression(receiverValue, resultingDescriptorName);
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return createCompileTimeConstant(result, expectedType);
|
||||
}
|
||||
else if (arguments.size() == 1) {
|
||||
Object result = EvaluatePackage.evaluateBinaryExpression(receiverValue, arguments.iterator().next(), resultingDescriptorName);
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
if (OperatorConventions.COMPARE_TO.equals(resultingDescriptorName)) {
|
||||
PsiElement parentExpression = resolvedCallExpression.getParent();
|
||||
if (parentExpression instanceof JetBinaryExpression) {
|
||||
return createCompileTimeConstantForCompareTo(result, (JetBinaryExpression) parentExpression);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return createCompileTimeConstant(result, expectedType);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CompileTimeConstant<?> createCompileTimeConstantForCompareTo(
|
||||
@NotNull Object result,
|
||||
@NotNull JetBinaryExpression expression
|
||||
) {
|
||||
if (result instanceof Integer) {
|
||||
int resultCode = ((Integer) result).intValue();
|
||||
IElementType operationToken = expression.getOperationToken();
|
||||
if (resultCode == 0) {
|
||||
if (operationToken == JetTokens.EQEQ ||
|
||||
operationToken == JetTokens.LTEQ ||
|
||||
operationToken == JetTokens.GTEQ) {
|
||||
return BooleanValue.TRUE;
|
||||
}
|
||||
else {
|
||||
return BooleanValue.FALSE;
|
||||
}
|
||||
}
|
||||
if (resultCode == 1) {
|
||||
if (operationToken == JetTokens.GT ||
|
||||
operationToken == JetTokens.GTEQ) {
|
||||
return BooleanValue.TRUE;
|
||||
}
|
||||
else {
|
||||
return BooleanValue.FALSE;
|
||||
}
|
||||
}
|
||||
if (resultCode == -1) {
|
||||
if (operationToken == JetTokens.LT ||
|
||||
operationToken == JetTokens.LTEQ) {
|
||||
return BooleanValue.TRUE;
|
||||
}
|
||||
else {
|
||||
return BooleanValue.FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitUnaryExpression(@NotNull JetUnaryExpression expression, Void data) {
|
||||
JetExpression leftExpression = expression.getBaseExpression();
|
||||
|
||||
+51
-1
@@ -153,6 +153,7 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(STRING, DOUBLE, "plus", { a, b -> a + b }),
|
||||
bOp(STRING, FLOAT, "plus", { a, b -> a + b }),
|
||||
bOp(STRING, CHAR, "plus", { a, b -> a + b }),
|
||||
bOp(STRING, STRING, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
|
||||
// Boolean
|
||||
bOp(BOOLEAN, BOOLEAN, "and", { a, b -> a and b }),
|
||||
@@ -197,6 +198,13 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(BYTE, SHORT, "mod", { a, b -> a % b }),
|
||||
bOp(BYTE, BYTE, "mod", { a, b -> a % b }),
|
||||
bOp(BYTE, CHAR, "mod", { a, b -> a % b }),
|
||||
bOp(BYTE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(BYTE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(BYTE, LONG, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(BYTE, INT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(BYTE, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(BYTE, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(BYTE, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
|
||||
// Short
|
||||
bOp(SHORT, DOUBLE, "plus", { a, b -> a + b }),
|
||||
@@ -234,6 +242,13 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(SHORT, SHORT, "mod", { a, b -> a % b }),
|
||||
bOp(SHORT, BYTE, "mod", { a, b -> a % b }),
|
||||
bOp(SHORT, CHAR, "mod", { a, b -> a % b }),
|
||||
bOp(SHORT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(SHORT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(SHORT, LONG, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(SHORT, INT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(SHORT, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(SHORT, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(SHORT, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
|
||||
// Int
|
||||
bOp(INT, DOUBLE, "plus", { a, b -> a + b }),
|
||||
@@ -277,6 +292,13 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(INT, INT, "and", { a, b -> a and b }),
|
||||
bOp(INT, INT, "or", { a, b -> a or b }),
|
||||
bOp(INT, INT, "xor", { a, b -> a xor b }),
|
||||
bOp(INT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(INT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(INT, LONG, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(INT, INT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(INT, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(INT, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(INT, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
|
||||
// Long
|
||||
bOp(LONG, DOUBLE, "plus", { a, b -> a + b }),
|
||||
@@ -320,6 +342,13 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(LONG, LONG, "and", { a, b -> a and b }),
|
||||
bOp(LONG, LONG, "or", { a, b -> a or b }),
|
||||
bOp(LONG, LONG, "xor", { a, b -> a xor b }),
|
||||
bOp(LONG, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(LONG, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(LONG, LONG, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(LONG, INT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(LONG, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(LONG, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(LONG, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
|
||||
// Double
|
||||
bOp(DOUBLE, DOUBLE, "plus", { a, b -> a + b }),
|
||||
@@ -356,6 +385,13 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(DOUBLE, INT, "mod", { a, b -> a % b }),
|
||||
bOp(DOUBLE, SHORT, "mod", { a, b -> a % b }),
|
||||
bOp(DOUBLE, BYTE, "mod", { a, b -> a % b }),
|
||||
bOp(DOUBLE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(DOUBLE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(DOUBLE, LONG, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(DOUBLE, INT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(DOUBLE, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(DOUBLE, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(DOUBLE, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
|
||||
// Float
|
||||
bOp(FLOAT, DOUBLE, "plus", { a, b -> a + b }),
|
||||
@@ -393,6 +429,13 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(FLOAT, SHORT, "mod", { a, b -> a % b }),
|
||||
bOp(FLOAT, BYTE, "mod", { a, b -> a % b }),
|
||||
bOp(FLOAT, CHAR, "mod", { a, b -> a % b }),
|
||||
bOp(FLOAT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(FLOAT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(FLOAT, LONG, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(FLOAT, INT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(FLOAT, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(FLOAT, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(FLOAT, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
|
||||
// Char
|
||||
bOp(CHAR, DOUBLE, "plus", { a, b -> a + b }),
|
||||
@@ -425,6 +468,13 @@ private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) ->
|
||||
bOp(CHAR, LONG, "mod", { a, b -> a % b }),
|
||||
bOp(CHAR, INT, "mod", { a, b -> a % b }),
|
||||
bOp(CHAR, SHORT, "mod", { a, b -> a % b }),
|
||||
bOp(CHAR, BYTE, "mod", { a, b -> a % b })
|
||||
bOp(CHAR, BYTE, "mod", { a, b -> a % b }),
|
||||
bOp(CHAR, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(CHAR, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(CHAR, LONG, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(CHAR, INT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(CHAR, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(CHAR, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
|
||||
bOp(CHAR, CHAR, "compareTo", { a, b -> a.compareTo(b) })
|
||||
)
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.constants
|
||||
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.evaluate.evaluateBinaryExpression
|
||||
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.evaluate.evaluateUnaryExpression
|
||||
|
||||
public fun resolveCallToCompileTimeValue(
|
||||
callName: Name,
|
||||
receiverValue: CompileTimeConstant<*>,
|
||||
arguments: Collection<CompileTimeConstant<*>>,
|
||||
expectedType: JetType
|
||||
): CompileTimeConstant<*>? {
|
||||
if (arguments.isEmpty()) {
|
||||
val result = evaluateUnaryExpression(receiverValue, callName)
|
||||
if (result == null) {
|
||||
return null
|
||||
}
|
||||
return ConstantExpressionEvaluator.createCompileTimeConstant(result, expectedType)
|
||||
}
|
||||
else if (arguments.size() == 1) {
|
||||
val result = evaluateBinaryExpression(receiverValue, arguments.iterator().next(), callName)
|
||||
if (result == null) {
|
||||
return null
|
||||
}
|
||||
return ConstantExpressionEvaluator.createCompileTimeConstant(result, expectedType)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package test
|
||||
|
||||
annotation class Ann(
|
||||
val b1: Boolean,
|
||||
val b2: Boolean,
|
||||
val b3: Boolean,
|
||||
val b4: Boolean,
|
||||
val b5: Boolean,
|
||||
val b6: Boolean
|
||||
)
|
||||
|
||||
val a = 1
|
||||
val b = 2
|
||||
|
||||
Ann(1 > 2, 1.0 > 2.0, 2 > a, b > a, 'b' > 'a', "a" > "b") class MyClass
|
||||
|
||||
// EXPECTED: Ann[b1 = false: jet.Boolean, b2 = false: jet.Boolean, b3 = true: jet.Boolean, b4 = true: jet.Boolean, b5 = true: jet.Boolean, b6 = false: jet.Boolean]
|
||||
@@ -0,0 +1,12 @@
|
||||
package test
|
||||
|
||||
annotation class Ann(
|
||||
val b1: Boolean,
|
||||
val b2: Boolean,
|
||||
val b3: Boolean,
|
||||
val b4: Boolean
|
||||
)
|
||||
|
||||
Ann(1 >= 2, 1.0 >= 2.0, 1 >= 1, 1.0 >= 1.0) class MyClass
|
||||
|
||||
// EXPECTED: Ann[b1 = false: jet.Boolean, b2 = false: jet.Boolean, b3 = true: jet.Boolean, b4 = true: jet.Boolean]
|
||||
@@ -0,0 +1,17 @@
|
||||
package test
|
||||
|
||||
annotation class Ann(
|
||||
val b1: Boolean,
|
||||
val b2: Boolean,
|
||||
val b3: Boolean,
|
||||
val b4: Boolean,
|
||||
val b5: Boolean,
|
||||
val b6: Boolean
|
||||
)
|
||||
|
||||
val a = 1
|
||||
val b = 2
|
||||
|
||||
Ann(1 < 2, 1.0 < 2.0, 2 < a, b < a, 'b' < 'a', "a" < "b") class MyClass
|
||||
|
||||
// EXPECTED: Ann[b1 = true: jet.Boolean, b2 = true: jet.Boolean, b3 = false: jet.Boolean, b4 = false: jet.Boolean, b5 = false: jet.Boolean, b6 = true: jet.Boolean]
|
||||
@@ -0,0 +1,12 @@
|
||||
package test
|
||||
|
||||
annotation class Ann(
|
||||
val b1: Boolean,
|
||||
val b2: Boolean,
|
||||
val b3: Boolean,
|
||||
val b4: Boolean
|
||||
)
|
||||
|
||||
Ann(1 <= 2, 1.0 <= 2.0, 1 <= 1, 1.0 <= 1.0) class MyClass
|
||||
|
||||
// EXPECTED: Ann[b1 = true: jet.Boolean, b2 = true: jet.Boolean, b3 = true: jet.Boolean, b4 = true: jet.Boolean]
|
||||
Reference in New Issue
Block a user