Support for unary expressions

This commit is contained in:
Natalia Ukhorskaya
2013-11-08 16:46:13 +04:00
parent b7b957ffd2
commit 96dc8b42bb
7 changed files with 112 additions and 1 deletions
@@ -212,6 +212,15 @@ public class ConstantExpressionEvaluator extends JetVisitor<CompileTimeConstant<
return null;
}
@Override
public CompileTimeConstant<?> visitUnaryExpression(@NotNull JetUnaryExpression expression, Void data) {
JetExpression leftExpression = expression.getBaseExpression();
if (leftExpression == null) {
return null;
}
return getCallConstant(expression.getOperationReference(), leftExpression);
}
public static CompileTimeConstant<?> createCompileTimeConstant(@NotNull Object value, @NotNull JetType expectedType) {
if (value instanceof Integer) {
return getIntegerValue(((Integer) value).longValue(), expectedType);
@@ -21,6 +21,22 @@ fun evaluateBinaryExpression(firstCompileTimeConstant: CompileTimeConstant<*>, s
return null
}
fun evaluateUnaryExpression(compileTimeConstant: CompileTimeConstant<*>, functionName: Name): Any? {
val compileTimeType = getCompileTimeType(compileTimeConstant)
if (compileTimeType == null) {
return null
}
val value = compileTimeConstant.getValue()
val function = unaryOperations[UnaryOperation(compileTimeType, functionName)]
if (function != null) {
return function(value)
}
return null
}
fun getCompileTimeType(c: CompileTimeConstant<*>): CompileTimeType<out Any>? = when (c.getValue()) {
is Int -> INT
is Byte -> BYTE
@@ -47,8 +63,29 @@ private val BOOLEAN = CompileTimeType<Boolean>()
private val STRING = CompileTimeType<String>()
private fun <A, B> bOp(a: CompileTimeType<A>, b: CompileTimeType<B>, functionNameAsString: String, f: (A, B) -> Any) = BinaryOperation(a, b, Name.identifier(functionNameAsString)) to f as Function2<Any?, Any?, Any>
private fun <A> uOp(a: CompileTimeType<A>, functionNameAsString: String, f: (A) -> Any) = UnaryOperation(a, Name.identifier(functionNameAsString)) to f as Function1<Any?, Any>
private data class BinaryOperation<A, B>(val f: CompileTimeType<out A>, val s: CompileTimeType<out B>, val functionName: Name)
private data class UnaryOperation<A>(val f: CompileTimeType<out A>, val functionName: Name)
private val unaryOperations = hashMapOf<UnaryOperation<*>, (Any?) -> Any>(
uOp(DOUBLE, "minus", { a -> a.minus() }),
uOp(FLOAT, "minus", { a -> a.minus() }),
uOp(LONG, "minus", { a -> a.minus() }),
uOp(INT, "minus", { a -> a.minus() }),
uOp(SHORT, "minus", { a -> a.minus() }),
uOp(BYTE, "minus", { a -> a.minus() }),
uOp(CHAR, "minus", { a -> a.minus() }),
uOp(DOUBLE, "plus", { a -> a.plus() }),
uOp(FLOAT, "plus", { a -> a.plus() }),
uOp(LONG, "plus", { a -> a.plus() }),
uOp(INT, "plus", { a -> a.plus() }),
uOp(SHORT, "plus", { a -> a.plus() }),
uOp(BYTE, "plus", { a -> a.plus() }),
uOp(CHAR, "plus", { a -> a.plus() }),
uOp(BOOLEAN, "not", { a -> a.not() })
)
private val binaryOperations = hashMapOf<BinaryOperation<*, *>, (Any?, Any?) -> Any>(
// String
@@ -21,6 +21,7 @@ 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,
@@ -30,7 +31,7 @@ public fun resolveCallToCompileTimeValue(
): CompileTimeConstant<*>? {
if (arguments.isEmpty()) {
val value = receiverValue.getValue()
return when (value) {
val toTypeConstant = when (value) {
is Number -> {
when(callName) {
OperatorConventions.DOUBLE -> DoubleValue(value.toDouble())
@@ -57,6 +58,14 @@ public fun resolveCallToCompileTimeValue(
}
else -> null
}
if (toTypeConstant != null) {
return toTypeConstant
}
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)