Handling of annotations on delegated property in descriptor loader & stub builder

This commit is contained in:
Mikhail Glukhikh
2016-01-15 18:33:04 +03:00
parent e4f7446bec
commit 7f2624c9a1
10 changed files with 75 additions and 7 deletions
@@ -0,0 +1,15 @@
// ALLOW_AST_ACCESS
package test
import kotlin.reflect.KProperty
annotation class Anno
class CustomDelegate {
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name
}
class Class {
@delegate:Anno val property by CustomDelegate()
}
@@ -0,0 +1,16 @@
package test
public final annotation class Anno : kotlin.Annotation {
/*primary*/ public constructor Anno()
}
public final class Class {
/*primary*/ public constructor Class()
@delegate:test.Anno() public final val property: kotlin.String
public final fun <get-property>(): kotlin.String
}
public final class CustomDelegate {
/*primary*/ public constructor CustomDelegate()
public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.String
}
@@ -2262,6 +2262,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("DelegateTarget.kt")
public void testDelegateTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/DelegateTarget.kt");
doTestCompiledKotlin(fileName);
}
@TestMetadata("FieldTarget.kt")
public void testFieldTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/FieldTarget.kt");
@@ -501,6 +501,12 @@ public class LoadKotlinWithTypeTableTestGenerated extends AbstractLoadKotlinWith
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("DelegateTarget.kt")
public void testDelegateTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/DelegateTarget.kt");
doTest(fileName);
}
@TestMetadata("FieldTarget.kt")
public void testFieldTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/FieldTarget.kt");
@@ -503,6 +503,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("DelegateTarget.kt")
public void testDelegateTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/DelegateTarget.kt");
doTest(fileName);
}
@TestMetadata("FieldTarget.kt")
public void testFieldTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/FieldTarget.kt");
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.kotlin
import com.google.protobuf.MessageLite
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.ClassId
@@ -102,7 +103,14 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
findClassAndLoadMemberAnnotations(container, sig, property = true, field = true)
}.orEmpty()
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations)
// TODO: check delegate presence in some other way
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations,
if (fieldSignature?.signature?.contains(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX) ?: false) {
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
}
else {
AnnotationUseSiteTarget.FIELD
})
}
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, kind) ?: return emptyList()
@@ -117,7 +125,8 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
return findClassAndLoadMemberAnnotations(container, signature)
}
protected abstract fun loadPropertyAnnotations(propertyAnnotations: List<A>, fieldAnnotations: List<A>): List<T>
protected abstract fun loadPropertyAnnotations(propertyAnnotations: List<A>, fieldAnnotations: List<A>,
fieldUseSiteTarget: AnnotationUseSiteTarget): List<T>
protected abstract fun transformAnnotations(annotations: List<A>): List<T>
@@ -85,10 +85,12 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
override fun loadPropertyAnnotations(
propertyAnnotations: List<AnnotationDescriptor>,
fieldAnnotations: List<AnnotationDescriptor>
fieldAnnotations: List<AnnotationDescriptor>,
fieldUseSiteTarget: AnnotationUseSiteTarget
): List<AnnotationWithTarget> {
return propertyAnnotations.map { AnnotationWithTarget(it, null) } +
fieldAnnotations.map { AnnotationWithTarget(it, AnnotationUseSiteTarget.FIELD) }
fieldAnnotations.map { AnnotationWithTarget(it, fieldUseSiteTarget) }
fieldAnnotations.map { AnnotationWithTarget(it, fieldUseSiteTarget) }
}
override fun transformAnnotations(annotations: List<AnnotationDescriptor>): List<AnnotationWithTarget> {
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
// The purpose of this class is to hold a unique signature of either a method or a field, so that annotations on a member can be put
// into a map indexed by these signatures
internal data class MemberSignature private constructor(private val signature: String) {
internal data class MemberSignature private constructor(internal val signature: String) {
companion object {
@JvmStatic
fun fromMethod(nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature): MemberSignature {
@@ -138,9 +138,11 @@ class AnnotationLoaderForClassFileStubBuilder(
return null
}
override fun loadPropertyAnnotations(propertyAnnotations: List<ClassId>, fieldAnnotations: List<ClassId>): List<ClassIdWithTarget> {
override fun loadPropertyAnnotations(
propertyAnnotations: List<ClassId>, fieldAnnotations: List<ClassId>, fieldUseSiteTarget: AnnotationUseSiteTarget
): List<ClassIdWithTarget> {
return propertyAnnotations.map { ClassIdWithTarget(it, null) } +
fieldAnnotations.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.FIELD) }
fieldAnnotations.map { ClassIdWithTarget(it, fieldUseSiteTarget ) }
}
override fun transformAnnotations(annotations: List<ClassId>) = annotations.map { ClassIdWithTarget(it, null) }
@@ -501,6 +501,12 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("DelegateTarget.kt")
public void testDelegateTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/DelegateTarget.kt");
doTest(fileName);
}
@TestMetadata("FieldTarget.kt")
public void testFieldTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/FieldTarget.kt");