Support Char.code in constant evaluator, KT-46036

But do not consider Char.code a pure integer constant.
This commit is contained in:
Ilya Gorbunov
2021-04-07 17:11:10 +03:00
parent 0a446230f7
commit 8041c3aa1d
10 changed files with 70 additions and 3 deletions

View File

@@ -33788,6 +33788,22 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/evaluate")
@TestDataPath("$PROJECT_ROOT")
public class Evaluate {
@Test
public void testAllFilesPresentInEvaluate() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/evaluate"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("charCodeExpType.kt")
public void testCharCodeExpType() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/evaluate/charCodeExpType.kt");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental")
@TestDataPath("$PROJECT_ROOT")

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -635,13 +635,14 @@ private class ConstantExpressionEvaluatorVisitor(
val usesVariableAsConstant = usesVariableAsConstant(argumentForReceiver.expression)
val usesNonConstValAsConstant = usesNonConstValAsConstant(argumentForReceiver.expression)
val isNumberConversionMethod = resultingDescriptorName in OperatorConventions.NUMBER_CONVERSIONS
val isCharCode = argumentForReceiver.ctcType == CHAR && resultingDescriptorName == StandardNames.CHAR_CODE
val dontCreateILT = !isUnaryPlusMinus && !hasIntegerLiteralType(receiverExpression)
return createConstant(
result,
expectedType,
CompileTimeConstant.Parameters(
canBeUsedInAnnotation,
!isNumberConversionMethod && isArgumentPure,
!isNumberConversionMethod && !isCharCode && isArgumentPure,
isUnsignedNumberLiteral = false,
isUnsignedLongNumberLiteral = false,
usesVariableAsConstant,

View File

@@ -38,6 +38,7 @@ internal fun evalUnaryOp(name: String, type: CompileTimeType, value: Any): Any?
"toLong" -> return (value as Char).toLong()
"toShort" -> return (value as Char).toShort()
"toString" -> return (value as Char).toString()
"code" -> return (value as Char).code
}
DOUBLE -> when (name) {
"toByte" -> return (value as Double).toByte()

View File

@@ -0,0 +1,8 @@
const val p1: Int = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'\n'.code<!>
const val p2: Long = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'\n'.code.toLong()<!>
const val p3: Byte = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'\n'.code.toByte()<!>
const val p4: Short = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'\n'.code.toShort()<!>
const val e2: Long = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'\n'.code<!>
const val e3: Byte = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'\n'.code<!>
const val e4: Short = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>'\n'.code<!>

View File

@@ -0,0 +1,8 @@
const val p1: Int = '\n'.code
const val p2: Long = '\n'.code.toLong()
const val p3: Byte = '\n'.code.toByte()
const val p4: Short = '\n'.code.toShort()
const val e2: Long = <!TYPE_MISMATCH!>'\n'.code<!>
const val e3: Byte = <!TYPE_MISMATCH!>'\n'.code<!>
const val e4: Short = <!TYPE_MISMATCH!>'\n'.code<!>

View File

@@ -0,0 +1,10 @@
package
public const val e2: kotlin.Long = 10
public const val e3: kotlin.Byte = 10
public const val e4: kotlin.Short = 10
public const val p1: kotlin.Int = 10
public const val p2: kotlin.Long = 10.toLong()
public const val p3: kotlin.Byte = 10.toByte()
public const val p4: kotlin.Short = 10.toShort()

View File

@@ -8,3 +8,6 @@ val prop2: Long = 0x7777777777
// val prop3: 513105426295.toLong()
val prop3 = 0x7777777777
// val prop4: 10
const val prop4 = '\n'.code

View File

@@ -33884,6 +33884,22 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/evaluate")
@TestDataPath("$PROJECT_ROOT")
public class Evaluate {
@Test
public void testAllFilesPresentInEvaluate() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/evaluate"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("charCodeExpType.kt")
public void testCharCodeExpType() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/evaluate/charCodeExpType.kt");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental")
@TestDataPath("$PROJECT_ROOT")

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -20,6 +20,8 @@ object StandardNames {
@JvmField val ENUM_VALUE_OF = Name.identifier("valueOf")
@JvmField val CHAR_CODE = Name.identifier("code")
@JvmField val COROUTINES_PACKAGE_FQ_NAME_RELEASE = FqName("kotlin.coroutines")
@JvmField val COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL = COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("experimental"))

View File

@@ -68,6 +68,8 @@ fun generate(): String {
}
}
unaryOperationsMap.add(Triple("code", listOf(builtIns.charType), false))
for (type in integerTypes) {
for (otherType in integerTypes) {
val parameters = listOf(type, otherType)