From ec02382976998801cc0025c7f9f4a3c13357036c Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 27 Aug 2014 12:36:11 +0400 Subject: [PATCH] Assert that reference annotation argument is always an enum value Rename JavaReferenceAnnotationArgument on that occasion to JavaEnumValueAnnotationArgument. Also add a test on a nested enum annotation argument --- .../impl/JavaAnnotationArgumentImpl.java | 2 +- ... JavaEnumValueAnnotationArgumentImpl.java} | 23 +++++++------ .../annotations/NestedEnumArgument.java | 14 ++++++++ .../annotations/NestedEnumArgument.txt | 33 +++++++++++++++++++ .../jvm/compiler/LoadJavaTestGenerated.java | 6 ++++ .../LazyJavaAnnotationDescriptor.kt | 8 ++--- ...a => JavaEnumValueAnnotationArgument.java} | 4 +-- 7 files changed, 70 insertions(+), 20 deletions(-) rename compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/{JavaReferenceAnnotationArgumentImpl.java => JavaEnumValueAnnotationArgumentImpl.java} (62%) create mode 100644 compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.java create mode 100644 compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.txt rename core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/{JavaReferenceAnnotationArgument.java => JavaEnumValueAnnotationArgument.java} (88%) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaAnnotationArgumentImpl.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaAnnotationArgumentImpl.java index 2c67cc202ab..77e802e9c4f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaAnnotationArgumentImpl.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaAnnotationArgumentImpl.java @@ -39,7 +39,7 @@ public abstract class JavaAnnotationArgumentImpl - implements JavaReferenceAnnotationArgument { - protected JavaReferenceAnnotationArgumentImpl(@NotNull PsiReferenceExpression psiReferenceExpression, @Nullable Name name) { +public class JavaEnumValueAnnotationArgumentImpl extends JavaAnnotationArgumentImpl + implements JavaEnumValueAnnotationArgument { + protected JavaEnumValueAnnotationArgumentImpl(@NotNull PsiReferenceExpression psiReferenceExpression, @Nullable Name name) { super(psiReferenceExpression, name); } @Override @Nullable - public JavaElement resolve() { - PsiReferenceExpression expression = getPsi(); - PsiElement element = expression.resolve(); - if (element instanceof PsiEnumConstant) { - return new JavaFieldImpl((PsiField) element); + public JavaField resolve() { + PsiElement element = getPsi().resolve(); + if (element == null) return null; + if (!(element instanceof PsiEnumConstant)) { + throw new IllegalStateException("Reference argument should be an enum value, but was " + element + ": " + element.getText()); } - // TODO: other types of references - return null; + return new JavaFieldImpl((PsiField) element); } } diff --git a/compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.java b/compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.java new file mode 100644 index 00000000000..34643a58a4f --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.java @@ -0,0 +1,14 @@ +package test; + +public class NestedEnumArgument { + public enum E { + FIRST + } + + @interface Anno { + E value(); + } + + @Anno(E.FIRST) + void foo() {} +} diff --git a/compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.txt b/compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.txt new file mode 100644 index 00000000000..eeb14afcd6d --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.txt @@ -0,0 +1,33 @@ +package test + +public open class NestedEnumArgument { + public constructor NestedEnumArgument() + test.NestedEnumArgument.Anno(value = E.FIRST: test.NestedEnumArgument.E) public/*package*/ open fun foo(): kotlin.Unit + + public/*package*/ final annotation class Anno : kotlin.Annotation { + public/*package*/ constructor Anno(/*0*/ value: test.NestedEnumArgument.E) + public abstract fun value(): test.NestedEnumArgument.E + } + + public final enum class E : kotlin.Enum { + private constructor E() + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + + public enum entry FIRST : test.NestedEnumArgument.E { + private constructor FIRST() + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + + public class object : test.NestedEnumArgument.E.FIRST { + private constructor () + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + } + } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.NestedEnumArgument.E + public final /*synthesized*/ fun values(): kotlin.Array + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 24c0c86e528..30700beb146 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -374,6 +374,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava(fileName); } + @TestMetadata("NestedEnumArgument.java") + public void testNestedEnumArgument() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/annotations/NestedEnumArgument.java"); + doTestCompiledJava(fileName); + } + @TestMetadata("PrimitiveValueInParam.java") public void testPrimitiveValueInParam() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/annotations/PrimitiveValueInParam.java"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index 0d2c524dacc..e89adc7fdc4 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -100,7 +100,7 @@ class LazyJavaAnnotationDescriptor( private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): CompileTimeConstant<*>? { return when (argument) { is JavaLiteralAnnotationArgument -> createCompileTimeConstant(argument.getValue(), true, false, false, null) - is JavaReferenceAnnotationArgument -> resolveFromReference(argument.resolve()) + is JavaEnumValueAnnotationArgument -> resolveFromEnumValue(argument.resolve()) is JavaArrayAnnotationArgument -> resolveFromArray(argument.getName() ?: DEFAULT_ANNOTATION_MEMBER_NAME, argument.getElements()) is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation()) is JavaClassObjectAnnotationArgument -> resolveFromJavaClassObjectType(argument.getReferencedType()) @@ -131,10 +131,8 @@ class LazyJavaAnnotationDescriptor( return ArrayValue(values, valueParameter.getType(), true, values.any { it.usesVariableAsConstant() }) } - private fun resolveFromReference(element: JavaElement?): CompileTimeConstant<*>? { - if (element !is JavaField) return null - - if (!element.isEnumEntry()) return null + private fun resolveFromEnumValue(element: JavaField?): CompileTimeConstant<*>? { + if (element == null || !element.isEnumEntry()) return null val containingJavaClass = element.getContainingClass() diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaReferenceAnnotationArgument.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaEnumValueAnnotationArgument.java similarity index 88% rename from core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaReferenceAnnotationArgument.java rename to core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaEnumValueAnnotationArgument.java index c8ad41e9a0b..ff8742f0859 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaReferenceAnnotationArgument.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaEnumValueAnnotationArgument.java @@ -18,7 +18,7 @@ package org.jetbrains.jet.lang.resolve.java.structure; import org.jetbrains.annotations.Nullable; -public interface JavaReferenceAnnotationArgument extends JavaAnnotationArgument { +public interface JavaEnumValueAnnotationArgument extends JavaAnnotationArgument { @Nullable - JavaElement resolve(); + JavaField resolve(); }