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)
@@ -0,0 +1,11 @@
package test
annotation class Ann(
val b1: Boolean,
val b2: Boolean,
val b3: Boolean
)
Ann(!true, !false) class MyClass
// EXPECTED: Ann[b1 = false: jet.Boolean, b2 = true: jet.Boolean]
@@ -0,0 +1,15 @@
package test
annotation class Ann(
val b1: Byte,
val b2: Short,
val b3: Int,
val b4: Long,
val b5: Double,
val b6: Float,
val b7: Char
)
Ann(-1, -1, -1, -1, -1.0, -1.0, -'c') class MyClass
// EXPECTED: Ann[b1 = -1.toByte(): jet.Byte, b2 = -1.toShort(): jet.Short, b3 = -1.toInt(): jet.Int, b4 = -1.toLong(): jet.Long, b5 = -1.0.toDouble(): jet.Double, b6 = -1.0.toDouble(): jet.Double, b7 = -99.toInt(): jet.Int]
@@ -0,0 +1,15 @@
package test
annotation class Ann(
val b1: Byte,
val b2: Short,
val b3: Int,
val b4: Long,
val b5: Double,
val b6: Float,
val b7: Char
)
Ann(+1, +1, +1, +1, +1.0, +1.0, +'c') class MyClass
// EXPECTED: Ann[b1 = 1.toByte(): jet.Byte, b2 = 1.toShort(): jet.Short, b3 = 1.toInt(): jet.Int, b4 = 1.toLong(): jet.Long, b5 = 1.0.toDouble(): jet.Double, b6 = 1.0.toDouble(): jet.Double, b7 = 99.toInt(): jet.Int]
@@ -198,6 +198,11 @@ public class AnnotationParameterTestGenerated extends AbstractAnnotationParamete
doTest("compiler/testData/resolveAnnotations/parameters/expressions/multilineString.kt");
}
@TestMetadata("not.kt")
public void testNot() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/not.kt");
}
@TestMetadata("orOr.kt")
public void testOrOr() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/orOr.kt");
@@ -233,6 +238,16 @@ public class AnnotationParameterTestGenerated extends AbstractAnnotationParamete
doTest("compiler/testData/resolveAnnotations/parameters/expressions/strings.kt");
}
@TestMetadata("unaryMinus.kt")
public void testUnaryMinus() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/unaryMinus.kt");
}
@TestMetadata("unaryPlus.kt")
public void testUnaryPlus() throws Exception {
doTest("compiler/testData/resolveAnnotations/parameters/expressions/unaryPlus.kt");
}
}
public static Test suite() {