Fix for varargs as annotation arguments #KT-4326 Fixed
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
+40
-10
@@ -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}")
|
||||
}
|
||||
}
|
||||
+15
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user