From c9a600a405af4cb0d118288702a515eb51f70893 Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Wed, 18 Dec 2013 10:59:46 +0400 Subject: [PATCH] Fix for varargs as annotation arguments #KT-4326 Fixed --- .../jet/lang/resolve/AnnotationResolver.java | 42 ++++++---------- .../jet/lang/resolve/BodyResolver.java | 2 +- .../varargInAnnotationParameter.kt | 50 +++++++++++++++---- ...lackBoxWithStdlibCodegenTestGenerated.java | 16 +++++- 4 files changed, 70 insertions(+), 40 deletions(-) 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 8e246ba8bda..edb13616886 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -45,10 +45,7 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import javax.inject.Inject; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; @@ -221,21 +218,27 @@ public class AnnotationResolver { JetType varargElementType = parameterDescriptor.getVarargElementType(); List> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace); - if (varargElementType == null) { - for (CompileTimeConstant constant : constants) { - annotationDescriptor.setValueArgument(parameterDescriptor, constant); - } - } - else { + + if (varargElementType != null && !hasSpread(descriptorToArgument.getValue())) { JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType); if (arrayType == null) { arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType); } annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType)); } + else { + for (CompileTimeConstant constant : constants) { + annotationDescriptor.setValueArgument(parameterDescriptor, constant); + } + } } } + private static boolean hasSpread(@NotNull ResolvedValueArgument argument) { + List arguments = argument.getArguments(); + return arguments.size() == 1 && arguments.get(0).getSpreadElement() != null; + } + @NotNull private static List> resolveValueArguments( @NotNull ResolvedValueArgument resolvedValueArgument, @@ -246,7 +249,7 @@ public class AnnotationResolver { for (ValueArgument argument : resolvedValueArgument.getArguments()) { JetExpression argumentExpression = argument.getArgumentExpression(); if (argumentExpression != null) { - CompileTimeConstant constant = resolveExpressionToCompileTimeValue(argumentExpression, expectedType, trace); + CompileTimeConstant constant = ConstantExpressionEvaluator.object$.evaluate(argumentExpression, trace, expectedType); if (constant instanceof IntegerValueTypeConstant) { IntegerValueTypeConstructor typeConstructor = ((IntegerValueTypeConstant) constant).getValue(); JetType defaultType = getPrimitiveNumberType(typeConstructor, expectedType); @@ -275,23 +278,6 @@ public class AnnotationResolver { return constants; } - @Nullable - public static CompileTimeConstant resolveExpressionToCompileTimeValue( - @NotNull JetExpression expression, - @NotNull JetType expectedType, - @NotNull BindingTrace trace - ) { - return ConstantExpressionEvaluator.object$.evaluate(expression, trace, expectedType); - } - - @NotNull - public List getResolvedAnnotations(@Nullable JetModifierList modifierList, BindingTrace trace) { - if (modifierList == null) { - return Collections.emptyList(); - } - return getResolvedAnnotations(modifierList.getAnnotationEntries(), trace); - } - @SuppressWarnings("MethodMayBeStatic") @NotNull public List getResolvedAnnotations(@NotNull List annotations, @NotNull BindingTrace trace) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 51c27fc7d03..b6c3c32ab55 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -557,7 +557,7 @@ public class BodyResolver { JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE; expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, context.getOuterDataFlowInfo(), trace); if (AnnotationUtils.isPropertyCompileTimeConstant(propertyDescriptor)) { - CompileTimeConstant constant = AnnotationResolver.resolveExpressionToCompileTimeValue(initializer, expectedTypeForInitializer, trace); + CompileTimeConstant constant = ConstantExpressionEvaluator.object$.evaluate(initializer, trace, expectedTypeForInitializer); if (constant != null) { trace.record(BindingContext.COMPILE_TIME_INITIALIZER, propertyDescriptor, constant); } diff --git a/compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt b/compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt index d845f7ee4d4..bcb6d456c13 100644 --- a/compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt +++ b/compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt @@ -2,20 +2,50 @@ import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy Retention(RetentionPolicy.RUNTIME) -annotation class Ann(val s: String, vararg val p: Int) +annotation class Ann(vararg val p: Int) -Ann("str", 1, 2, 3) class MyClass +Ann() class MyClass1 +Ann(1) class MyClass2 +Ann(1, 2) class MyClass3 + +Ann(*intArray()) class MyClass4 +Ann(*intArray(1)) class MyClass5 +Ann(*intArray(1, 2)) class MyClass6 + +Ann(p = 1) class MyClass7 + +Ann(p = *intArray()) class MyClass8 +Ann(p = *intArray(1)) class MyClass9 +Ann(p = *intArray(1, 2)) class MyClass10 fun box(): String { - val ann = javaClass().getAnnotation(javaClass()) - if (ann == null) return "fail: cannot find Ann on MyClass" - if (ann.s != "str") return "fail: annotation parameter s should be \"str\"" - if (ann.p[0] != 1) return "fail: annotation parameter p[0] should be 1" - if (ann.p[1] != 2) return "fail: annotation parameter p[1] should be 2" - if (ann.p[2] != 3) return "fail: annotation parameter p[2] should be 3" + test(javaClass(), "") + test(javaClass(), "1") + test(javaClass(), "12") + + test(javaClass(), "") + test(javaClass(), "1") + test(javaClass(), "12") + + test(javaClass(), "1") + + test(javaClass(), "") + test(javaClass(), "1") + test(javaClass(), "12") + return "OK" } -fun main(args: Array) { - println(box()) +fun test(klass: Class<*>, expected: String) { + val ann = klass.getAnnotation(javaClass()) + if (ann == null) throw AssertionError("fail: cannot find Ann on ${klass}") + + var result = "" + for (i in ann.p) { + result += i + } + + if (result != expected) { + throw AssertionError("fail: expected = ${expected}, actual = ${result}") + } } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 0964f4c7e1b..f1802513137 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithStdlib") -@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class}) +@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class}) public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithStdlib() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib"), Pattern.compile("^(.+)\\.kt$"), true); @@ -1051,6 +1051,19 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/vararg") + public static class Vararg extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInVararg() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib/vararg"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("varargInFunParam.kt") + public void testVarargInFunParam() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/vararg/varargInFunParam.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("BlackBoxWithStdlibCodegenTestGenerated"); suite.addTestSuite(BlackBoxWithStdlibCodegenTestGenerated.class); @@ -1065,6 +1078,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode suite.addTestSuite(Regressions.class); suite.addTestSuite(Strings.class); suite.addTestSuite(ToArray.class); + suite.addTestSuite(Vararg.class); return suite; } }