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:
Alexander Udalov
2012-08-24 22:07:55 +04:00
parent 9be4f63735
commit d99ffbd120
12 changed files with 84 additions and 15 deletions
@@ -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);
@@ -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;
@@ -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());
+4 -2
View File
@@ -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);
+4 -2
View File
@@ -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
}
+1 -1
View File
@@ -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>
}
+36
View File
@@ -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)
}
}