From 42b0bdc54dfd05f212a696721eb9db16f77361cb Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Fri, 5 Jul 2013 18:15:54 +0400 Subject: [PATCH] Support varargs in annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 56 ++++++++++++------- .../testData/resolveAnnotations/testFile.kt | 2 + .../AnnotationDescriptorResolveTest.java | 12 ++++ 3 files changed, 51 insertions(+), 19 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 ffda825cae0..2852d2f0324 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import javax.inject.Inject; import java.util.Collections; @@ -174,25 +175,48 @@ public class AnnotationResolver { if (results.isSuccess()) { for (Map.Entry descriptorToArgument : results.getResultingCall().getValueArguments().entrySet()) { - // TODO: are varargs supported here? - List valueArguments = descriptorToArgument.getValue().getArguments(); + AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); + assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); + ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); - for (ValueArgument argument : valueArguments) { - JetExpression argumentExpression = argument.getArgumentExpression(); - if (argumentExpression != null) { - CompileTimeConstant compileTimeConstant = - resolveAnnotationArgument(argumentExpression, parameterDescriptor.getType(), trace); - if (compileTimeConstant != null) { - AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); - assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); - annotationDescriptor.setValueArgument(parameterDescriptor, compileTimeConstant); - } + + JetType varargElementType = parameterDescriptor.getVarargElementType(); + List> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace); + if (varargElementType == null) { + for (CompileTimeConstant constant : constants) { + annotationDescriptor.setValueArgument(parameterDescriptor, constant); } } + else { + JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType); + if (arrayType == null) { + arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType); + } + annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType)); + } } } } + @NotNull + private List> resolveValueArguments( + @NotNull ResolvedValueArgument resolvedValueArgument, + @NotNull JetType expectedType, + @NotNull BindingTrace trace + ) { + List> constants = Lists.newArrayList(); + for (ValueArgument argument : resolvedValueArgument.getArguments()) { + JetExpression argumentExpression = argument.getArgumentExpression(); + if (argumentExpression != null) { + CompileTimeConstant constant = resolveAnnotationArgument(argumentExpression, expectedType, trace); + if (constant != null) { + constants.add(constant); + } + } + } + return constants; + } + @Nullable private CompileTimeConstant resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull final JetType expectedType, final BindingTrace trace) { JetVisitor, Void> visitor = new JetVisitor, Void>() { @@ -265,13 +289,7 @@ public class AnnotationResolver { JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType(); List> arguments = Lists.newArrayList(); for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) { - List valueArguments = descriptorToArgument.getArguments(); - for (ValueArgument argument : valueArguments) { - JetExpression argumentExpression = argument.getArgumentExpression(); - if (argumentExpression != null) { - arguments.add(resolveAnnotationArgument(argumentExpression, type, trace)); - } - } + arguments.addAll(resolveValueArguments(descriptorToArgument, type, trace)); } return new ArrayValue(arguments, resultingDescriptor.getReturnType()); } diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index 8734dd77b8e..8f6025b4b10 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -41,6 +41,8 @@ annotation class AnnString(a: String) annotation class AnnInt(a: Int) annotation class AnnEnum(a: MyEnum) annotation class AnnIntArray(a: IntArray) +annotation class AnnIntVararg(vararg a: Int) +annotation class AnnStringVararg(vararg a: String) annotation class AnnStringArray(a: Array) annotation class AnnArrayOfEnum(a: Array) diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 126b50b6f34..1ad56e3a9a7 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -89,6 +89,18 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testIntArrayVarargAnnotation() throws IOException { + String content = getContent("AnnIntVararg(1, 2)"); + String expectedAnnotation = "AnnIntVararg[a = [1.toInt(), 2.toInt()]: jet.IntArray]"; + doTest(content, expectedAnnotation); + } + + public void testStringArrayVarargAnnotation() throws IOException { + String content = getContent("AnnStringVararg(\"a\", \"b\")"); + String expectedAnnotation = "AnnStringVararg[a = [\"a\", \"b\"]: jet.Array]"; + doTest(content, expectedAnnotation); + } + public void testStringArrayAnnotation() throws IOException { String content = getContent("AnnStringArray(array(\"a\"))"); String expectedAnnotation = "AnnStringArray[a = [\"a\"]: jet.Array]";