Support enums as annotation arguments in deserialized Kotlin descriptors
This commit is contained in:
+27
-8
@@ -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<VariableDescriptor> 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 <get-bar>(): jet.Int
|
||||
internal final fun <set-bar>(/*0*/ <set-?>: jet.Int): jet.Unit
|
||||
test.Anno(t = ElementType.METHOD: java.lang.annotation.ElementType) internal final fun foo(): jet.Unit
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 <class-object-for-Class> {
|
||||
/*primary*/ private constructor <class-object-for-Class>()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
import java.lang.annotation.*
|
||||
|
||||
Retention(RetentionPolicy.RUNTIME) annotation class Anno
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
test.Anno(t = ElementType.FIELD: java.lang.annotation.ElementType) internal val bar: jet.Int
|
||||
internal fun <get-bar>(): 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)
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
+20
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user