From e42b1515615c2a5e2e6a90e09974b77521fc1bc8 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 22 Jun 2017 18:55:55 +0300 Subject: [PATCH] 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 --- .../annotations/PrimitiveArrayArguments.kt | 24 ++++++++++++++++++ .../annotations/PrimitiveArrayArguments.txt | 25 +++++++++++++++++++ .../jvm/compiler/LoadJavaTestGenerated.java | 6 +++++ .../LoadKotlinWithTypeTableTestGenerated.java | 6 +++++ ...mRuntimeDescriptorLoaderTestGenerated.java | 6 +++++ ...aryClassAnnotationAndConstantLoaderImpl.kt | 4 +-- .../resolve/constants/ConstantValueFactory.kt | 20 ++++++++++++--- .../stubs/ResolveByStubTestGenerated.java | 6 +++++ 8 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt create mode 100644 compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.txt diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt b/compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt new file mode 100644 index 00000000000..840649f3de7 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.kt @@ -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 diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.txt b/compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.txt new file mode 100644 index 00000000000..d6ae4abe091 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/PrimitiveArrayArguments.txt @@ -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 (): kotlin.BooleanArray + public final val bytes: kotlin.ByteArray + public final fun (): kotlin.ByteArray + public final val chars: kotlin.CharArray + public final fun (): kotlin.CharArray + public final val doubles: kotlin.DoubleArray + public final fun (): kotlin.DoubleArray + public final val floats: kotlin.FloatArray + public final fun (): kotlin.FloatArray + public final val ints: kotlin.IntArray + public final fun (): kotlin.IntArray + public final val longs: kotlin.LongArray + public final fun (): kotlin.LongArray + public final val shorts: kotlin.ShortArray + public final fun (): 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() +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java index c02d08b8dce..10c19e92a27 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java index c3a5b2c3856..033e43bc6ec 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java index 07716e364d4..0c188e4ee7a 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java @@ -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"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt index ac193ce6222..95309aaad4b 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.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) } } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt index 75e135f6070..799821df788 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt @@ -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> = + this.toList().mapNotNull { createConstantValue(it) } + + private fun PrimitiveType.arrayType(): KotlinType = + builtins.getPrimitiveArrayKotlinType(this) + fun createIntegerConstantValue( value: Long, expectedType: KotlinType diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java index 1b564cf5773..49cc92c8e23 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java @@ -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");