diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java index 85aebacb26e..c8065b5ef68 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java @@ -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); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index d41d96645eb..840d98b1430 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -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 result, PsiClassType[] extendsListTypes, TypeVariableResolver typeVariableResolver, boolean annotation) { + private void transformSupertypeList(List 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; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java index 55ce2ed344d..1acc9e01bcd 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java @@ -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()); diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index 1837e6f8e26..49acab798c7 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -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 synchronized(lock: Any, block : () -> R) : R diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index db2278350d2..db4a8788e58 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -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(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java index b976b0fb494..c7282b754f1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java @@ -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 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.class); primitiveTypeToJetType = new EnumMap(PrimitiveType.class); primitiveTypeToNullableJetType = new EnumMap(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); diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index c55c686c89f..f994aea079d 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -1,5 +1,7 @@ namespace jet +public abstract trait jet.Annotation : jet.Any { +} public open class jet.Any { public final /*constructor*/ fun (): jet.Any } @@ -1292,10 +1294,10 @@ public final class jet.Tuple9(): jet.atomic } -public final annotation class jet.volatile : jet.Any { +public final annotation class jet.volatile : jet.Annotation { public final /*constructor*/ fun (): jet.volatile } public final fun arrayOfNulls(/*0*/ size: jet.Int): jet.Array diff --git a/compiler/testData/loadJava/annotation/AnnotatedAnnotation.txt b/compiler/testData/loadJava/annotation/AnnotatedAnnotation.txt index 168b051262e..075226dcfac 100644 --- a/compiler/testData/loadJava/annotation/AnnotatedAnnotation.txt +++ b/compiler/testData/loadJava/annotation/AnnotatedAnnotation.txt @@ -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 (): test.AnnotatedAnnotation } diff --git a/compiler/testData/loadJava/annotation/SimpleAnnotation.txt b/compiler/testData/loadJava/annotation/SimpleAnnotation.txt index 9a863c3a96e..e68ebbb09b9 100644 --- a/compiler/testData/loadJava/annotation/SimpleAnnotation.txt +++ b/compiler/testData/loadJava/annotation/SimpleAnnotation.txt @@ -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 (): test.SimpleAnnotation } diff --git a/compiler/testData/renderer/Classes.kt b/compiler/testData/renderer/Classes.kt index 7cd2a36bad6..9c44c5e2892 100644 --- a/compiler/testData/renderer/Classes.kt +++ b/compiler/testData/renderer/Classes.kt @@ -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 defined in rendererTest // defined in rendererTest.TheClass // defined in rendererTest.TheClass diff --git a/libraries/stdlib/src/kotlin/Annotations.kt b/libraries/stdlib/src/kotlin/Annotations.kt new file mode 100644 index 00000000000..088341ff789 --- /dev/null +++ b/libraries/stdlib/src/kotlin/Annotations.kt @@ -0,0 +1,9 @@ +package kotlin + +import java.lang.reflect.Proxy + +public fun T.annotationType() : Class { + val invocationHandler = Proxy.getInvocationHandler(this)!! + val method = this.javaClass.getMethod("annotationType") + return invocationHandler.invoke(this, method, array())!! as Class +} diff --git a/libraries/stdlib/test/AnnotationsTest.kt b/libraries/stdlib/test/AnnotationsTest.kt new file mode 100644 index 00000000000..40c45c3b3e6 --- /dev/null +++ b/libraries/stdlib/test/AnnotationsTest.kt @@ -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().getAnnotations()!! + + var foundMyAnno = false + var foundDeprecated = false + + for (annotation in annotations) { + val clazz = annotation!!.annotationType() + when { + clazz == javaClass() -> foundMyAnno = true + clazz == javaClass() -> foundDeprecated = true + else -> {} + } + } + + assertTrue(foundMyAnno) + assertTrue(foundDeprecated) + } +}