Support varargs in annotation arguments
This commit is contained in:
@@ -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.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -174,25 +175,48 @@ public class AnnotationResolver {
|
|||||||
if (results.isSuccess()) {
|
if (results.isSuccess()) {
|
||||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument :
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument :
|
||||||
results.getResultingCall().getValueArguments().entrySet()) {
|
results.getResultingCall().getValueArguments().entrySet()) {
|
||||||
// TODO: are varargs supported here?
|
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
|
||||||
List<ValueArgument> valueArguments = descriptorToArgument.getValue().getArguments();
|
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
|
||||||
|
|
||||||
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
|
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
|
||||||
for (ValueArgument argument : valueArguments) {
|
|
||||||
JetExpression argumentExpression = argument.getArgumentExpression();
|
JetType varargElementType = parameterDescriptor.getVarargElementType();
|
||||||
if (argumentExpression != null) {
|
List<CompileTimeConstant<?>> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace);
|
||||||
CompileTimeConstant<?> compileTimeConstant =
|
if (varargElementType == null) {
|
||||||
resolveAnnotationArgument(argumentExpression, parameterDescriptor.getType(), trace);
|
for (CompileTimeConstant<?> constant : constants) {
|
||||||
if (compileTimeConstant != null) {
|
annotationDescriptor.setValueArgument(parameterDescriptor, constant);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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<CompileTimeConstant<?>> resolveValueArguments(
|
||||||
|
@NotNull ResolvedValueArgument resolvedValueArgument,
|
||||||
|
@NotNull JetType expectedType,
|
||||||
|
@NotNull BindingTrace trace
|
||||||
|
) {
|
||||||
|
List<CompileTimeConstant<?>> 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
|
@Nullable
|
||||||
private CompileTimeConstant<?> resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull final JetType expectedType, final BindingTrace trace) {
|
private CompileTimeConstant<?> resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull final JetType expectedType, final BindingTrace trace) {
|
||||||
JetVisitor<CompileTimeConstant<?>, Void> visitor = new JetVisitor<CompileTimeConstant<?>, Void>() {
|
JetVisitor<CompileTimeConstant<?>, Void> visitor = new JetVisitor<CompileTimeConstant<?>, Void>() {
|
||||||
@@ -265,13 +289,7 @@ public class AnnotationResolver {
|
|||||||
JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType();
|
JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType();
|
||||||
List<CompileTimeConstant<?>> arguments = Lists.newArrayList();
|
List<CompileTimeConstant<?>> arguments = Lists.newArrayList();
|
||||||
for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) {
|
for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) {
|
||||||
List<ValueArgument> valueArguments = descriptorToArgument.getArguments();
|
arguments.addAll(resolveValueArguments(descriptorToArgument, type, trace));
|
||||||
for (ValueArgument argument : valueArguments) {
|
|
||||||
JetExpression argumentExpression = argument.getArgumentExpression();
|
|
||||||
if (argumentExpression != null) {
|
|
||||||
arguments.add(resolveAnnotationArgument(argumentExpression, type, trace));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new ArrayValue(arguments, resultingDescriptor.getReturnType());
|
return new ArrayValue(arguments, resultingDescriptor.getReturnType());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ annotation class AnnString(a: String)
|
|||||||
annotation class AnnInt(a: Int)
|
annotation class AnnInt(a: Int)
|
||||||
annotation class AnnEnum(a: MyEnum)
|
annotation class AnnEnum(a: MyEnum)
|
||||||
annotation class AnnIntArray(a: IntArray)
|
annotation class AnnIntArray(a: IntArray)
|
||||||
|
annotation class AnnIntVararg(vararg a: Int)
|
||||||
|
annotation class AnnStringVararg(vararg a: String)
|
||||||
annotation class AnnStringArray(a: Array<String>)
|
annotation class AnnStringArray(a: Array<String>)
|
||||||
annotation class AnnArrayOfEnum(a: Array<MyEnum>)
|
annotation class AnnArrayOfEnum(a: Array<MyEnum>)
|
||||||
|
|
||||||
|
|||||||
+12
@@ -89,6 +89,18 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture {
|
|||||||
doTest(content, expectedAnnotation);
|
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<jet.String>]";
|
||||||
|
doTest(content, expectedAnnotation);
|
||||||
|
}
|
||||||
|
|
||||||
public void testStringArrayAnnotation() throws IOException {
|
public void testStringArrayAnnotation() throws IOException {
|
||||||
String content = getContent("AnnStringArray(array(\"a\"))");
|
String content = getContent("AnnStringArray(array(\"a\"))");
|
||||||
String expectedAnnotation = "AnnStringArray[a = [\"a\"]: jet.Array<jet.String>]";
|
String expectedAnnotation = "AnnStringArray[a = [\"a\"]: jet.Array<jet.String>]";
|
||||||
|
|||||||
Reference in New Issue
Block a user