Support KClass<*> annotation arguments in serialization/deserialization

#KT-11586 Fixed
This commit is contained in:
Alexander Udalov
2017-10-19 15:44:31 +02:00
parent d0e8f99d60
commit f2be34ca1c
11 changed files with 106 additions and 10 deletions
@@ -741,7 +741,7 @@ private class ConstantExpressionEvaluatorVisitor(
override fun visitClassLiteralExpression(expression: KtClassLiteralExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
val type = trace.getType(expression)!!
if (type.isError) return null
return KClassValue(type).wrap()
return factory.createKClassValue(type).wrap()
}
private fun resolveArguments(valueArguments: List<ValueArgument>, expectedType: KotlinType): List<CompileTimeConstant<*>?> {
@@ -97,9 +97,12 @@ class AnnotationSerializer(private val stringTable: StringTable) {
intValue = value.value.toLong()
}
override fun visitKClassValue(value: KClassValue?, data: Unit?) {
// TODO: support class literals
throw UnsupportedOperationException("Class literal annotation arguments are not yet supported: $value")
override fun visitKClassValue(value: KClassValue, data: Unit) {
val descriptor = value.value.constructor.declarationDescriptor as? ClassDescriptor
?: throw UnsupportedOperationException("Class literal annotation argument should be a class: $value")
type = Type.CLASS
classId = stringTable.getFqNameIndex(descriptor)
}
override fun visitLongValue(value: LongValue, data: Unit) {
@@ -0,0 +1,20 @@
// ALLOW_AST_ACCESS
package test
import kotlin.reflect.KClass
@Target(AnnotationTarget.TYPE)
annotation class Ann(val klass: KClass<*>)
class A {
fun simple(s: @Ann(Simple::class) String) {}
fun generic(s: @Ann(Generic::class) String) {}
fun innerGeneric(s: @Ann(InnerGeneric.Inner::class) String) {}
}
class Simple
class Generic<T>
class InnerGeneric<A, B> {
inner class Inner<in C, D : A>
}
@@ -0,0 +1,30 @@
package test
public final class A {
/*primary*/ public constructor A()
public final fun generic(/*0*/ s: @test.Ann(klass = test.Generic<*>::class) kotlin.String): kotlin.Unit
public final fun innerGeneric(/*0*/ s: @test.Ann(klass = test.InnerGeneric<*, *>.Inner<*, *>::class) kotlin.String): kotlin.Unit
public final fun simple(/*0*/ s: @test.Ann(klass = test.Simple::class) kotlin.String): kotlin.Unit
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) public final annotation class Ann : kotlin.Annotation {
/*primary*/ public constructor Ann(/*0*/ klass: kotlin.reflect.KClass<*>)
public final val klass: kotlin.reflect.KClass<*>
public final fun <get-klass>(): kotlin.reflect.KClass<*>
}
public final class Generic</*0*/ T> {
/*primary*/ public constructor Generic</*0*/ T>()
}
public final class InnerGeneric</*0*/ A, /*1*/ B> {
/*primary*/ public constructor InnerGeneric</*0*/ A, /*1*/ B>()
public final inner class Inner</*0*/ in C, /*1*/ D : A> /*captured type parameters: /*2*/ A, /*3*/ B*/ {
/*primary*/ public constructor Inner</*0*/ in C, /*1*/ D : A>()
}
}
public final class Simple {
/*primary*/ public constructor Simple()
}
@@ -2250,6 +2250,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/types"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("ClassLiteralArgument.kt")
public void testClassLiteralArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ClassLiteralArgument.kt");
doTestCompiledKotlin(fileName);
}
@TestMetadata("ReceiverParameter.kt")
public void testReceiverParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt");
@@ -457,6 +457,12 @@ public class LoadKotlinWithTypeTableTestGenerated extends AbstractLoadKotlinWith
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/types"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("ClassLiteralArgument.kt")
public void testClassLiteralArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ClassLiteralArgument.kt");
doTest(fileName);
}
@TestMetadata("ReceiverParameter.kt")
public void testReceiverParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt");
@@ -2250,6 +2250,12 @@ public class LoadJavaUsingJavacTestGenerated extends AbstractLoadJavaUsingJavacT
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/types"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("ClassLiteralArgument.kt")
public void testClassLiteralArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ClassLiteralArgument.kt");
doTestCompiledKotlin(fileName);
}
@TestMetadata("ReceiverParameter.kt")
public void testReceiverParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt");
@@ -459,6 +459,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/types"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("ClassLiteralArgument.kt")
public void testClassLiteralArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ClassLiteralArgument.kt");
doTest(fileName);
}
@TestMetadata("ReceiverParameter.kt")
public void testReceiverParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt");