Fix for varargs as annotation arguments #KT-4326 Fixed

This commit is contained in:
Natalia Ukhorskaya
2013-12-18 10:59:46 +04:00
parent 145c7811a8
commit c9a600a405
4 changed files with 70 additions and 40 deletions
@@ -45,10 +45,7 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
@@ -221,21 +218,27 @@ public class AnnotationResolver {
JetType varargElementType = parameterDescriptor.getVarargElementType();
List<CompileTimeConstant<?>> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace);
if (varargElementType == null) {
for (CompileTimeConstant<?> constant : constants) {
annotationDescriptor.setValueArgument(parameterDescriptor, constant);
}
}
else {
if (varargElementType != null && !hasSpread(descriptorToArgument.getValue())) {
JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType);
if (arrayType == null) {
arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType);
}
annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType));
}
else {
for (CompileTimeConstant<?> constant : constants) {
annotationDescriptor.setValueArgument(parameterDescriptor, constant);
}
}
}
}
private static boolean hasSpread(@NotNull ResolvedValueArgument argument) {
List<ValueArgument> arguments = argument.getArguments();
return arguments.size() == 1 && arguments.get(0).getSpreadElement() != null;
}
@NotNull
private static List<CompileTimeConstant<?>> resolveValueArguments(
@NotNull ResolvedValueArgument resolvedValueArgument,
@@ -246,7 +249,7 @@ public class AnnotationResolver {
for (ValueArgument argument : resolvedValueArgument.getArguments()) {
JetExpression argumentExpression = argument.getArgumentExpression();
if (argumentExpression != null) {
CompileTimeConstant<?> constant = resolveExpressionToCompileTimeValue(argumentExpression, expectedType, trace);
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.object$.evaluate(argumentExpression, trace, expectedType);
if (constant instanceof IntegerValueTypeConstant) {
IntegerValueTypeConstructor typeConstructor = ((IntegerValueTypeConstant) constant).getValue();
JetType defaultType = getPrimitiveNumberType(typeConstructor, expectedType);
@@ -275,23 +278,6 @@ public class AnnotationResolver {
return constants;
}
@Nullable
public static CompileTimeConstant<?> resolveExpressionToCompileTimeValue(
@NotNull JetExpression expression,
@NotNull JetType expectedType,
@NotNull BindingTrace trace
) {
return ConstantExpressionEvaluator.object$.evaluate(expression, trace, expectedType);
}
@NotNull
public List<AnnotationDescriptor> getResolvedAnnotations(@Nullable JetModifierList modifierList, BindingTrace trace) {
if (modifierList == null) {
return Collections.emptyList();
}
return getResolvedAnnotations(modifierList.getAnnotationEntries(), trace);
}
@SuppressWarnings("MethodMayBeStatic")
@NotNull
public List<AnnotationDescriptor> getResolvedAnnotations(@NotNull List<JetAnnotationEntry> annotations, @NotNull BindingTrace trace) {
@@ -557,7 +557,7 @@ public class BodyResolver {
JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, context.getOuterDataFlowInfo(), trace);
if (AnnotationUtils.isPropertyCompileTimeConstant(propertyDescriptor)) {
CompileTimeConstant<?> constant = AnnotationResolver.resolveExpressionToCompileTimeValue(initializer, expectedTypeForInitializer, trace);
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.object$.evaluate(initializer, trace, expectedTypeForInitializer);
if (constant != null) {
trace.record(BindingContext.COMPILE_TIME_INITIALIZER, propertyDescriptor, constant);
}
@@ -2,20 +2,50 @@ import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
Retention(RetentionPolicy.RUNTIME)
annotation class Ann(val s: String, vararg val p: Int)
annotation class Ann(vararg val p: Int)
Ann("str", 1, 2, 3) class MyClass
Ann() class MyClass1
Ann(1) class MyClass2
Ann(1, 2) class MyClass3
Ann(*intArray()) class MyClass4
Ann(*intArray(1)) class MyClass5
Ann(*intArray(1, 2)) class MyClass6
Ann(p = 1) class MyClass7
Ann(p = *intArray()) class MyClass8
Ann(p = *intArray(1)) class MyClass9
Ann(p = *intArray(1, 2)) class MyClass10
fun box(): String {
val ann = javaClass<MyClass>().getAnnotation(javaClass<Ann>())
if (ann == null) return "fail: cannot find Ann on MyClass"
if (ann.s != "str") return "fail: annotation parameter s should be \"str\""
if (ann.p[0] != 1) return "fail: annotation parameter p[0] should be 1"
if (ann.p[1] != 2) return "fail: annotation parameter p[1] should be 2"
if (ann.p[2] != 3) return "fail: annotation parameter p[2] should be 3"
test(javaClass<MyClass1>(), "")
test(javaClass<MyClass2>(), "1")
test(javaClass<MyClass3>(), "12")
test(javaClass<MyClass4>(), "")
test(javaClass<MyClass5>(), "1")
test(javaClass<MyClass6>(), "12")
test(javaClass<MyClass7>(), "1")
test(javaClass<MyClass8>(), "")
test(javaClass<MyClass9>(), "1")
test(javaClass<MyClass10>(), "12")
return "OK"
}
fun main(args: Array<String>) {
println(box())
fun test(klass: Class<*>, expected: String) {
val ann = klass.getAnnotation(javaClass<Ann>())
if (ann == null) throw AssertionError("fail: cannot find Ann on ${klass}")
var result = ""
for (i in ann.p) {
result += i
}
if (result != expected) {
throw AssertionError("fail: expected = ${expected}, actual = ${result}")
}
}
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/boxWithStdlib")
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class})
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class})
public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBoxWithStdlib() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -1051,6 +1051,19 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/vararg")
public static class Vararg extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInVararg() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib/vararg"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("varargInFunParam.kt")
public void testVarargInFunParam() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/vararg/varargInFunParam.kt");
}
}
public static Test suite() {
TestSuite suite = new TestSuite("BlackBoxWithStdlibCodegenTestGenerated");
suite.addTestSuite(BlackBoxWithStdlibCodegenTestGenerated.class);
@@ -1065,6 +1078,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
suite.addTestSuite(Regressions.class);
suite.addTestSuite(Strings.class);
suite.addTestSuite(ToArray.class);
suite.addTestSuite(Vararg.class);
return suite;
}
}