From 93bbd2cbbcfdac3c783662c9ed9a35a828139ab5 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 20 Apr 2015 18:48:10 +0300 Subject: [PATCH] Java: load annotations methods as properties --- .../descriptors/LazyJavaClassMemberScope.kt | 46 +++++++++++++++---- .../lazy/descriptors/LazyJavaMemberScope.kt | 26 ++++++----- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index 52f75d7ba60..0555b3f006a 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -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) { + 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) { + 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 { 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 = nestedClassIndex().keySet() + enumEntryIndex().keySet() - override fun getPropertyNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection = - memberIndex().getAllFieldNames() + - getContainingDeclaration().getTypeConstructor().getSupertypes().flatMapTo(LinkedHashSet()) { supertype -> - supertype.getMemberScope().getDescriptors(kindFilter, nameFilter).map { variable -> - variable.getName() - } + override fun getPropertyNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection { + if (jClass.isAnnotationType()) return memberIndex().getMethodNames(nameFilter) + + return memberIndex().getAllFieldNames() + + getContainingDeclaration().getTypeConstructor().getSupertypes().flatMapTo(LinkedHashSet()) { supertype -> + supertype.getMemberScope().getDescriptors(kindFilter, nameFilter).map { variable -> + variable.getName() } + } + } // TODO override fun getImplicitReceiversHierarchy(): List = listOf() diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt index 75ee636330c..30e9575d4fa 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -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, val hasSynthesizedNames: Boolean) protected fun resolveValueParameters(