Support constant evaluation of unsigned type constructors
#KT-23816 In Progress
This commit is contained in:
@@ -69,12 +69,14 @@ class TypeMappingMode private constructor(
|
||||
|
||||
/**
|
||||
* kotlin.reflect.KClass mapped to java.lang.Class
|
||||
* primitive types and inline class types are not boxed because types in annotations cannot be nullable
|
||||
* Other types mapped as DEFAULT
|
||||
*/
|
||||
@JvmField
|
||||
val VALUE_FOR_ANNOTATION = TypeMappingMode(
|
||||
isForAnnotationParameter = true,
|
||||
needPrimitiveBoxing = false,
|
||||
needInlineClassWrapping = false,
|
||||
genericArgumentMode = TypeMappingMode(isForAnnotationParameter = true, genericArgumentMode = GENERIC_ARGUMENT))
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.builtins
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
enum class UnsignedType(val typeName: Name) {
|
||||
UBYTE("UByte"), USHORT("UShort"), UINT("UInt"), ULONG("ULong");
|
||||
|
||||
constructor(typeName: String) : this(Name.identifier(typeName))
|
||||
}
|
||||
|
||||
object UnsignedTypes {
|
||||
val unsignedTypeNames = enumValues<UnsignedType>().map { it.typeName }.toSet()
|
||||
|
||||
fun isUnsignedType(type: KotlinType): Boolean {
|
||||
val descriptor = type.constructor.declarationDescriptor ?: return false
|
||||
return isUnsignedClass(descriptor)
|
||||
}
|
||||
|
||||
fun isUnsignedClass(descriptor: DeclarationDescriptor): Boolean {
|
||||
val container = descriptor.containingDeclaration
|
||||
return container is PackageFragmentDescriptor &&
|
||||
container.fqName == KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME &&
|
||||
descriptor.name in UnsignedTypes.unsignedTypeNames
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
package org.jetbrains.kotlin.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
@@ -26,4 +27,6 @@ object ConstUtil {
|
||||
@JvmStatic fun canBeUsedForConstVal(type: KotlinType) = type.canBeUsedForConstVal()
|
||||
}
|
||||
|
||||
fun KotlinType.canBeUsedForConstVal() = KotlinBuiltIns.isPrimitiveType(this) && !TypeUtils.isNullableType(this) || KotlinBuiltIns.isString(this)
|
||||
fun KotlinType.canBeUsedForConstVal() =
|
||||
(KotlinBuiltIns.isPrimitiveType(this) || UnsignedTypes.isUnsignedType(this)) && !TypeUtils.isNullableType(this) ||
|
||||
KotlinBuiltIns.isString(this)
|
||||
|
||||
+8
@@ -50,4 +50,12 @@ public interface AnnotationArgumentVisitor<R, D> {
|
||||
R visitAnnotationValue(AnnotationValue value, D data);
|
||||
|
||||
R visitKClassValue(KClassValue value, D data);
|
||||
|
||||
R visitUByteValue(UByteValue value, D data);
|
||||
|
||||
R visitUShortValue(UShortValue value, D data);
|
||||
|
||||
R visitUIntValue(UIntValue value, D data);
|
||||
|
||||
R visitULongValue(ULongValue value, D data);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
@@ -457,7 +458,8 @@ public class DescriptorUtils {
|
||||
return KotlinBuiltIns.isPrimitiveType(type) ||
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getStringType(), type) ||
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getNumber().getDefaultType(), type) ||
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getAnyType(), type);
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getAnyType(), type) ||
|
||||
UnsignedTypes.INSTANCE.isUnsignedType(type);
|
||||
}
|
||||
|
||||
public static boolean classCanHaveAbstractFakeOverride(@NotNull ClassDescriptor classDescriptor) {
|
||||
|
||||
@@ -18,6 +18,7 @@ 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
|
||||
|
||||
@@ -48,6 +49,16 @@ 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)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createArrayValue(value: List<*>, componentType: PrimitiveType): ArrayValue =
|
||||
ArrayValue(value.toList().mapNotNull(this::createConstantValue)) { module ->
|
||||
module.builtIns.getPrimitiveArrayKotlinType(componentType)
|
||||
|
||||
@@ -40,6 +40,9 @@ 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
|
||||
}
|
||||
|
||||
class AnnotationValue(value: AnnotationDescriptor) : ConstantValue<AnnotationDescriptor>(value) {
|
||||
override fun getType(module: ModuleDescriptor): KotlinType = value.type
|
||||
@@ -189,3 +192,27 @@ class StringValue(value: String) : ConstantValue<String>(value) {
|
||||
|
||||
override fun toString() = "\"$value\""
|
||||
}
|
||||
|
||||
class UByteValue(byteValue: ByteValue, kotlinType: KotlinType) : UnsignedValueConstant<Byte>(byteValue.value, kotlinType) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitULongValue(this, data)
|
||||
|
||||
override fun toString() = "$value.toULong()"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user