Resolve arrays in annotation arguments

This commit is contained in:
Natalia.Ukhorskaya
2013-07-05 14:12:55 +04:00
parent dddec9ea3d
commit 98d3b1e113
4 changed files with 61 additions and 0 deletions
@@ -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<? extends CallableDescriptor> 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<CompileTimeConstant<?>> arguments = Lists.newArrayList();
for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) {
List<ValueArgument> 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:
@@ -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<AnnotationDescriptor> 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());
}
@@ -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<String>)
annotation class AnnArrayOfEnum(a: Array<MyEnum>)
enum class MyEnum {
A
@@ -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");