From 98d3b1e113f2da352d9606d202fb1b3b4728e05f Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Fri, 5 Jul 2013 14:12:55 +0400 Subject: [PATCH] Resolve arrays in annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 25 +++++++++++++++++++ .../jet/lang/resolve/AnnotationUtils.java | 15 +++++++++++ .../testData/resolveAnnotations/testFile.kt | 3 +++ .../AnnotationDescriptorResolveTest.java | 18 +++++++++++++ 4 files changed, 61 insertions(+) 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 a078c4fae7e..ffda825cae0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -30,6 +30,7 @@ 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.ArrayValue; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -254,6 +255,30 @@ public class AnnotationResolver { return super.visitQualifiedExpression(expression, data); } + @Override + public CompileTimeConstant visitCallExpression(JetCallExpression expression, Void data) { + ResolvedCall call = + trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression()); + if (call != null) { + if (AnnotationUtils.isArrayMethodCall(call)) { + CallableDescriptor resultingDescriptor = call.getResultingDescriptor(); + 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)); + } + } + } + return new ArrayValue(arguments, resultingDescriptor.getReturnType()); + } + } + return null; + } + @Override public CompileTimeConstant visitJetElement(JetElement element, Void nothing) { // TODO: diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java index 5ba69ba59c8..339c19c43ed 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java @@ -19,8 +19,10 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.psi.JetTypeReference; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeUtils; @@ -87,6 +89,19 @@ public class AnnotationUtils { return false; } + public static boolean isArrayMethodCall(@NotNull ResolvedCall resolvedCall) { + List annotations = resolvedCall.getResultingDescriptor().getOriginal().getAnnotations(); + if (annotations != null) { + for (AnnotationDescriptor annotation : annotations) { + //noinspection ConstantConditions + if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().asString())) { + return "kotlin.arrays.array".equals(annotation.getAllValueArguments().values().iterator().next().getValue()); + } + } + } + return false; + } + private static boolean isJavaLangClass(ClassDescriptor descriptor) { return "java.lang.Class".equals(DescriptorUtils.getFQName(descriptor).asString()); } diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index ab055ef1d93..8734dd77b8e 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -40,6 +40,9 @@ val funLiteral = {([ANNOTATION] a: Int) -> a } annotation class AnnString(a: String) annotation class AnnInt(a: Int) annotation class AnnEnum(a: MyEnum) +annotation class AnnIntArray(a: IntArray) +annotation class AnnStringArray(a: Array) +annotation class AnnArrayOfEnum(a: Array) enum class MyEnum { A diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 92121675578..8325b74e56b 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -81,6 +81,24 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testIntArrayAnnotation() throws IOException { + String content = getContent("AnnIntArray(intArray(1, 2))"); + String expectedAnnotation = "AnnIntArray[a = [1.toInt(), 2.toInt()]]"; + doTest(content, expectedAnnotation); + } + + public void testStringArrayAnnotation() throws IOException { + String content = getContent("AnnStringArray(array(\"a\"))"); + String expectedAnnotation = "AnnStringArray[a = [\"a\"]]"; + doTest(content, expectedAnnotation); + } + + public void testEnumArrayAnnotation() throws IOException { + String content = getContent("AnnArrayOfEnum(array(MyEnum.A))"); + String expectedAnnotation = "AnnArrayOfEnum[a = [MyEnum.A]]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass");