Load unsigned constants from class file with the use of expected type

This commit is contained in:
Mikhail Zarechenskiy
2018-07-09 13:28:10 +03:00
parent 9b6e8fa5d1
commit 14b8ff7d71
6 changed files with 45 additions and 3 deletions
@@ -5,17 +5,27 @@
@kotlin.annotation.Target(AnnotationTarget.TYPE, AnnotationTarget.FUNCTION)
annotation class Anno(val u: UInt)
const val ONE_UINT = 1u
object ForTest {
@Anno(0u)
fun f(a: @Anno(43u) String) {}
@Anno(ONE_UINT)
fun g(b: @Anno(ONE_UINT) String) {}
}
// FILE: B.kt
fun box(): String {
val result = (ForTest::f.annotations.first() as Anno).u // force annotation deserialization
if (result != 0u) return "Fail"
val fResult = (ForTest::f.annotations.first() as Anno).u // force annotation deserialization
if (fResult != 0u) return "Fail"
val gResult = (ForTest::g.annotations.first() as Anno).u
if (gResult != 1u) return "Fail"
if (ONE_UINT != 1u) return "Fail"
return "OK"
}
@@ -10,7 +10,13 @@ annotation class Ann(
val ulong: ULong
)
const val ubyteConst: UByte = 10u
const val ushortConst: UShort = 20u
const val uintConst = 30u
const val ulongConst = 40uL
class A {
fun unsigned(s: @Ann(1u, 2u, 3u, 4u) String) {}
fun <@Ann(0xFFu, 0xFFFFu, 0xFFFF_FFFFu, 0xFFFF_FFFF_FFFF_FFFFuL) T> typeParam() {}
fun unsignedConsts(s: @Ann(ubyteConst, ushortConst, uintConst, ulongConst) String) {}
}
@@ -1,9 +1,19 @@
package test
public const val ubyteConst: kotlin.UByte = 10.toUByte()
public fun <get-ubyteConst>(): kotlin.UByte
public const val uintConst: kotlin.UInt = 30.toUInt()
public fun <get-uintConst>(): kotlin.UInt
public const val ulongConst: kotlin.ULong = 40.toULong()
public fun <get-ulongConst>(): kotlin.ULong
public const val ushortConst: kotlin.UShort = 20.toUShort()
public fun <get-ushortConst>(): kotlin.UShort
public final class A {
/*primary*/ public constructor A()
public final fun </*0*/ @test.Ann(ubyte = -1.toUByte(), uint = -1.toUInt(), ulong = -1.toULong(), ushort = -1.toUShort()) T> typeParam(): kotlin.Unit
public final fun unsigned(/*0*/ s: @test.Ann(ubyte = 1.toUByte(), uint = 3.toUInt(), ulong = 4.toULong(), ushort = 2.toUShort()) kotlin.String): kotlin.Unit
public final fun unsignedConsts(/*0*/ s: @test.Ann(ubyte = 10.toUByte(), uint = 30.toUInt(), ulong = 40.toULong(), ushort = 20.toUShort()) kotlin.String): kotlin.Unit
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER}) public final annotation class Ann : kotlin.Annotation {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.load.java.JvmAbi
@@ -48,6 +49,8 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
protected abstract fun loadConstant(desc: String, initializer: Any): C?
protected abstract fun transformToUnsignedConstant(constant: C): C?
protected abstract fun loadAnnotation(
annotationClassId: ClassId,
source: SourceElement,
@@ -202,7 +205,8 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
val specialCase = getSpecialCaseContainerClass(container, property = true, field = true, isConst = Flags.IS_CONST.get(proto.flags))
val kotlinClass = findClassWithAnnotationsAndInitializers(container, specialCase) ?: return null
return storage(kotlinClass).propertyConstants[signature]
val constant = storage(kotlinClass).propertyConstants[signature] ?: return null
return if (UnsignedTypes.isUnsignedType(expectedType)) transformToUnsignedConstant(constant) else constant
}
private fun findClassWithAnnotationsAndInitializers(
@@ -64,6 +64,16 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
return ConstantValueFactory.createConstantValue(normalizedValue)
}
override fun transformToUnsignedConstant(constant: ConstantValue<*>): ConstantValue<*>? {
return when (constant) {
is ByteValue -> UByteValue(constant.value)
is ShortValue -> UShortValue(constant.value)
is IntValue -> UIntValue(constant.value)
is LongValue -> ULongValue(constant.value)
else -> constant
}
}
override fun loadPropertyAnnotations(
propertyAnnotations: List<AnnotationDescriptor>,
fieldAnnotations: List<AnnotationDescriptor>,
@@ -126,6 +126,8 @@ class AnnotationLoaderForClassFileStubBuilder(
override fun loadConstant(desc: String, initializer: Any) = null
override fun transformToUnsignedConstant(constant: Unit) = null
override fun loadAnnotation(
annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {