From dddec9ea3ddc293cf7af1a7e5c53887807ffc536 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 2 Jul 2013 16:45:20 +0400 Subject: [PATCH] Resolve enum in annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 37 +++++++++++++++++++ .../testData/resolveAnnotations/testFile.kt | 9 ++++- .../AnnotationDescriptorResolveTest.java | 18 +++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index c8345704670..a078c4fae7e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -24,12 +24,14 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; +import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.ErrorUtils; @@ -227,6 +229,31 @@ public class AnnotationResolver { return trace.get(BindingContext.COMPILE_TIME_VALUE, expression); } + @Override + public CompileTimeConstant visitSimpleNameExpression(JetSimpleNameExpression expression, Void data) { + ResolvedCall resolvedCall = + trace.getBindingContext().get(BindingContext.RESOLVED_CALL, expression); + if (resolvedCall != null) { + CallableDescriptor callableDescriptor = resolvedCall.getResultingDescriptor(); + if (callableDescriptor instanceof PropertyDescriptor) { + PropertyDescriptor propertyDescriptor = (PropertyDescriptor) callableDescriptor; + if (isEnumProperty(propertyDescriptor)) { + return new EnumValue(propertyDescriptor); + } + } + } + return null; + } + + @Override + public CompileTimeConstant visitQualifiedExpression(JetQualifiedExpression expression, Void data) { + JetExpression selectorExpression = expression.getSelectorExpression(); + if (selectorExpression != null) { + return selectorExpression.accept(this, null); + } + return super.visitQualifiedExpression(expression, data); + } + @Override public CompileTimeConstant visitJetElement(JetElement element, Void nothing) { // TODO: @@ -237,6 +264,16 @@ public class AnnotationResolver { return expression.accept(visitor, null); } + private static boolean isEnumProperty(@NotNull PropertyDescriptor descriptor) { + if (DescriptorUtils.isKindOf(descriptor.getType(), ClassKind.ENUM_CLASS)) { + DeclarationDescriptor enumClassObject = descriptor.getContainingDeclaration(); + if (DescriptorUtils.isKindOf(enumClassObject, ClassKind.CLASS_OBJECT)) { + return DescriptorUtils.isKindOf(enumClassObject.getContainingDeclaration(), ClassKind.ENUM_CLASS); + } + } + return false; + } + @NotNull public List getResolvedAnnotations(@Nullable JetModifierList modifierList, BindingTrace trace) { if (modifierList == null) { diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index c949abc1c20..ab055ef1d93 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -1,5 +1,7 @@ package test +import test.MyEnum.* + ANNOTATION class MyClass [ANNOTATION]([ANNOTATION] param: Int, [ANNOTATION] val consProp: Int) { ANNOTATION class object { } @@ -36,4 +38,9 @@ val funLiteral = {([ANNOTATION] a: Int) -> a } annotation class AnnString(a: String) -annotation class AnnInt(a: Int) \ No newline at end of file +annotation class AnnInt(a: Int) +annotation class AnnEnum(a: MyEnum) + +enum class MyEnum { + A +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 89d4c68a773..92121675578 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -63,6 +63,24 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testEnumAnnotation() throws IOException { + String content = getContent("AnnEnum(MyEnum.A)"); + String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + doTest(content, expectedAnnotation); + } + + public void testQualifiedEnumAnnotation() throws IOException { + String content = getContent("AnnEnum(test.MyEnum.A)"); + String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + doTest(content, expectedAnnotation); + } + + public void testUnqualifiedEnumAnnotation() throws IOException { + String content = getContent("AnnEnum(A)"); + String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass");