More correct handling of compile time constant types #KT-13421 Fixed

This commit is contained in:
Mikhail Glukhikh
2016-08-16 15:00:15 +03:00
parent 354d047533
commit ac3dfd93bd
6 changed files with 64 additions and 14 deletions

View File

@@ -702,9 +702,10 @@ private class ConstantExpressionEvaluatorVisitor(
}
}
private fun createOperationArgument(expression: KtExpression, expressionType: KotlinType, compileTimeType: CompileTimeType<*>): OperationArgument? {
val compileTimeConstant = constantExpressionEvaluator.evaluateExpression(expression, trace, expressionType) ?: return null
val evaluationResult = compileTimeConstant.getValue(expressionType) ?: return null
private fun createOperationArgument(expression: KtExpression, parameterType: KotlinType, compileTimeType: CompileTimeType<*>): OperationArgument? {
val compileTimeConstant = constantExpressionEvaluator.evaluateExpression(expression, trace, parameterType) ?: return null
if (compileTimeConstant is TypedCompileTimeConstant && !compileTimeConstant.type.isSubtypeOf(parameterType)) return null
val evaluationResult = compileTimeConstant.getValue(parameterType) ?: return null
return OperationArgument(evaluationResult, compileTimeType, expression)
}
@@ -866,18 +867,20 @@ private fun getReceiverExpressionType(resolvedCall: ResolvedCall<*>): KotlinType
}
}
internal class CompileTimeType<T>
internal class CompileTimeType<T>(val name: String) {
override fun toString() = name
}
internal val BYTE = CompileTimeType<Byte>()
internal val SHORT = CompileTimeType<Short>()
internal val INT = CompileTimeType<Int>()
internal val LONG = CompileTimeType<Long>()
internal val DOUBLE = CompileTimeType<Double>()
internal val FLOAT = CompileTimeType<Float>()
internal val CHAR = CompileTimeType<Char>()
internal val BOOLEAN = CompileTimeType<Boolean>()
internal val STRING = CompileTimeType<String>()
internal val ANY = CompileTimeType<Any>()
internal val BYTE = CompileTimeType<Byte>("Byte")
internal val SHORT = CompileTimeType<Short>("Short")
internal val INT = CompileTimeType<Int>("Int")
internal val LONG = CompileTimeType<Long>("Long")
internal val DOUBLE = CompileTimeType<Double>("Double")
internal val FLOAT = CompileTimeType<Float>("Float")
internal val CHAR = CompileTimeType<Char>("Char")
internal val BOOLEAN = CompileTimeType<Boolean>("Boolean")
internal val STRING = CompileTimeType<String>("String")
internal val ANY = CompileTimeType<Any>("Any")
@Suppress("UNCHECKED_CAST")
internal fun <A, B> binaryOperation(

View File

@@ -0,0 +1,8 @@
fun bar() {
false and false
}
// See exception in KT-13421
fun foo() {
42 and <!CONSTANT_EXPECTED_TYPE_MISMATCH!>false<!>
}

View File

@@ -0,0 +1,4 @@
package
public fun bar(): kotlin.Unit
public fun foo(): kotlin.Unit

View File

@@ -0,0 +1,23 @@
package test
// val x1: 3
val x1 = 1 + 2
// val x2: 3.toLong()
val x2 = 1 + 2L
// val x3: 3
val x3 = 1.toShort() + 2.toByte()
// val x4: 3
val x4 = 1.toByte() + 2.toByte()
// val x5: 4656
val x5 = 0x1234 and 0x5678
// Strange result, see KT-13517
// val x6: null
val x6 = 0x1234 and 0x5678L
// val x7: 4656.toLong()
val x7 = 0x1234L and 0x5678

View File

@@ -6840,6 +6840,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("logicWithNumber.kt")
public void testLogicWithNumber() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/evaluate/logicWithNumber.kt");
doTest(fileName);
}
@TestMetadata("longOverflow.kt")
public void testLongOverflow() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/evaluate/longOverflow.kt");

View File

@@ -97,6 +97,12 @@ public class CompileTimeConstantEvaluatorTestGenerated extends AbstractCompileTi
doConstantTest(fileName);
}
@TestMetadata("integerOperations.kt")
public void testIntegerOperations() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/evaluate/constant/integerOperations.kt");
doConstantTest(fileName);
}
@TestMetadata("integers.kt")
public void testIntegers() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/evaluate/constant/integers.kt");