Support loading Java annotations with TYPE_PARAMETER target
This commit is contained in:
+6
@@ -197,4 +197,10 @@ public class JavaClassImpl extends JavaClassifierImpl<PsiClass> implements JavaC
|
||||
|
||||
return PsiSubstitutorImpl.createSubstitutor(substMap);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiAnnotationOwner getAnnotationOwnerPsi() {
|
||||
return getPsi().getModifierList();
|
||||
}
|
||||
}
|
||||
|
||||
-7
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java.structure.impl;
|
||||
|
||||
import com.intellij.psi.PsiAnnotationOwner;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -32,12 +31,6 @@ public abstract class JavaClassifierImpl<Psi extends PsiClass> extends JavaEleme
|
||||
super(psiClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiAnnotationOwner getAnnotationOwnerPsi() {
|
||||
return getPsi().getModifierList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/* package */ static JavaClassifier create(@NotNull PsiClass psiClass) {
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
|
||||
+6
@@ -73,4 +73,10 @@ public class JavaTypeParameterImpl extends JavaClassifierImpl<PsiTypeParameter>
|
||||
public JavaTypeProvider getTypeProvider() {
|
||||
return new JavaTypeProviderImpl(getPsi().getManager());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiAnnotationOwner getAnnotationOwnerPsi() {
|
||||
return getPsi();
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -42,6 +42,12 @@ public class LoadJava8TestGenerated extends AbstractLoadJava8Test {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava8/compiledJava/TypeAnnotations.java");
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeParameterAnnotations.java")
|
||||
public void testTypeParameterAnnotations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava8/compiledJava/TypeParameterAnnotations.java");
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadJava8/sourceJava")
|
||||
@@ -57,5 +63,11 @@ public class LoadJava8TestGenerated extends AbstractLoadJava8Test {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava8/sourceJava/TypeAnnotations.java");
|
||||
doTestSourceJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeParameterAnnotations.java")
|
||||
public void testTypeParameterAnnotations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava8/sourceJava/TypeParameterAnnotations.java");
|
||||
doTestSourceJava(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -40,4 +40,10 @@ public class Jvm8RuntimeDescriptorLoaderTestGenerated extends AbstractJvm8Runtim
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava8/compiledJava/TypeAnnotations.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeParameterAnnotations.java")
|
||||
public void testTypeParameterAnnotations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava8/compiledJava/TypeParameterAnnotations.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package test;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
public class TypeParameterAnnotations {
|
||||
@Target(ElementType.TYPE_PARAMETER)
|
||||
public @interface A {
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
// Currently annotations on type parameters and arguments are not loaded from compiled code because of IDEA-153093
|
||||
// Once it will be fixed check if KT-11454 is ready to be resolved
|
||||
public interface G<@A T> {
|
||||
<@A("abc") R> void foo(R r);
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package test
|
||||
|
||||
public open class TypeParameterAnnotations {
|
||||
public constructor TypeParameterAnnotations()
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER}) @kotlin.annotation.Retention(value = ...) public final annotation class A : kotlin.Annotation {
|
||||
public final val value: kotlin.String
|
||||
public final fun <get-value>(): kotlin.String
|
||||
}
|
||||
|
||||
public interface G</*0*/ @test.TypeParameterAnnotations.A(value = "") T : kotlin.Any!> {
|
||||
public abstract fun </*0*/ @test.TypeParameterAnnotations.A(value = "abc") R : kotlin.Any!> foo(/*0*/ R!): kotlin.Unit
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package test
|
||||
|
||||
public open class TypeParameterAnnotations {
|
||||
public constructor TypeParameterAnnotations()
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER}) public final annotation class A : kotlin.Annotation {
|
||||
public constructor A(/*0*/ value: kotlin.String = ...)
|
||||
public final val value: kotlin.String
|
||||
}
|
||||
|
||||
public interface G</*0*/ T : kotlin.Any!> {
|
||||
public abstract fun </*0*/ R : kotlin.Any!> foo(/*0*/ p0: R!): kotlin.Unit
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package test;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
public class TypeParameterAnnotations {
|
||||
@Target(ElementType.TYPE_PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface A {
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
interface G<@A T> {
|
||||
<@A("abc") R> void foo(R r);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package test
|
||||
|
||||
public open class TypeParameterAnnotations {
|
||||
public constructor TypeParameterAnnotations()
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public/*package*/ final annotation class A : kotlin.Annotation {
|
||||
public/*package*/ constructor A(/*0*/ value: kotlin.String = ...)
|
||||
public final val value: kotlin.String
|
||||
}
|
||||
|
||||
public/*package*/ interface G</*0*/ @test.TypeParameterAnnotations.A() T : kotlin.Any!> {
|
||||
public abstract fun </*0*/ @test.TypeParameterAnnotations.A(value = "abc") R : kotlin.Any!> foo(/*0*/ r: R!): kotlin.Unit
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -19,5 +19,5 @@ package org.jetbrains.kotlin.jvm.runtime
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
|
||||
abstract class AbstractJvm8RuntimeDescriptorLoaderTest : AbstractJvmRuntimeDescriptorLoaderTest() {
|
||||
override val defaultJdkKind: TestJdkKind = TestJdkKind.MOCK_JDK
|
||||
override val defaultJdkKind: TestJdkKind = TestJdkKind.FULL_JDK
|
||||
}
|
||||
|
||||
+5
@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaAnnotations
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
||||
@@ -42,6 +44,9 @@ class LazyJavaTypeParameterDescriptor(
|
||||
index,
|
||||
SourceElement.NO_SOURCE, c.components.supertypeLoopChecker
|
||||
) {
|
||||
private val annotations = LazyJavaAnnotations(c, javaTypeParameter)
|
||||
|
||||
override fun getAnnotations() = annotations
|
||||
|
||||
override fun resolveUpperBounds(): List<KotlinType> {
|
||||
val bounds = javaTypeParameter.upperBounds
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.name.FqName;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface JavaClass extends JavaClassifier, JavaTypeParameterListOwner, JavaModifierListOwner, JavaAnnotationOwner {
|
||||
public interface JavaClass extends JavaClassifier, JavaTypeParameterListOwner, JavaModifierListOwner {
|
||||
@NotNull
|
||||
Collection<JavaClass> getInnerClasses();
|
||||
|
||||
|
||||
+1
-1
@@ -16,5 +16,5 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java.structure;
|
||||
|
||||
public interface JavaClassifier extends JavaNamedElement {
|
||||
public interface JavaClassifier extends JavaNamedElement, JavaAnnotationOwner {
|
||||
}
|
||||
|
||||
+7
-7
@@ -21,19 +21,19 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import java.lang.reflect.AnnotatedElement
|
||||
|
||||
interface ReflectJavaAnnotationOwner : JavaAnnotationOwner {
|
||||
val element: AnnotatedElement
|
||||
val element: AnnotatedElement?
|
||||
|
||||
override fun getAnnotations() = getAnnotations(element.declaredAnnotations)
|
||||
override fun getAnnotations() = element?.declaredAnnotations?.getAnnotations() ?: emptyList()
|
||||
|
||||
override fun findAnnotation(fqName: FqName) = findAnnotation(element.declaredAnnotations, fqName)
|
||||
override fun findAnnotation(fqName: FqName) = element?.declaredAnnotations?.findAnnotation(fqName)
|
||||
|
||||
override fun isDeprecatedInJavaDoc() = false
|
||||
}
|
||||
|
||||
fun getAnnotations(annotations: Array<Annotation>): List<ReflectJavaAnnotation> {
|
||||
return annotations.map { ReflectJavaAnnotation(it) }
|
||||
fun Array<Annotation>.getAnnotations(): List<ReflectJavaAnnotation> {
|
||||
return map { ReflectJavaAnnotation(it) }
|
||||
}
|
||||
|
||||
fun findAnnotation(annotations: Array<Annotation>, fqName: FqName): ReflectJavaAnnotation? {
|
||||
return annotations.firstOrNull { it.annotationClass.java.classId.asSingleFqName() == fqName }?.let { ReflectJavaAnnotation(it) }
|
||||
fun Array<Annotation>.findAnnotation(fqName: FqName): ReflectJavaAnnotation? {
|
||||
return firstOrNull { it.annotationClass.java.classId.asSingleFqName() == fqName }?.let { ReflectJavaAnnotation(it) }
|
||||
}
|
||||
|
||||
+7
-5
@@ -16,24 +16,26 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java.structure.reflect
|
||||
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeProvider
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.lang.reflect.AnnotatedElement
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.TypeVariable
|
||||
|
||||
class ReflectJavaTypeParameter(
|
||||
val typeVariable: TypeVariable<*>
|
||||
) : ReflectJavaElement(), JavaTypeParameter {
|
||||
) : ReflectJavaElement(), JavaTypeParameter, ReflectJavaAnnotationOwner {
|
||||
override fun getUpperBounds(): List<ReflectJavaClassifierType> {
|
||||
val bounds = typeVariable.bounds.map { bound -> ReflectJavaClassifierType(bound) }
|
||||
if (bounds.singleOrNull()?.type == Any::class.java) return emptyList()
|
||||
return bounds
|
||||
}
|
||||
|
||||
override val element: AnnotatedElement?
|
||||
// TypeVariable is AnnotatedElement only in JDK8
|
||||
get() = typeVariable as? AnnotatedElement
|
||||
|
||||
override fun getOwner(): JavaTypeParameterListOwner? {
|
||||
val owner = typeVariable.genericDeclaration
|
||||
return when (owner) {
|
||||
|
||||
+2
-2
@@ -26,9 +26,9 @@ class ReflectJavaValueParameter(
|
||||
private val name: String?,
|
||||
private val isVararg: Boolean
|
||||
) : ReflectJavaElement(), JavaValueParameter {
|
||||
override fun getAnnotations() = getAnnotations(annotations)
|
||||
override fun getAnnotations() = annotations.getAnnotations()
|
||||
|
||||
override fun findAnnotation(fqName: FqName) = findAnnotation(annotations, fqName)
|
||||
override fun findAnnotation(fqName: FqName) = annotations.findAnnotation(fqName)
|
||||
|
||||
override fun isDeprecatedInJavaDoc() = false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user