diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 79e15f0c502..339452f6775 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -131,6 +131,7 @@ public interface Errors { DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_KCLASS_LITERAL = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_ENUM_CONST = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 DEPRECATED_ANNOTATION_SYNTAX = DiagnosticFactory0.create(WARNING); + DiagnosticFactory0 ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT = DiagnosticFactory0.create(ERROR); // Classes and traits diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 5c6649b122a..54ae7f2bf7c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -567,6 +567,7 @@ public class DefaultErrorMessages { MAP.put(ANNOTATION_PARAMETER_MUST_BE_CLASS_LITERAL, "An annotation parameter must be a `javaClass()` call"); MAP.put(ANNOTATION_PARAMETER_MUST_BE_KCLASS_LITERAL, "An annotation parameter must be a class literal (T::class)"); MAP.put(DEPRECATED_ANNOTATION_SYNTAX, "This syntax for annotations is deprecated. Use '@' before annotation identifier instead"); + MAP.put(ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT, "Default value of annotation parameter must be a compile-time constant"); MAP.put(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE, "An overriding function is not allowed to specify default values for its parameters"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt index 1ab4ded8b9f..bae1179f575 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.types.expressions import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.JetParameter import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo @@ -65,6 +66,7 @@ public class ValueParameterResolver( expressionTypingServices.getTypeInfo(defaultValue, context.replaceExpectedType(valueParameterDescriptor.getType())) if (DescriptorUtils.isAnnotationClass(DescriptorResolver.getContainingClass(context.scope))) { ConstantExpressionEvaluator.evaluate(defaultValue, context.trace, valueParameterDescriptor.getType()) + ?: context.trace.report(Errors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT.on(defaultValue)) } } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.kt new file mode 100644 index 00000000000..81d235a213c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.kt @@ -0,0 +1,22 @@ +import kotlin.reflect.KClass + +val CONST = 1 +fun foo() = 1 +val nonConst = foo() + +annotation class ValidAnn( + val p1: Int = 1 + CONST, + val p2: String = "", + val p3: KClass<*> = String::class, + val p4: IntArray = intArrayOf(1, 2, 3), + val p5: Array = arrayOf("abc"), + val p6: Array> = arrayOf(Int::class) +) + +val nonConstKClass = String::class + +annotation class InvalidAnn( + val p1: Int = foo(), + val p2: Int = nonConst, + val p3: KClass<*> = nonConstKClass +) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.txt new file mode 100644 index 00000000000..811b3654351 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.txt @@ -0,0 +1,29 @@ +package + +internal val CONST: kotlin.Int = 1 +internal val nonConst: kotlin.Int +internal val nonConstKClass: kotlin.reflect.KClass +internal fun foo(): kotlin.Int + +internal final annotation class InvalidAnn : kotlin.Annotation { + public constructor InvalidAnn(/*0*/ p1: kotlin.Int = ..., /*1*/ p2: kotlin.Int = ..., /*2*/ p3: kotlin.reflect.KClass<*> = ...) + internal final val p1: kotlin.Int + internal final val p2: kotlin.Int + internal final val p3: kotlin.reflect.KClass<*> + 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 +} + +internal final annotation class ValidAnn : kotlin.Annotation { + public constructor ValidAnn(/*0*/ p1: kotlin.Int = ..., /*1*/ p2: kotlin.String = ..., /*2*/ p3: kotlin.reflect.KClass<*> = ..., /*3*/ p4: kotlin.IntArray = ..., /*4*/ p5: kotlin.Array = ..., /*5*/ p6: kotlin.Array> = ...) + internal final val p1: kotlin.Int + internal final val p2: kotlin.String + internal final val p3: kotlin.reflect.KClass<*> + internal final val p4: kotlin.IntArray + internal final val p5: kotlin.Array + internal final val p6: kotlin.Array> + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 4f15c68981a..a4f75d0b9e1 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -61,6 +61,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } + @TestMetadata("defaultValueMustBeConstant.kt") + public void testDefaultValueMustBeConstant() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.kt"); + doTest(fileName); + } + @TestMetadata("qualifiedCallValue.kt") public void testQualifiedCallValue() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt");