diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java index 43482ce8d8d..eacb960f867 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java @@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; +import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; @@ -38,6 +39,7 @@ import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNotNull; import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.utils.ExceptionUtils; import javax.inject.Inject; @@ -186,23 +188,40 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer annotation.setAnnotationType(annotationClass.getDefaultType()); return new AnnotationVisitor(Opcodes.ASM4) { - // TODO: arrays, annotations, enums + // TODO: arrays, annotations @Override public void visit(String name, Object value) { - ValueParameterDescriptor parameter = - DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter(Name.identifier(name), annotationClass); - if (parameter != null) { - CompileTimeConstant argument = JavaCompileTimeConstResolver.resolveCompileTimeConstantValue(value, null); - if (argument != null) { - annotation.setValueArgument(parameter, argument); - } + CompileTimeConstant argument = JavaCompileTimeConstResolver.resolveCompileTimeConstantValue(value, null); + if (argument != null) { + setArgumentValueByName(name, argument); } } + @Override + public void visitEnum(String name, String desc, String value) { + FqName fqName = convertJvmDescriptorToFqName(desc); + ClassDescriptor enumClass = javaClassResolver.resolveClass(fqName, IGNORE_KOTLIN_SOURCES); + assert enumClass != null : "Enum class referenced in annotation is not found: " + desc; + JetScope scope = DescriptorUtils.getEnumEntriesScope(enumClass); + Collection properties = scope.getProperties(Name.identifier(value)); + assert properties.size() == 1 : "Enum class should have exactly one property with the referenced name: " + value + + "\n" + properties + "\n" + enumClass; + EnumValue enumValue = new EnumValue((PropertyDescriptor) properties.iterator().next()); + setArgumentValueByName(name, enumValue); + } + @Override public void visitEnd() { result.add(annotation); } + + private void setArgumentValueByName(@NotNull String name, @NotNull CompileTimeConstant argumentValue) { + ValueParameterDescriptor parameter = + DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter(Name.identifier(name), annotationClass); + if (parameter != null) { + annotation.setValueArgument(parameter, argumentValue); + } + } }; } diff --git a/compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.kt b/compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.kt new file mode 100644 index 00000000000..21d470499a7 --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.kt @@ -0,0 +1,11 @@ +package test + +import java.lang.annotation.ElementType + +annotation class Anno(t: ElementType) + +class Class { + Anno(ElementType.METHOD) fun foo() {} + + Anno(ElementType.FIELD) var bar = 42 +} diff --git a/compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.txt b/compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.txt new file mode 100644 index 00000000000..a9e75cb0512 --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.txt @@ -0,0 +1,13 @@ +package test + +internal final annotation class Anno : jet.Annotation { + /*primary*/ public constructor Anno(/*0*/ t: java.lang.annotation.ElementType) +} + +internal final class Class { + /*primary*/ public constructor Class() + test.Anno(t = ElementType.FIELD: java.lang.annotation.ElementType) internal final var bar: jet.Int + internal final fun (): jet.Int + internal final fun (/*0*/ : jet.Int): jet.Unit + test.Anno(t = ElementType.METHOD: java.lang.annotation.ElementType) internal final fun foo(): jet.Unit +} diff --git a/compiler/testData/loadKotlin/annotations/classes/EnumArgument.kt b/compiler/testData/loadKotlin/annotations/classes/EnumArgument.kt new file mode 100644 index 00000000000..d5266ded2a3 --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/classes/EnumArgument.kt @@ -0,0 +1,13 @@ +package test + +import java.lang.annotation.ElementType + +annotation class Anno(t: ElementType) + +Anno(ElementType.METHOD) class Class { + Anno(ElementType.PARAMETER) inner class Inner + + Anno(ElementType.TYPE) class Nested + + Anno(ElementType.ANNOTATION_TYPE) class object +} diff --git a/compiler/testData/loadKotlin/annotations/classes/EnumArgument.txt b/compiler/testData/loadKotlin/annotations/classes/EnumArgument.txt new file mode 100644 index 00000000000..e7a7c3223df --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/classes/EnumArgument.txt @@ -0,0 +1,21 @@ +package test + +internal final annotation class Anno : jet.Annotation { + /*primary*/ public constructor Anno(/*0*/ t: java.lang.annotation.ElementType) +} + +test.Anno(t = ElementType.METHOD: java.lang.annotation.ElementType) internal final class Class { + /*primary*/ public constructor Class() + + test.Anno(t = ElementType.ANNOTATION_TYPE: java.lang.annotation.ElementType) internal class object { + /*primary*/ private constructor () + } + + test.Anno(t = ElementType.PARAMETER: java.lang.annotation.ElementType) internal final inner class Inner { + /*primary*/ public constructor Inner() + } + + test.Anno(t = ElementType.TYPE: java.lang.annotation.ElementType) internal final class Nested { + /*primary*/ public constructor Nested() + } +} diff --git a/compiler/testData/loadKotlin/annotations/classes/Retention.kt b/compiler/testData/loadKotlin/annotations/classes/Retention.kt new file mode 100644 index 00000000000..371342c6293 --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/classes/Retention.kt @@ -0,0 +1,5 @@ +package test + +import java.lang.annotation.* + +Retention(RetentionPolicy.RUNTIME) annotation class Anno diff --git a/compiler/testData/loadKotlin/annotations/classes/Retention.txt b/compiler/testData/loadKotlin/annotations/classes/Retention.txt new file mode 100644 index 00000000000..44752969c59 --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/classes/Retention.txt @@ -0,0 +1,5 @@ +package test + +java.lang.annotation.Retention(value = RetentionPolicy.RUNTIME: java.lang.annotation.RetentionPolicy) internal final annotation class Anno : jet.Annotation { + /*primary*/ public constructor Anno() +} diff --git a/compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.kt b/compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.kt new file mode 100644 index 00000000000..14fb0d39554 --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.kt @@ -0,0 +1,9 @@ +package test + +import java.lang.annotation.ElementType + +annotation class Anno(t: ElementType) + +Anno(ElementType.METHOD) fun foo() {} + +Anno(ElementType.FIELD) val bar = 42 diff --git a/compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.txt b/compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.txt new file mode 100644 index 00000000000..b81fab515e3 --- /dev/null +++ b/compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.txt @@ -0,0 +1,9 @@ +package test + +test.Anno(t = ElementType.FIELD: java.lang.annotation.ElementType) internal val bar: jet.Int + internal fun (): jet.Int +test.Anno(t = ElementType.METHOD: java.lang.annotation.ElementType) internal fun foo(): jet.Unit + +internal final annotation class Anno : jet.Annotation { + /*primary*/ public constructor Anno(/*0*/ t: java.lang.annotation.ElementType) +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 077945f69d3..06d7020a7be 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -65,6 +65,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/annotations/classMembers/DelegatedProperty.kt"); } + @TestMetadata("EnumArgument.kt") + public void testEnumArgument() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.kt"); + } + @TestMetadata("Function.kt") public void testFunction() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/annotations/classMembers/Function.kt"); @@ -113,6 +118,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/annotations/classes/Deprecated.kt"); } + @TestMetadata("EnumArgument.kt") + public void testEnumArgument() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/annotations/classes/EnumArgument.kt"); + } + @TestMetadata("MultipleAnnotations.kt") public void testMultipleAnnotations() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/annotations/classes/MultipleAnnotations.kt"); @@ -123,6 +133,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/annotations/classes/NestedClass.kt"); } + @TestMetadata("Retention.kt") + public void testRetention() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/annotations/classes/Retention.kt"); + } + @TestMetadata("Simple.kt") public void testSimple() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/annotations/classes/Simple.kt"); @@ -151,6 +166,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/annotations/packageMembers/DelegatedProperty.kt"); } + @TestMetadata("EnumArgument.kt") + public void testEnumArgument() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.kt"); + } + @TestMetadata("Function.kt") public void testFunction() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/annotations/packageMembers/Function.kt"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index 48ea102aa9e..60037009bdd 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -67,6 +67,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classMembers/DelegatedProperty.kt"); } + @TestMetadata("EnumArgument.kt") + public void testEnumArgument() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classMembers/EnumArgument.kt"); + } + @TestMetadata("Function.kt") public void testFunction() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classMembers/Function.kt"); @@ -115,6 +120,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classes/Deprecated.kt"); } + @TestMetadata("EnumArgument.kt") + public void testEnumArgument() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classes/EnumArgument.kt"); + } + @TestMetadata("MultipleAnnotations.kt") public void testMultipleAnnotations() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classes/MultipleAnnotations.kt"); @@ -125,6 +135,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classes/NestedClass.kt"); } + @TestMetadata("Retention.kt") + public void testRetention() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classes/Retention.kt"); + } + @TestMetadata("Simple.kt") public void testSimple() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classes/Simple.kt"); @@ -153,6 +168,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/packageMembers/DelegatedProperty.kt"); } + @TestMetadata("EnumArgument.kt") + public void testEnumArgument() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/packageMembers/EnumArgument.kt"); + } + @TestMetadata("Function.kt") public void testFunction() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/packageMembers/Function.kt");