jet.Annotation
Create a supertype for all Kotlin annotations, jet.Annotation. Map java.lang.annotation.Annotation to jet.Annotation and vice versa. Add extension function "annotationType()" to every annotation, similar to java.lang.annotation.Annotation.annotationType() #KT-1620 Fixed
This commit is contained in:
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||
import org.jetbrains.jet.lang.types.ref.ClassName;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -70,6 +71,7 @@ public class KotlinToJavaTypesMap {
|
||||
register(standardLibrary.getCharSequence(), CharSequence.class);
|
||||
register(standardLibrary.getComparable(), Comparable.class);
|
||||
register(standardLibrary.getEnum(), Enum.class);
|
||||
register(standardLibrary.getAnnotation(), Annotation.class);
|
||||
register(standardLibrary.getIterable(), Iterable.class);
|
||||
register(standardLibrary.getIterator(), Iterator.class);
|
||||
register(standardLibrary.getMutableIterable(), Iterable.class);
|
||||
|
||||
+4
-7
@@ -703,8 +703,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
}
|
||||
else {
|
||||
TypeVariableResolver typeVariableResolverForSupertypes = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes);
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes);
|
||||
}
|
||||
|
||||
for (JetType supertype : result) {
|
||||
@@ -733,16 +733,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
return result;
|
||||
}
|
||||
|
||||
private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes, TypeVariableResolver typeVariableResolver, boolean annotation) {
|
||||
private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes, TypeVariableResolver typeVariableResolver) {
|
||||
for (PsiClassType type : extendsListTypes) {
|
||||
PsiClass resolved = type.resolve();
|
||||
if (resolved != null && JvmStdlibNames.JET_OBJECT.getFqName().equalsTo(resolved.getQualifiedName())) {
|
||||
continue;
|
||||
}
|
||||
if (resolved != null && annotation && JdkNames.JLA_ANNOTATION.getFqName().equalsTo(resolved.getQualifiedName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
JetType transform = semanticServices.getTypeTransformer().transformToType(type, JavaTypeTransformer.TypeUsage.SUPERTYPE, typeVariableResolver);
|
||||
if (ErrorUtils.isErrorType(transform)) {
|
||||
continue;
|
||||
|
||||
+2
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -65,6 +66,7 @@ public class JavaToKotlinTypesMap {
|
||||
register(Number.class, standardLibrary.getNumber());
|
||||
register(Comparable.class, standardLibrary.getComparable());
|
||||
register(Enum.class, standardLibrary.getEnum());
|
||||
register(Annotation.class, standardLibrary.getAnnotation());
|
||||
register(Iterable.class, standardLibrary.getIterable());
|
||||
register(Iterator.class, standardLibrary.getIterator());
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package jet
|
||||
|
||||
public annotation class volatile
|
||||
public annotation class atomic
|
||||
public trait Annotation
|
||||
|
||||
public annotation class volatile : Annotation
|
||||
public annotation class atomic : Annotation
|
||||
|
||||
public fun <R> synchronized(lock: Any, block : () -> R) : R
|
||||
|
||||
|
||||
@@ -170,6 +170,9 @@ public class DescriptorResolver {
|
||||
return ErrorUtils.createErrorType("Supertype not specified");
|
||||
}
|
||||
}
|
||||
else if (jetClass instanceof JetClass && ((JetClass) jetClass).isAnnotation()) {
|
||||
return JetStandardLibrary.getInstance().getAnnotationType();
|
||||
}
|
||||
return JetStandardClasses.getAnyType();
|
||||
}
|
||||
|
||||
|
||||
@@ -98,10 +98,11 @@ public class JetStandardLibrary {
|
||||
private ClassDescriptor comparableClass;
|
||||
private ClassDescriptor throwableClass;
|
||||
private ClassDescriptor enumClass;
|
||||
private ClassDescriptor annotationClass;
|
||||
private ClassDescriptor volatileClass;
|
||||
|
||||
private JetType stringType;
|
||||
|
||||
private JetType annotationType;
|
||||
private JetType tuple0Type;
|
||||
|
||||
private EnumMap<PrimitiveType, ClassDescriptor> primitiveTypeToClass;
|
||||
@@ -180,6 +181,9 @@ public class JetStandardLibrary {
|
||||
this.stringType = new JetTypeImpl(getString());
|
||||
this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0));
|
||||
|
||||
this.annotationClass = getStdClassByName("Annotation");
|
||||
this.annotationType = new JetTypeImpl(annotationClass);
|
||||
|
||||
primitiveTypeToClass = new EnumMap<PrimitiveType, ClassDescriptor>(PrimitiveType.class);
|
||||
primitiveTypeToJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
||||
primitiveTypeToNullableJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
||||
@@ -345,6 +349,18 @@ public class JetStandardLibrary {
|
||||
return enumClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getAnnotation() {
|
||||
initStdClasses();
|
||||
return annotationClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType getAnnotationType() {
|
||||
initStdClasses();
|
||||
return annotationType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType getPrimitiveJetType(PrimitiveType primitiveType) {
|
||||
return primitiveTypeToJetType.get(primitiveType);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
namespace jet
|
||||
|
||||
public abstract trait jet.Annotation : jet.Any {
|
||||
}
|
||||
public open class jet.Any {
|
||||
public final /*constructor*/ fun <init>(): jet.Any
|
||||
}
|
||||
@@ -1292,10 +1294,10 @@ public final class jet.Tuple9</*0*/ out T1 : jet.Any?, /*1*/ out T2 : jet.Any?,
|
||||
public final val _8: T8
|
||||
public final val _9: T9
|
||||
}
|
||||
public final annotation class jet.atomic : jet.Any {
|
||||
public final annotation class jet.atomic : jet.Annotation {
|
||||
public final /*constructor*/ fun <init>(): jet.atomic
|
||||
}
|
||||
public final annotation class jet.volatile : jet.Any {
|
||||
public final annotation class jet.volatile : jet.Annotation {
|
||||
public final /*constructor*/ fun <init>(): jet.volatile
|
||||
}
|
||||
public final fun </*0*/ T : jet.Any?>arrayOfNulls(/*0*/ size: jet.Int): jet.Array<T?>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace test
|
||||
|
||||
test.AnnotatedAnnotation() public final annotation class test.AnnotatedAnnotation : jet.Any {
|
||||
test.AnnotatedAnnotation() public final annotation class test.AnnotatedAnnotation : jet.Annotation {
|
||||
public final /*constructor*/ fun <init>(): test.AnnotatedAnnotation
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace test
|
||||
|
||||
public final annotation class test.SimpleAnnotation : jet.Any {
|
||||
public final annotation class test.SimpleAnnotation : jet.Annotation {
|
||||
public final /*constructor*/ fun <init>(): test.SimpleAnnotation
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ trait TheTrait {
|
||||
}
|
||||
|
||||
//package rendererTest defined in root package
|
||||
//internal final annotation class TheAnnotation defined in rendererTest
|
||||
//internal final annotation class TheAnnotation : jet.Annotation defined in rendererTest
|
||||
//public open class TheClass<out T : jet.Int, X> defined in rendererTest
|
||||
//<out T : jet.Int> defined in rendererTest.TheClass
|
||||
//<X> defined in rendererTest.TheClass
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package kotlin
|
||||
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
public fun <T : Annotation> T.annotationType() : Class<out T> {
|
||||
val invocationHandler = Proxy.getInvocationHandler(this)!!
|
||||
val method = this.javaClass.getMethod("annotationType")
|
||||
return invocationHandler.invoke(this, method, array<Object>())!! as Class<out T>
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package test.annotations
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.test.assertTrue
|
||||
import org.junit.Test as test
|
||||
import java.lang.annotation.*
|
||||
|
||||
|
||||
Retention(RetentionPolicy.RUNTIME)
|
||||
annotation class MyAnno
|
||||
|
||||
MyAnno
|
||||
Deprecated
|
||||
class AnnotatedClass
|
||||
|
||||
|
||||
class AnnotationTest {
|
||||
test fun annotationType() {
|
||||
val annotations = javaClass<AnnotatedClass>().getAnnotations()!!
|
||||
|
||||
var foundMyAnno = false
|
||||
var foundDeprecated = false
|
||||
|
||||
for (annotation in annotations) {
|
||||
val clazz = annotation!!.annotationType()
|
||||
when {
|
||||
clazz == javaClass<MyAnno>() -> foundMyAnno = true
|
||||
clazz == javaClass<Deprecated>() -> foundDeprecated = true
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(foundMyAnno)
|
||||
assertTrue(foundDeprecated)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user