KT-15010 Missing error on an usage non-constant property in annotation default argument

This commit is contained in:
Dmitry Petrov
2017-01-24 13:36:06 +03:00
parent df8394bcd2
commit 5ef27f7ad3
6 changed files with 93 additions and 4 deletions
@@ -61,8 +61,10 @@ class ValueParameterResolver(
val defaultValue = jetParameter.getDefaultValue() ?: return
expressionTypingServices.getTypeInfo(defaultValue, context.replaceExpectedType(valueParameterDescriptor.type))
if (DescriptorUtils.isAnnotationClass(DescriptorResolver.getContainingClass(context.scope))) {
constantExpressionEvaluator.evaluateExpression(defaultValue, context.trace, valueParameterDescriptor.type)
?: context.trace.report(Errors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT.on(defaultValue))
val constant = constantExpressionEvaluator.evaluateExpression(defaultValue, context.trace, valueParameterDescriptor.type)
if (constant == null || constant.usesNonConstValAsConstant) {
context.trace.report(Errors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT.on(defaultValue))
}
}
}
}
@@ -0,0 +1,12 @@
const val iConst = 42
val iVal = 42
fun iFun() = 42
annotation class Ann(val x: Int)
annotation class Test1(val x: Int = 42)
annotation class Test2(val x: Int = iConst)
annotation class Test3(val x: Int = 1 + iConst + 1)
annotation class Test4(val x: Int = <!ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT!>iVal<!>)
annotation class Test5(val x: Int = <!ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT!>1 + iVal + 1<!>)
annotation class Test6(val x: Int = <!ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT!>iFun()<!>)
annotation class Test7(val x: Int = <!ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT!>1 + iFun() + 1<!>)
@@ -0,0 +1,69 @@
package
public const val iConst: kotlin.Int = 42
public val iVal: kotlin.Int = 42
public fun iFun(): kotlin.Int
public final annotation class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Test1 : kotlin.Annotation {
public constructor Test1(/*0*/ x: kotlin.Int = ...)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Test2 : kotlin.Annotation {
public constructor Test2(/*0*/ x: kotlin.Int = ...)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Test3 : kotlin.Annotation {
public constructor Test3(/*0*/ x: kotlin.Int = ...)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Test4 : kotlin.Annotation {
public constructor Test4(/*0*/ x: kotlin.Int = ...)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Test5 : kotlin.Annotation {
public constructor Test5(/*0*/ x: kotlin.Int = ...)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Test6 : kotlin.Annotation {
public constructor Test6(/*0*/ x: kotlin.Int = ...)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Test7 : kotlin.Annotation {
public constructor Test7(/*0*/ x: kotlin.Int = ...)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1,6 +1,6 @@
import kotlin.reflect.KClass
val CONST = 1
const val CONST = 1
fun foo() = 1
val nonConst = foo()
@@ -1,6 +1,6 @@
package
public val CONST: kotlin.Int = 1
public const val CONST: kotlin.Int = 1
public val nonConst: kotlin.Int
public val nonConstKClass: kotlin.reflect.KClass<kotlin.String>
public fun foo(): kotlin.Int
@@ -1206,6 +1206,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("annotationConstructorDefaultParameter.kt")
public void testAnnotationConstructorDefaultParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/annotationConstructorDefaultParameter.kt");
doTest(fileName);
}
@TestMetadata("booleanLocalVal.kt")
public void testBooleanLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/booleanLocalVal.kt");