Support primitive array annotation arguments in ConstantValueFactory

This has no visible consequences at the moment, but will help once we
need to load such argument from some annotation in the compiler in the
future
This commit is contained in:
Alexander Udalov
2017-06-22 18:55:55 +03:00
parent b67542533b
commit e42b151561
8 changed files with 91 additions and 6 deletions
@@ -0,0 +1,24 @@
package test
annotation class Anno(
val bytes: ByteArray,
val shorts: ShortArray,
val ints: IntArray,
val longs: LongArray,
val chars: CharArray,
val floats: FloatArray,
val doubles: DoubleArray,
val booleans: BooleanArray
)
@Anno(
byteArrayOf(42.toByte(), (-1).toByte()),
shortArrayOf((-42).toShort(), 0.toShort()),
intArrayOf(42, 239),
longArrayOf(42L, 239L),
charArrayOf('a', 'Z'),
floatArrayOf(2.72f, 0.0f),
doubleArrayOf(42.0, -3.14),
booleanArrayOf(true, false)
)
class Klass
@@ -0,0 +1,25 @@
package test
public final annotation class Anno : kotlin.Annotation {
/*primary*/ public constructor Anno(/*0*/ bytes: kotlin.ByteArray, /*1*/ shorts: kotlin.ShortArray, /*2*/ ints: kotlin.IntArray, /*3*/ longs: kotlin.LongArray, /*4*/ chars: kotlin.CharArray, /*5*/ floats: kotlin.FloatArray, /*6*/ doubles: kotlin.DoubleArray, /*7*/ booleans: kotlin.BooleanArray)
public final val booleans: kotlin.BooleanArray
public final fun <get-booleans>(): kotlin.BooleanArray
public final val bytes: kotlin.ByteArray
public final fun <get-bytes>(): kotlin.ByteArray
public final val chars: kotlin.CharArray
public final fun <get-chars>(): kotlin.CharArray
public final val doubles: kotlin.DoubleArray
public final fun <get-doubles>(): kotlin.DoubleArray
public final val floats: kotlin.FloatArray
public final fun <get-floats>(): kotlin.FloatArray
public final val ints: kotlin.IntArray
public final fun <get-ints>(): kotlin.IntArray
public final val longs: kotlin.LongArray
public final fun <get-longs>(): kotlin.LongArray
public final val shorts: kotlin.ShortArray
public final fun <get-shorts>(): kotlin.ShortArray
}
@test.Anno(booleans = {true, false}, bytes = {42.toByte(), -1.toByte()}, chars = {\u0061 ('a'), \u005A ('Z')}, doubles = {42.0.toDouble(), -3.14.toDouble()}, floats = {2.72.toFloat(), 0.0.toFloat()}, ints = {42, 239}, longs = {42.toLong(), 239.toLong()}, shorts = {-42.toShort(), 0.toShort()}) public final class Klass {
/*primary*/ public constructor Klass()
}
@@ -1852,6 +1852,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
doTestCompiledKotlin(fileName);
}
@TestMetadata("PrimitiveArrayArguments.kt")
public void testPrimitiveArrayArguments() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt");
doTestCompiledKotlin(fileName);
}
@TestMetadata("SimpleAnnotation.kt")
public void testSimpleAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/SimpleAnnotation.kt");
@@ -74,6 +74,12 @@ public class LoadKotlinWithTypeTableTestGenerated extends AbstractLoadKotlinWith
doTest(fileName);
}
@TestMetadata("PrimitiveArrayArguments.kt")
public void testPrimitiveArrayArguments() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt");
doTest(fileName);
}
@TestMetadata("SimpleAnnotation.kt")
public void testSimpleAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/SimpleAnnotation.kt");
@@ -76,6 +76,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
doTest(fileName);
}
@TestMetadata("PrimitiveArrayArguments.kt")
public void testPrimitiveArrayArguments() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt");
doTest(fileName);
}
@TestMetadata("SimpleAnnotation.kt")
public void testSimpleAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/SimpleAnnotation.kt");
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.compactIfPossible
import java.util.*
class BinaryClassAnnotationAndConstantLoaderImpl(
@@ -115,8 +116,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
override fun visitEnd() {
val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass)
if (parameter != null) {
elements.trimToSize()
arguments[parameter] = factory.createArrayValue(elements, parameter.type)
arguments[parameter] = factory.createArrayValue(elements.compactIfPossible(), parameter.type)
}
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.constants
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.types.KotlinType
@@ -58,10 +59,7 @@ class ConstantValueFactory(
fun createKClassValue(type: KotlinType) = KClassValue(type)
fun createConstantValue(
value: Any?
): ConstantValue<*>? {
// TODO: primitive arrays
fun createConstantValue(value: Any?): ConstantValue<*>? {
return when (value) {
is Byte -> createByteValue(value)
is Short -> createShortValue(value)
@@ -72,11 +70,25 @@ class ConstantValueFactory(
is Double -> createDoubleValue(value)
is Boolean -> createBooleanValue(value)
is String -> createStringValue(value)
is ByteArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.BYTE.arrayType())
is ShortArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.SHORT.arrayType())
is IntArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.INT.arrayType())
is LongArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.LONG.arrayType())
is CharArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.CHAR.arrayType())
is FloatArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.FLOAT.arrayType())
is DoubleArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.DOUBLE.arrayType())
is BooleanArray -> createArrayValue(value.toList().arrayToList(), PrimitiveType.BOOLEAN.arrayType())
null -> createNullValue()
else -> null
}
}
private fun List<*>.arrayToList(): List<ConstantValue<*>> =
this.toList().mapNotNull { createConstantValue(it) }
private fun PrimitiveType.arrayType(): KotlinType =
builtins.getPrimitiveArrayKotlinType(this)
fun createIntegerConstantValue(
value: Long,
expectedType: KotlinType
@@ -74,6 +74,12 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest {
doTest(fileName);
}
@TestMetadata("PrimitiveArrayArguments.kt")
public void testPrimitiveArrayArguments() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt");
doTest(fileName);
}
@TestMetadata("SimpleAnnotation.kt")
public void testSimpleAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/SimpleAnnotation.kt");