Treat number with unsigned literal as UByte & UShort & UInt & ULong
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@ class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator {
|
||||
//Note: evaluated expression may be of class that does not match field type in some cases
|
||||
// tested for Int, left other checks just in case
|
||||
is Byte, is Short, is Int, is Long -> {
|
||||
ConstantValueFactory.createIntegerConstantValue((evaluated as Number).toLong(), descriptor.type)
|
||||
ConstantValueFactory.createIntegerConstantValue((evaluated as Number).toLong(), descriptor.type, false)
|
||||
}
|
||||
else -> {
|
||||
ConstantValueFactory.createConstantValue(evaluated)
|
||||
|
||||
+28
-12
@@ -387,11 +387,18 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
val isLongWithSuffix = nodeElementType == KtNodeTypes.INTEGER_CONSTANT && hasLongSuffix(text)
|
||||
val isUnsigned = hasUnsignedSuffix(text)
|
||||
val typedConstant = nodeElementType == KtNodeTypes.INTEGER_CONSTANT && (hasLongSuffix(text) || isUnsigned)
|
||||
return createConstant(
|
||||
result,
|
||||
expectedType,
|
||||
CompileTimeConstant.Parameters(true, !isLongWithSuffix, false, usesNonConstValAsConstant = false)
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation = true,
|
||||
isPure = !typedConstant,
|
||||
isUnsigned = isUnsigned,
|
||||
usesVariableAsConstant = false,
|
||||
usesNonConstValAsConstant = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -435,6 +442,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
expectedType,
|
||||
CompileTimeConstant.Parameters(
|
||||
isPure = false,
|
||||
isUnsigned = false,
|
||||
canBeUsedInAnnotation = canBeUsedInAnnotation,
|
||||
usesVariableAsConstant = usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = usesNonConstantVariableAsConstant
|
||||
@@ -497,6 +505,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation = true,
|
||||
isPure = false,
|
||||
isUnsigned = false,
|
||||
usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = leftConstant.usesNonConstValAsConstant || rightConstant.usesNonConstValAsConstant
|
||||
)
|
||||
@@ -544,6 +553,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation,
|
||||
!isNumberConversionMethod && isArgumentPure,
|
||||
false,
|
||||
usesVariableAsConstant, usesNonConstValAsConstant
|
||||
)
|
||||
)
|
||||
@@ -575,8 +585,9 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
usesVariableAsConstant(argumentForReceiver.expression) || usesVariableAsConstant(argumentForParameter.expression)
|
||||
val usesNonConstValAsConstant =
|
||||
usesNonConstValAsConstant(argumentForReceiver.expression) || usesNonConstValAsConstant(argumentForParameter.expression)
|
||||
val parameters =
|
||||
CompileTimeConstant.Parameters(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant, usesNonConstValAsConstant)
|
||||
val parameters = CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation, areArgumentsPure, false, usesVariableAsConstant, usesNonConstValAsConstant
|
||||
)
|
||||
return when (resultingDescriptorName) {
|
||||
OperatorNameConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression)?.wrap(parameters)
|
||||
OperatorNameConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression)?.wrap(parameters)
|
||||
@@ -696,6 +707,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor),
|
||||
isPure = false,
|
||||
isUnsigned = false,
|
||||
usesVariableAsConstant = true,
|
||||
usesNonConstValAsConstant = !callableDescriptor.isConst
|
||||
)
|
||||
@@ -899,7 +911,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
expectedType: KotlinType?,
|
||||
parameters: CompileTimeConstant.Parameters
|
||||
): CompileTimeConstant<*>? {
|
||||
return if (parameters.isPure) {
|
||||
return if (parameters.isPure || parameters.isUnsigned) {
|
||||
return createCompileTimeConstant(value, parameters, expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
|
||||
} else {
|
||||
ConstantValueFactory.createConstantValue(value)?.wrap(parameters)
|
||||
@@ -923,15 +935,17 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
expectedType: KotlinType
|
||||
): CompileTimeConstant<*>? {
|
||||
if (TypeUtils.noExpectedType(expectedType) || expectedType.isError) {
|
||||
return IntegerValueTypeConstant(value, builtIns, parameters)
|
||||
return IntegerValueTypeConstant(value, constantExpressionEvaluator.module, parameters)
|
||||
}
|
||||
val integerValue = ConstantValueFactory.createIntegerConstantValue(value, expectedType)
|
||||
val integerValue = ConstantValueFactory.createIntegerConstantValue(value, expectedType, parameters.isUnsigned)
|
||||
if (integerValue != null) {
|
||||
return integerValue.wrap(parameters)
|
||||
}
|
||||
return when (value) {
|
||||
value.toInt().toLong() -> IntValue(value.toInt())
|
||||
else -> LongValue(value)
|
||||
value.toInt().toLong() ->
|
||||
if (parameters.isUnsigned) UIntValue(value.toInt()) else IntValue(value.toInt())
|
||||
else ->
|
||||
if (parameters.isUnsigned) ULongValue(value) else LongValue(value)
|
||||
}.wrap(parameters)
|
||||
}
|
||||
|
||||
@@ -941,13 +955,15 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
private fun <T> ConstantValue<T>.wrap(
|
||||
canBeUsedInAnnotation: Boolean = this !is NullValue,
|
||||
isPure: Boolean = false,
|
||||
isUnsigned: Boolean = false,
|
||||
usesVariableAsConstant: Boolean = false,
|
||||
usesNonConstValAsConstant: Boolean = false
|
||||
): TypedCompileTimeConstant<T> =
|
||||
wrap(CompileTimeConstant.Parameters(canBeUsedInAnnotation, isPure, usesVariableAsConstant, usesNonConstValAsConstant))
|
||||
wrap(CompileTimeConstant.Parameters(canBeUsedInAnnotation, isPure, isUnsigned, usesVariableAsConstant, usesNonConstValAsConstant))
|
||||
}
|
||||
|
||||
private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L')
|
||||
private fun hasUnsignedSuffix(text: String) = text.endsWith('u')
|
||||
|
||||
private fun parseNumericLiteral(text: String, type: IElementType): Any? {
|
||||
val canonicalText = LiteralFormatUtil.removeUnderscores(text)
|
||||
@@ -960,8 +976,8 @@ private fun parseNumericLiteral(text: String, type: IElementType): Any? {
|
||||
|
||||
private fun parseLong(text: String): Long? {
|
||||
try {
|
||||
fun substringLongSuffix(s: String) = if (hasLongSuffix(text)) s.substring(0, s.length - 1) else s
|
||||
fun parseLong(text: String, radix: Int) = java.lang.Long.parseLong(substringLongSuffix(text), radix)
|
||||
fun substringSuffix(s: String) = if (hasLongSuffix(text) || hasUnsignedSuffix(text)) s.substring(0, s.length - 1) else s
|
||||
fun parseLong(text: String, radix: Int) = java.lang.Long.parseLong(substringSuffix(text), radix)
|
||||
|
||||
val (number, radix) = extractRadix(text)
|
||||
return parseLong(number, radix)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// !SKIP_METADATA_VERSION_CHECK
|
||||
// WITH_UNSIGNED
|
||||
|
||||
fun box(): String {
|
||||
val u1 = 1u
|
||||
val u2 = 2u
|
||||
val u3 = u1 + u2
|
||||
if (u3.toInt() != 3) return "fail"
|
||||
|
||||
val max = 0u.dec().toLong()
|
||||
val expected = Int.MAX_VALUE * 2L + 1
|
||||
if (max != expected) return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// !SKIP_METADATA_VERSION_CHECK
|
||||
// WITH_UNSIGNED
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER")
|
||||
fun box(): String {
|
||||
val u1 = UInt(1)
|
||||
val u2 = UInt(2)
|
||||
val u3 = u1 + u2
|
||||
return if (u3.toInt() == 3) "OK" else "fail"
|
||||
}
|
||||
+9
-2
@@ -25,8 +25,10 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.TypeResolver
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
@@ -64,8 +66,13 @@ class ConstraintSystemTestData(
|
||||
val matcher = INTEGER_VALUE_TYPE_PATTERN.matcher(name)
|
||||
if (matcher.find()) {
|
||||
val number = matcher.group(1)!!
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(Annotations.EMPTY, IntegerValueTypeConstructor(number.toLong(), functionFoo.builtIns),
|
||||
listOf(), false, MemberScope.Empty
|
||||
val parameters = CompileTimeConstant.Parameters(false, false, false, false, false)
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||
Annotations.EMPTY,
|
||||
IntegerValueTypeConstructor(number.toLong(), functionFoo.module, parameters),
|
||||
listOf(),
|
||||
false,
|
||||
MemberScope.Empty
|
||||
)
|
||||
}
|
||||
return typeResolver.resolveType(
|
||||
|
||||
Generated
+5
-5
@@ -11179,6 +11179,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callComputablePropertyInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBasicUnsignedLiterals.kt")
|
||||
public void testCheckBasicUnsignedLiterals() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt")
|
||||
public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt");
|
||||
@@ -11229,11 +11234,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkPlusOfUInt.kt")
|
||||
public void testCheckPlusOfUInt() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkPlusOfUInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkUnboxingResultFromTypeVariable.kt")
|
||||
public void testCheckUnboxingResultFromTypeVariable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkUnboxingResultFromTypeVariable.kt");
|
||||
|
||||
+5
-5
@@ -11179,6 +11179,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callComputablePropertyInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBasicUnsignedLiterals.kt")
|
||||
public void testCheckBasicUnsignedLiterals() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt")
|
||||
public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt");
|
||||
@@ -11229,11 +11234,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkPlusOfUInt.kt")
|
||||
public void testCheckPlusOfUInt() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkPlusOfUInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkUnboxingResultFromTypeVariable.kt")
|
||||
public void testCheckUnboxingResultFromTypeVariable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkUnboxingResultFromTypeVariable.kt");
|
||||
|
||||
+5
-5
@@ -11179,6 +11179,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callComputablePropertyInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBasicUnsignedLiterals.kt")
|
||||
public void testCheckBasicUnsignedLiterals() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt")
|
||||
public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt");
|
||||
@@ -11229,11 +11234,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkPlusOfUInt.kt")
|
||||
public void testCheckPlusOfUInt() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkPlusOfUInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkUnboxingResultFromTypeVariable.kt")
|
||||
public void testCheckUnboxingResultFromTypeVariable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkUnboxingResultFromTypeVariable.kt");
|
||||
|
||||
@@ -332,6 +332,15 @@ public abstract class KotlinBuiltIns {
|
||||
public final FqNameUnsafe kMutableProperty2 = reflect("KMutableProperty2");
|
||||
public final ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe());
|
||||
|
||||
public final FqName uByteFqName = fqName("UByte");
|
||||
public final FqName uShortFqName = fqName("UShort");
|
||||
public final FqName uIntFqName = fqName("UInt");
|
||||
public final FqName uLongFqName = fqName("ULong");
|
||||
public final ClassId uByte = ClassId.topLevel(uByteFqName);
|
||||
public final ClassId uShort = ClassId.topLevel(uShortFqName);
|
||||
public final ClassId uInt = ClassId.topLevel(uIntFqName);
|
||||
public final ClassId uLong = ClassId.topLevel(uLongFqName);
|
||||
|
||||
public final Set<Name> primitiveTypeShortNames = newHashSetWithExpectedSize(PrimitiveType.values().length);
|
||||
public final Set<Name> primitiveArrayTypeShortNames = newHashSetWithExpectedSize(PrimitiveType.values().length);
|
||||
public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType = newHashMapWithExpectedSize(PrimitiveType.values().length);
|
||||
@@ -975,6 +984,22 @@ public abstract class KotlinBuiltIns {
|
||||
return isDoubleOrNullableDouble(type) && !type.isMarkedNullable();
|
||||
}
|
||||
|
||||
public static boolean isUByte(@NotNull KotlinType type) {
|
||||
return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.uByteFqName.toUnsafe());
|
||||
}
|
||||
|
||||
public static boolean isUShort(@NotNull KotlinType type) {
|
||||
return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.uShortFqName.toUnsafe());
|
||||
}
|
||||
|
||||
public static boolean isUInt(@NotNull KotlinType type) {
|
||||
return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.uIntFqName.toUnsafe());
|
||||
}
|
||||
|
||||
public static boolean isULong(@NotNull KotlinType type) {
|
||||
return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.uLongFqName.toUnsafe());
|
||||
}
|
||||
|
||||
public static boolean isDoubleOrNullableDouble(@NotNull KotlinType type) {
|
||||
return isConstructedFromGivenClass(type, FQ_NAMES._double);
|
||||
}
|
||||
|
||||
@@ -42,9 +42,12 @@ interface CompileTimeConstant<out T> {
|
||||
|
||||
val isPure: Boolean get() = parameters.isPure
|
||||
|
||||
val isUnsigned: Boolean get() = parameters.isUnsigned
|
||||
|
||||
class Parameters(
|
||||
val canBeUsedInAnnotation: Boolean,
|
||||
val isPure: Boolean,
|
||||
val isUnsigned: Boolean,
|
||||
val usesVariableAsConstant: Boolean,
|
||||
val usesNonConstValAsConstant: Boolean
|
||||
)
|
||||
@@ -84,10 +87,10 @@ class TypedCompileTimeConstant<out T>(
|
||||
|
||||
class IntegerValueTypeConstant(
|
||||
private val value: Number,
|
||||
builtIns: KotlinBuiltIns,
|
||||
module: ModuleDescriptor,
|
||||
override val parameters: CompileTimeConstant.Parameters
|
||||
) : CompileTimeConstant<Number> {
|
||||
private val typeConstructor = IntegerValueTypeConstructor(value.toLong(), builtIns)
|
||||
private val typeConstructor = IntegerValueTypeConstructor(value.toLong(), module, parameters)
|
||||
|
||||
override fun toConstantValue(expectedType: KotlinType): ConstantValue<Number> {
|
||||
val type = getType(expectedType)
|
||||
@@ -95,6 +98,13 @@ class IntegerValueTypeConstant(
|
||||
KotlinBuiltIns.isInt(type) -> IntValue(value.toInt())
|
||||
KotlinBuiltIns.isByte(type) -> ByteValue(value.toByte())
|
||||
KotlinBuiltIns.isShort(type) -> ShortValue(value.toShort())
|
||||
KotlinBuiltIns.isLong(type) -> LongValue(value.toLong())
|
||||
|
||||
KotlinBuiltIns.isUInt(type) -> UIntValue(value.toInt())
|
||||
KotlinBuiltIns.isUByte(type) -> UByteValue(value.toByte())
|
||||
KotlinBuiltIns.isUShort(type) -> UShortValue(value.toShort())
|
||||
KotlinBuiltIns.isULong(type) -> ULongValue(value.toLong())
|
||||
|
||||
else -> LongValue(value.toLong())
|
||||
}
|
||||
}
|
||||
|
||||
+23
-13
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.resolve.constants
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
@@ -51,10 +50,10 @@ object ConstantValueFactory {
|
||||
|
||||
fun createUnsignedValue(constantValue: ConstantValue<*>, type: KotlinType): UnsignedValueConstant<*>? {
|
||||
return when (constantValue) {
|
||||
is ByteValue -> UByteValue(constantValue, type)
|
||||
is ShortValue -> UShortValue(constantValue, type)
|
||||
is IntValue -> UIntValue(constantValue, type)
|
||||
is LongValue -> ULongValue(constantValue, type)
|
||||
is ByteValue -> UByteValue(constantValue.value)
|
||||
is ShortValue -> UShortValue(constantValue.value)
|
||||
is IntValue -> UIntValue(constantValue.value)
|
||||
is LongValue -> ULongValue(constantValue.value)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -66,16 +65,27 @@ object ConstantValueFactory {
|
||||
|
||||
fun createIntegerConstantValue(
|
||||
value: Long,
|
||||
expectedType: KotlinType
|
||||
expectedType: KotlinType,
|
||||
isUnsigned: Boolean
|
||||
): ConstantValue<*>? {
|
||||
val notNullExpected = TypeUtils.makeNotNullable(expectedType)
|
||||
return when {
|
||||
KotlinBuiltIns.isLong(notNullExpected) -> LongValue(value)
|
||||
KotlinBuiltIns.isInt(notNullExpected) && value == value.toInt().toLong() -> IntValue(value.toInt())
|
||||
KotlinBuiltIns.isShort(notNullExpected) && value == value.toShort().toLong() -> ShortValue(value.toShort())
|
||||
KotlinBuiltIns.isByte(notNullExpected) && value == value.toByte().toLong() -> ByteValue(value.toByte())
|
||||
KotlinBuiltIns.isChar(notNullExpected) -> IntValue(value.toInt())
|
||||
else -> null
|
||||
return if (isUnsigned) {
|
||||
when {
|
||||
KotlinBuiltIns.isUByte(notNullExpected) && value == value.toByte().toLong() -> UByteValue(value.toByte())
|
||||
KotlinBuiltIns.isUShort(notNullExpected) && value == value.toShort().toLong() -> UShortValue(value.toShort())
|
||||
KotlinBuiltIns.isUInt(notNullExpected) && value == value.toInt().toLong() -> UIntValue(value.toInt())
|
||||
KotlinBuiltIns.isULong(notNullExpected) -> ULongValue(value)
|
||||
else -> null
|
||||
}
|
||||
} else {
|
||||
when {
|
||||
KotlinBuiltIns.isLong(notNullExpected) -> LongValue(value)
|
||||
KotlinBuiltIns.isInt(notNullExpected) && value == value.toInt().toLong() -> IntValue(value.toInt())
|
||||
KotlinBuiltIns.isShort(notNullExpected) && value == value.toShort().toLong() -> ShortValue(value.toShort())
|
||||
KotlinBuiltIns.isByte(notNullExpected) && value == value.toByte().toLong() -> ByteValue(value.toByte())
|
||||
KotlinBuiltIns.isChar(notNullExpected) -> IntValue(value.toInt())
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-7
@@ -17,14 +17,20 @@
|
||||
package org.jetbrains.kotlin.resolve.constants
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import java.util.*
|
||||
|
||||
class IntegerValueTypeConstructor(
|
||||
private val value: Long,
|
||||
private val builtIns: KotlinBuiltIns
|
||||
private val value: Long,
|
||||
private val module: ModuleDescriptor,
|
||||
parameters: CompileTimeConstant.Parameters
|
||||
) : TypeConstructor {
|
||||
private val supertypes = ArrayList<KotlinType>(4)
|
||||
|
||||
@@ -32,10 +38,28 @@ class IntegerValueTypeConstructor(
|
||||
// order of types matters
|
||||
// 'getPrimitiveNumberType' returns first of supertypes that is a subtype of expected type
|
||||
// for expected type 'Any' result type 'Int' should be returned
|
||||
checkBoundsAndAddSuperType(value, Integer.MIN_VALUE.toLong(), Integer.MAX_VALUE.toLong(), builtIns.intType)
|
||||
checkBoundsAndAddSuperType(value, java.lang.Byte.MIN_VALUE.toLong(), java.lang.Byte.MAX_VALUE.toLong(), builtIns.byteType)
|
||||
checkBoundsAndAddSuperType(value, java.lang.Short.MIN_VALUE.toLong(), java.lang.Short.MAX_VALUE.toLong(), builtIns.shortType)
|
||||
supertypes.add(builtIns.longType)
|
||||
val isUnsigned = parameters.isUnsigned
|
||||
|
||||
// TODO: fix value ranges for unsigned types
|
||||
checkBoundsAndAddSuperType(
|
||||
value,
|
||||
Integer.MIN_VALUE.toLong(),
|
||||
Integer.MAX_VALUE.toLong(),
|
||||
if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uInt) else builtIns.intType
|
||||
)
|
||||
checkBoundsAndAddSuperType(
|
||||
value,
|
||||
java.lang.Byte.MIN_VALUE.toLong(),
|
||||
java.lang.Byte.MAX_VALUE.toLong(),
|
||||
if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uByte) else builtIns.byteType
|
||||
)
|
||||
checkBoundsAndAddSuperType(
|
||||
value,
|
||||
java.lang.Short.MIN_VALUE.toLong(),
|
||||
java.lang.Short.MAX_VALUE.toLong(),
|
||||
if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uShort) else builtIns.shortType
|
||||
)
|
||||
supertypes.add(if (isUnsigned) unsignedType(KotlinBuiltIns.FQ_NAMES.uLong) else builtIns.longType)
|
||||
}
|
||||
|
||||
private fun checkBoundsAndAddSuperType(value: Long, minValue: Long, maxValue: Long, kotlinType: KotlinType) {
|
||||
@@ -44,6 +68,9 @@ class IntegerValueTypeConstructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun unsignedType(classId: ClassId): SimpleType =
|
||||
module.findClassAcrossModuleDependencies(classId)?.defaultType ?: ErrorUtils.createErrorType("Error type for $classId")
|
||||
|
||||
override fun getSupertypes(): Collection<KotlinType> = supertypes
|
||||
|
||||
override fun getParameters(): List<TypeParameterDescriptor> = emptyList()
|
||||
@@ -57,7 +84,7 @@ class IntegerValueTypeConstructor(
|
||||
fun getValue(): Long = value
|
||||
|
||||
override fun getBuiltIns(): KotlinBuiltIns {
|
||||
return builtIns
|
||||
return module.builtIns
|
||||
}
|
||||
|
||||
override fun toString() = "IntegerValueType($value)"
|
||||
|
||||
@@ -40,9 +40,7 @@ abstract class ConstantValue<out T>(open val value: T) {
|
||||
}
|
||||
|
||||
abstract class IntegerValueConstant<out T> protected constructor(value: T) : ConstantValue<T>(value)
|
||||
abstract class UnsignedValueConstant<out T> protected constructor(value: T, private val kotlinType: KotlinType) : ConstantValue<T>(value) {
|
||||
override fun getType(module: ModuleDescriptor): KotlinType = kotlinType
|
||||
}
|
||||
abstract class UnsignedValueConstant<out T> protected constructor(value: T) : ConstantValue<T>(value)
|
||||
|
||||
class AnnotationValue(value: AnnotationDescriptor) : ConstantValue<AnnotationDescriptor>(value) {
|
||||
override fun getType(module: ModuleDescriptor): KotlinType = value.type
|
||||
@@ -193,25 +191,45 @@ class StringValue(value: String) : ConstantValue<String>(value) {
|
||||
override fun toString() = "\"$value\""
|
||||
}
|
||||
|
||||
class UByteValue(byteValue: ByteValue, kotlinType: KotlinType) : UnsignedValueConstant<Byte>(byteValue.value, kotlinType) {
|
||||
class UByteValue(byteValue: Byte) : UnsignedValueConstant<Byte>(byteValue) {
|
||||
override fun getType(module: ModuleDescriptor): KotlinType {
|
||||
return module.findClassAcrossModuleDependencies(KotlinBuiltIns.FQ_NAMES.uByte)?.defaultType
|
||||
?: ErrorUtils.createErrorType("Unsigned type UByte not found")
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitUByteValue(this, data)
|
||||
|
||||
override fun toString() = "$value.toUByte()"
|
||||
}
|
||||
|
||||
class UShortValue(shortValue: ShortValue, kotlinType: KotlinType) : UnsignedValueConstant<Short>(shortValue.value, kotlinType) {
|
||||
class UShortValue(shortValue: Short) : UnsignedValueConstant<Short>(shortValue) {
|
||||
override fun getType(module: ModuleDescriptor): KotlinType {
|
||||
return module.findClassAcrossModuleDependencies(KotlinBuiltIns.FQ_NAMES.uShort)?.defaultType
|
||||
?: ErrorUtils.createErrorType("Unsigned type UByte not found")
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitUShortValue(this, data)
|
||||
|
||||
override fun toString() = "$value.toUShort()"
|
||||
}
|
||||
|
||||
class UIntValue(intValue: IntValue, kotlinType: KotlinType) : UnsignedValueConstant<Int>(intValue.value, kotlinType) {
|
||||
class UIntValue(intValue: Int) : UnsignedValueConstant<Int>(intValue) {
|
||||
override fun getType(module: ModuleDescriptor): KotlinType {
|
||||
return module.findClassAcrossModuleDependencies(KotlinBuiltIns.FQ_NAMES.uInt)?.defaultType
|
||||
?: ErrorUtils.createErrorType("Unsigned type UByte not found")
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D) = visitor.visitUIntValue(this, data)
|
||||
|
||||
override fun toString() = "$value.toUInt()"
|
||||
}
|
||||
|
||||
class ULongValue(longValue: LongValue, kotlinType: KotlinType) : UnsignedValueConstant<Long>(longValue.value, kotlinType) {
|
||||
class ULongValue(longValue: Long) : UnsignedValueConstant<Long>(longValue) {
|
||||
override fun getType(module: ModuleDescriptor): KotlinType {
|
||||
return module.findClassAcrossModuleDependencies(KotlinBuiltIns.FQ_NAMES.uLong)?.defaultType
|
||||
?: ErrorUtils.createErrorType("Unsigned type UByte not found")
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitULongValue(this, data)
|
||||
|
||||
override fun toString() = "$value.toULong()"
|
||||
|
||||
@@ -15,6 +15,9 @@ import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
@@ -445,6 +448,27 @@ public class TypeUtils {
|
||||
if (supertypes.contains(longType)) {
|
||||
return longType;
|
||||
}
|
||||
|
||||
KotlinType uIntType = findByFqName(supertypes, KotlinBuiltIns.FQ_NAMES.uIntFqName);
|
||||
if (uIntType != null) return uIntType;
|
||||
|
||||
KotlinType uLongType = findByFqName(supertypes, KotlinBuiltIns.FQ_NAMES.uLongFqName);
|
||||
if (uLongType != null) return uLongType;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static KotlinType findByFqName(@NotNull Collection<KotlinType> supertypes, FqName fqName) {
|
||||
for (KotlinType supertype : supertypes) {
|
||||
ClassifierDescriptor descriptor = supertype.getConstructor().getDeclarationDescriptor();
|
||||
if (descriptor == null) continue;
|
||||
|
||||
FqNameUnsafe descriptorFqName = DescriptorUtils.getFqName(descriptor);
|
||||
if (descriptorFqName.equals(fqName.toUnsafe())) {
|
||||
return supertype;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -9715,6 +9715,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callComputablePropertyInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBasicUnsignedLiterals.kt")
|
||||
public void testCheckBasicUnsignedLiterals() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt")
|
||||
public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt");
|
||||
@@ -9765,11 +9770,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkPlusOfUInt.kt")
|
||||
public void testCheckPlusOfUInt() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkPlusOfUInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("checkUnboxingResultFromTypeVariable.kt")
|
||||
public void testCheckUnboxingResultFromTypeVariable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/checkUnboxingResultFromTypeVariable.kt");
|
||||
|
||||
Reference in New Issue
Block a user