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 2852d2f0324..00b575063f6 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.AnnotationValue; import org.jetbrains.jet.lang.resolve.constants.ArrayValue; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.EnumValue; @@ -173,27 +174,34 @@ public class AnnotationResolver { ) { OverloadResolutionResults results = resolveAnnotationCall(annotationEntry, scope, trace); if (results.isSuccess()) { - for (Map.Entry descriptorToArgument : - results.getResultingCall().getValueArguments().entrySet()) { - AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); - assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); + AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); + assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); + resolveAnnotationArgument(annotationDescriptor, results.getResultingCall(), trace); + } + } - ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); + private void resolveAnnotationArgument( + @NotNull AnnotationDescriptor annotationDescriptor, + @NotNull ResolvedCall call, + @NotNull BindingTrace trace + ) { + for (Map.Entry descriptorToArgument : + call.getValueArguments().entrySet()) { + ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); - JetType varargElementType = parameterDescriptor.getVarargElementType(); - List> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace); - if (varargElementType == null) { - for (CompileTimeConstant constant : constants) { - annotationDescriptor.setValueArgument(parameterDescriptor, constant); - } + 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)); + } + else { + JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType); + if (arrayType == null) { + arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType); } + annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType)); } } } @@ -210,7 +218,7 @@ public class AnnotationResolver { if (argumentExpression != null) { CompileTimeConstant constant = resolveAnnotationArgument(argumentExpression, expectedType, trace); if (constant != null) { - constants.add(constant); + constants.add(constant); } } } @@ -284,8 +292,8 @@ public class AnnotationResolver { ResolvedCall call = trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression()); if (call != null) { + CallableDescriptor resultingDescriptor = call.getResultingDescriptor(); 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()) { @@ -293,6 +301,17 @@ public class AnnotationResolver { } return new ArrayValue(arguments, resultingDescriptor.getReturnType()); } + + if (resultingDescriptor instanceof ConstructorDescriptor) { + JetType constructorReturnType = resultingDescriptor.getReturnType(); + assert constructorReturnType != null : "Constructor should have return type"; + if (DescriptorUtils.isAnnotationClass(constructorReturnType.getConstructor().getDeclarationDescriptor())) { + AnnotationDescriptor descriptor = new AnnotationDescriptor(); + descriptor.setAnnotationType(constructorReturnType); + resolveAnnotationArgument(descriptor, call, trace); + return new AnnotationValue(descriptor); + } + } } return null; } diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index 8f6025b4b10..ca0d49d67be 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -45,6 +45,7 @@ annotation class AnnIntVararg(vararg a: Int) annotation class AnnStringVararg(vararg a: String) annotation class AnnStringArray(a: Array) annotation class AnnArrayOfEnum(a: Array) +annotation class AnnAnn(a: AnnInt) 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 1ad56e3a9a7..6129e4c616d 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -113,6 +113,12 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testAnnotationAnnotation() throws Exception { + String content = getContent("AnnAnn(AnnInt(1))"); + String expectedAnnotation = "AnnAnn[a = AnnInt[a = 1.toInt()]: test.AnnInt]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass");