Java: load annotations methods as properties
This commit is contained in:
+37
-9
@@ -21,22 +21,23 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||
import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl
|
||||
import java.util.Collections
|
||||
import org.jetbrains.kotlin.utils.*
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.*
|
||||
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor
|
||||
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.child
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import java.util.LinkedHashSet
|
||||
@@ -78,12 +79,36 @@ public class LazyJavaClassMemberScope(
|
||||
}
|
||||
|
||||
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
|
||||
if (jClass.isAnnotationType()) {
|
||||
computeAnnotationProperties(name, result)
|
||||
}
|
||||
|
||||
val propertiesFromSupertypes = getPropertiesFromSupertypes(name, getContainingDeclaration())
|
||||
|
||||
result.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, getContainingDeclaration(),
|
||||
c.errorReporter))
|
||||
}
|
||||
|
||||
private fun computeAnnotationProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
|
||||
val method = memberIndex().findMethodsByName(name).singleOrNull() ?: return
|
||||
val annotations = c.resolveAnnotations(method)
|
||||
|
||||
val propertyDescriptor = JavaPropertyDescriptor(
|
||||
getContainingDeclaration(), annotations, method.getVisibility(),
|
||||
/* isVar = */ false, method.getName(), c.sourceElementFactory.source(method)
|
||||
)
|
||||
|
||||
// default getter is necessary because there is no real field in annotation
|
||||
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor)
|
||||
propertyDescriptor.initialize(getter, null)
|
||||
|
||||
val returnType = computeMethodReturnType(method, annotations, c.child(propertyDescriptor, method))
|
||||
propertyDescriptor.setType(returnType, listOf(), getDispatchReceiverParameter(), null : JetType?)
|
||||
getter.initialize(returnType)
|
||||
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
|
||||
private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<PropertyDescriptor> {
|
||||
return descriptor.getTypeConstructor().getSupertypes().flatMap {
|
||||
it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor }
|
||||
@@ -295,13 +320,16 @@ public class LazyJavaClassMemberScope(
|
||||
override fun getClassNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name>
|
||||
= nestedClassIndex().keySet() + enumEntryIndex().keySet()
|
||||
|
||||
override fun getPropertyNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name> =
|
||||
memberIndex().getAllFieldNames() +
|
||||
getContainingDeclaration().getTypeConstructor().getSupertypes().flatMapTo(LinkedHashSet<Name>()) { supertype ->
|
||||
supertype.getMemberScope().getDescriptors(kindFilter, nameFilter).map { variable ->
|
||||
variable.getName()
|
||||
}
|
||||
override fun getPropertyNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name> {
|
||||
if (jClass.isAnnotationType()) return memberIndex().getMethodNames(nameFilter)
|
||||
|
||||
return memberIndex().getAllFieldNames() +
|
||||
getContainingDeclaration().getTypeConstructor().getSupertypes().flatMapTo(LinkedHashSet<Name>()) { supertype ->
|
||||
supertype.getMemberScope().getDescriptors(kindFilter, nameFilter).map { variable ->
|
||||
variable.getName()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = listOf()
|
||||
|
||||
+15
-11
@@ -119,17 +119,7 @@ public abstract class LazyJavaMemberScope(
|
||||
val methodTypeParameters = method.getTypeParameters().map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! }
|
||||
val valueParameters = resolveValueParameters(c, functionDescriptorImpl, method.getValueParameters())
|
||||
|
||||
val annotationMethod = method.getContainingClass().isAnnotationType()
|
||||
val returnTypeAttrs = LazyJavaTypeAttributes(
|
||||
c, method, TypeUsage.MEMBER_SIGNATURE_COVARIANT, annotations,
|
||||
allowFlexible = !annotationMethod,
|
||||
isForAnnotationParameter = annotationMethod
|
||||
)
|
||||
val returnJavaType = method.getReturnType() ?: throw IllegalStateException("Constructor passed as method: $method")
|
||||
// Annotation arguments are never null in Java
|
||||
val returnType = c.typeResolver.transformJavaType(returnJavaType, returnTypeAttrs).let {
|
||||
if (annotationMethod) TypeUtils.makeNotNullable(it) else it
|
||||
}
|
||||
val returnType = computeMethodReturnType(method, annotations, c)
|
||||
|
||||
val (effectiveSignature, superFunctions, signatureErrors) = resolveMethodSignature(method, methodTypeParameters, returnType, valueParameters)
|
||||
|
||||
@@ -155,6 +145,20 @@ public abstract class LazyJavaMemberScope(
|
||||
return functionDescriptorImpl
|
||||
}
|
||||
|
||||
protected fun computeMethodReturnType(method: JavaMethod, annotations: Annotations, c: LazyJavaResolverContext): JetType {
|
||||
val annotationMethod = method.getContainingClass().isAnnotationType()
|
||||
val returnTypeAttrs = LazyJavaTypeAttributes(
|
||||
c, method, TypeUsage.MEMBER_SIGNATURE_COVARIANT, annotations,
|
||||
allowFlexible = !annotationMethod,
|
||||
isForAnnotationParameter = annotationMethod
|
||||
)
|
||||
val returnJavaType = method.getReturnType() ?: throw IllegalStateException("Constructor passed as method: $method")
|
||||
// Annotation arguments are never null in Java
|
||||
return c.typeResolver.transformJavaType(returnJavaType, returnTypeAttrs).let {
|
||||
if (annotationMethod) TypeUtils.makeNotNullable(it) else it
|
||||
}
|
||||
}
|
||||
|
||||
protected class ResolvedValueParameters(val descriptors: List<ValueParameterDescriptor>, val hasSynthesizedNames: Boolean)
|
||||
|
||||
protected fun resolveValueParameters(
|
||||
|
||||
Reference in New Issue
Block a user