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.lang.PrimitiveType;
|
||||||
import org.jetbrains.jet.lang.types.ref.ClassName;
|
import org.jetbrains.jet.lang.types.ref.ClassName;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -70,6 +71,7 @@ public class KotlinToJavaTypesMap {
|
|||||||
register(standardLibrary.getCharSequence(), CharSequence.class);
|
register(standardLibrary.getCharSequence(), CharSequence.class);
|
||||||
register(standardLibrary.getComparable(), Comparable.class);
|
register(standardLibrary.getComparable(), Comparable.class);
|
||||||
register(standardLibrary.getEnum(), Enum.class);
|
register(standardLibrary.getEnum(), Enum.class);
|
||||||
|
register(standardLibrary.getAnnotation(), Annotation.class);
|
||||||
register(standardLibrary.getIterable(), Iterable.class);
|
register(standardLibrary.getIterable(), Iterable.class);
|
||||||
register(standardLibrary.getIterator(), Iterator.class);
|
register(standardLibrary.getIterator(), Iterator.class);
|
||||||
register(standardLibrary.getMutableIterable(), Iterable.class);
|
register(standardLibrary.getMutableIterable(), Iterable.class);
|
||||||
|
|||||||
+4
-7
@@ -703,8 +703,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TypeVariableResolver typeVariableResolverForSupertypes = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
|
TypeVariableResolver typeVariableResolverForSupertypes = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
|
||||||
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes);
|
||||||
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JetType supertype : result) {
|
for (JetType supertype : result) {
|
||||||
@@ -733,16 +733,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
return result;
|
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) {
|
for (PsiClassType type : extendsListTypes) {
|
||||||
PsiClass resolved = type.resolve();
|
PsiClass resolved = type.resolve();
|
||||||
if (resolved != null && JvmStdlibNames.JET_OBJECT.getFqName().equalsTo(resolved.getQualifiedName())) {
|
if (resolved != null && JvmStdlibNames.JET_OBJECT.getFqName().equalsTo(resolved.getQualifiedName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (resolved != null && annotation && JdkNames.JLA_ANNOTATION.getFqName().equalsTo(resolved.getQualifiedName())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
JetType transform = semanticServices.getTypeTransformer().transformToType(type, JavaTypeTransformer.TypeUsage.SUPERTYPE, typeVariableResolver);
|
JetType transform = semanticServices.getTypeTransformer().transformToType(type, JavaTypeTransformer.TypeUsage.SUPERTYPE, typeVariableResolver);
|
||||||
if (ErrorUtils.isErrorType(transform)) {
|
if (ErrorUtils.isErrorType(transform)) {
|
||||||
continue;
|
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.JetStandardLibrary;
|
||||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -65,6 +66,7 @@ public class JavaToKotlinTypesMap {
|
|||||||
register(Number.class, standardLibrary.getNumber());
|
register(Number.class, standardLibrary.getNumber());
|
||||||
register(Comparable.class, standardLibrary.getComparable());
|
register(Comparable.class, standardLibrary.getComparable());
|
||||||
register(Enum.class, standardLibrary.getEnum());
|
register(Enum.class, standardLibrary.getEnum());
|
||||||
|
register(Annotation.class, standardLibrary.getAnnotation());
|
||||||
register(Iterable.class, standardLibrary.getIterable());
|
register(Iterable.class, standardLibrary.getIterable());
|
||||||
register(Iterator.class, standardLibrary.getIterator());
|
register(Iterator.class, standardLibrary.getIterator());
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package jet
|
package jet
|
||||||
|
|
||||||
public annotation class volatile
|
public trait Annotation
|
||||||
public annotation class atomic
|
|
||||||
|
public annotation class volatile : Annotation
|
||||||
|
public annotation class atomic : Annotation
|
||||||
|
|
||||||
public fun <R> synchronized(lock: Any, block : () -> R) : R
|
public fun <R> synchronized(lock: Any, block : () -> R) : R
|
||||||
|
|
||||||
|
|||||||
@@ -170,6 +170,9 @@ public class DescriptorResolver {
|
|||||||
return ErrorUtils.createErrorType("Supertype not specified");
|
return ErrorUtils.createErrorType("Supertype not specified");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (jetClass instanceof JetClass && ((JetClass) jetClass).isAnnotation()) {
|
||||||
|
return JetStandardLibrary.getInstance().getAnnotationType();
|
||||||
|
}
|
||||||
return JetStandardClasses.getAnyType();
|
return JetStandardClasses.getAnyType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,10 +98,11 @@ public class JetStandardLibrary {
|
|||||||
private ClassDescriptor comparableClass;
|
private ClassDescriptor comparableClass;
|
||||||
private ClassDescriptor throwableClass;
|
private ClassDescriptor throwableClass;
|
||||||
private ClassDescriptor enumClass;
|
private ClassDescriptor enumClass;
|
||||||
|
private ClassDescriptor annotationClass;
|
||||||
private ClassDescriptor volatileClass;
|
private ClassDescriptor volatileClass;
|
||||||
|
|
||||||
private JetType stringType;
|
private JetType stringType;
|
||||||
|
private JetType annotationType;
|
||||||
private JetType tuple0Type;
|
private JetType tuple0Type;
|
||||||
|
|
||||||
private EnumMap<PrimitiveType, ClassDescriptor> primitiveTypeToClass;
|
private EnumMap<PrimitiveType, ClassDescriptor> primitiveTypeToClass;
|
||||||
@@ -180,6 +181,9 @@ public class JetStandardLibrary {
|
|||||||
this.stringType = new JetTypeImpl(getString());
|
this.stringType = new JetTypeImpl(getString());
|
||||||
this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0));
|
this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0));
|
||||||
|
|
||||||
|
this.annotationClass = getStdClassByName("Annotation");
|
||||||
|
this.annotationType = new JetTypeImpl(annotationClass);
|
||||||
|
|
||||||
primitiveTypeToClass = new EnumMap<PrimitiveType, ClassDescriptor>(PrimitiveType.class);
|
primitiveTypeToClass = new EnumMap<PrimitiveType, ClassDescriptor>(PrimitiveType.class);
|
||||||
primitiveTypeToJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
primitiveTypeToJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
||||||
primitiveTypeToNullableJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
primitiveTypeToNullableJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
|
||||||
@@ -345,6 +349,18 @@ public class JetStandardLibrary {
|
|||||||
return enumClass;
|
return enumClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ClassDescriptor getAnnotation() {
|
||||||
|
initStdClasses();
|
||||||
|
return annotationClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetType getAnnotationType() {
|
||||||
|
initStdClasses();
|
||||||
|
return annotationType;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType getPrimitiveJetType(PrimitiveType primitiveType) {
|
public JetType getPrimitiveJetType(PrimitiveType primitiveType) {
|
||||||
return primitiveTypeToJetType.get(primitiveType);
|
return primitiveTypeToJetType.get(primitiveType);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
namespace jet
|
namespace jet
|
||||||
|
|
||||||
|
public abstract trait jet.Annotation : jet.Any {
|
||||||
|
}
|
||||||
public open class jet.Any {
|
public open class jet.Any {
|
||||||
public final /*constructor*/ fun <init>(): 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 _8: T8
|
||||||
public final val _9: T9
|
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 /*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 /*constructor*/ fun <init>(): jet.volatile
|
||||||
}
|
}
|
||||||
public final fun </*0*/ T : jet.Any?>arrayOfNulls(/*0*/ size: jet.Int): jet.Array<T?>
|
public final fun </*0*/ T : jet.Any?>arrayOfNulls(/*0*/ size: jet.Int): jet.Array<T?>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
namespace test
|
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
|
public final /*constructor*/ fun <init>(): test.AnnotatedAnnotation
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
namespace test
|
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
|
public final /*constructor*/ fun <init>(): test.SimpleAnnotation
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ trait TheTrait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//package rendererTest defined in root package
|
//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
|
//public open class TheClass<out T : jet.Int, X> defined in rendererTest
|
||||||
//<out T : jet.Int> defined in rendererTest.TheClass
|
//<out T : jet.Int> defined in rendererTest.TheClass
|
||||||
//<X> 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