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.name.Name
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
import org.jetbrains.kotlin.load.java.structure.*
|
||||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
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.load.java.components.TypeUsage
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import org.jetbrains.kotlin.utils.*
|
import org.jetbrains.kotlin.utils.*
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
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.lazy.resolveAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
|
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.types.JetType
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import java.util.LinkedHashSet
|
import java.util.LinkedHashSet
|
||||||
@@ -78,12 +79,36 @@ public class LazyJavaClassMemberScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
|
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
|
||||||
|
if (jClass.isAnnotationType()) {
|
||||||
|
computeAnnotationProperties(name, result)
|
||||||
|
}
|
||||||
|
|
||||||
val propertiesFromSupertypes = getPropertiesFromSupertypes(name, getContainingDeclaration())
|
val propertiesFromSupertypes = getPropertiesFromSupertypes(name, getContainingDeclaration())
|
||||||
|
|
||||||
result.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, getContainingDeclaration(),
|
result.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, getContainingDeclaration(),
|
||||||
c.errorReporter))
|
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> {
|
private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<PropertyDescriptor> {
|
||||||
return descriptor.getTypeConstructor().getSupertypes().flatMap {
|
return descriptor.getTypeConstructor().getSupertypes().flatMap {
|
||||||
it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor }
|
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>
|
override fun getClassNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name>
|
||||||
= nestedClassIndex().keySet() + enumEntryIndex().keySet()
|
= nestedClassIndex().keySet() + enumEntryIndex().keySet()
|
||||||
|
|
||||||
override fun getPropertyNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name> =
|
override fun getPropertyNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name> {
|
||||||
memberIndex().getAllFieldNames() +
|
if (jClass.isAnnotationType()) return memberIndex().getMethodNames(nameFilter)
|
||||||
getContainingDeclaration().getTypeConstructor().getSupertypes().flatMapTo(LinkedHashSet<Name>()) { supertype ->
|
|
||||||
supertype.getMemberScope().getDescriptors(kindFilter, nameFilter).map { variable ->
|
return memberIndex().getAllFieldNames() +
|
||||||
variable.getName()
|
getContainingDeclaration().getTypeConstructor().getSupertypes().flatMapTo(LinkedHashSet<Name>()) { supertype ->
|
||||||
}
|
supertype.getMemberScope().getDescriptors(kindFilter, nameFilter).map { variable ->
|
||||||
|
variable.getName()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = listOf()
|
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 methodTypeParameters = method.getTypeParameters().map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! }
|
||||||
val valueParameters = resolveValueParameters(c, functionDescriptorImpl, method.getValueParameters())
|
val valueParameters = resolveValueParameters(c, functionDescriptorImpl, method.getValueParameters())
|
||||||
|
|
||||||
val annotationMethod = method.getContainingClass().isAnnotationType()
|
val returnType = computeMethodReturnType(method, annotations, c)
|
||||||
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 (effectiveSignature, superFunctions, signatureErrors) = resolveMethodSignature(method, methodTypeParameters, returnType, valueParameters)
|
val (effectiveSignature, superFunctions, signatureErrors) = resolveMethodSignature(method, methodTypeParameters, returnType, valueParameters)
|
||||||
|
|
||||||
@@ -155,6 +145,20 @@ public abstract class LazyJavaMemberScope(
|
|||||||
return functionDescriptorImpl
|
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 class ResolvedValueParameters(val descriptors: List<ValueParameterDescriptor>, val hasSynthesizedNames: Boolean)
|
||||||
|
|
||||||
protected fun resolveValueParameters(
|
protected fun resolveValueParameters(
|
||||||
|
|||||||
Reference in New Issue
Block a user