From afd4e644a335516426bf5d20ab04614f437eb52b Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 21 Sep 2015 18:14:35 +0300 Subject: [PATCH] Report warning on usages of non-const vals in places where constants expected --- .../jetbrains/kotlin/diagnostics/Errors.java | 2 ++ .../rendering/DefaultErrorMessages.java | 1 + .../kotlin/resolve/DescriptorResolver.java | 13 +++++-- .../evaluate/ConstantExpressionEvaluator.kt | 35 +++++++++++++------ .../RecursivelyAnnotatedGlobalProperty.kt | 2 +- .../RecursivelyAnnotatedGlobalProperty.txt | 2 +- .../kotlinProperties.kt | 4 +-- .../kotlinProperties.txt | 4 +-- .../strings.kt | 2 +- .../strings.txt | 2 +- .../tests/functionAsExpression/Common.kt | 2 +- .../tests/functionAsExpression/Common.txt | 2 +- .../array.kt | 2 +- .../array.txt | 2 +- .../useOfNonConstVal.kt | 16 +++++++++ .../useOfNonConstVal.txt | 24 +++++++++++++ .../vararg.kt | 2 +- .../vararg.txt | 2 +- ...JetDiagnosticsTestWithStdLibGenerated.java | 6 ++++ .../resolve/constants/CompileTimeConstant.kt | 5 ++- idea/testData/checker/AnnotationOnFile.kt | 4 +-- 21 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index d965d5cf3b5..a5216e3dd40 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -141,6 +141,8 @@ public interface Errors { DiagnosticFactory0 CONST_VAL_WITHOUT_INITIALIZER = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 CONST_VAL_WITH_NON_CONST_INITIALIZER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION = DiagnosticFactory0.create(WARNING); + DiagnosticFactory1 INAPPLICABLE_TARGET_ON_PROPERTY = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 INAPPLICABLE_FIELD_TARGET_NO_BACKING_FIELD = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE = DiagnosticFactory0.create(ERROR); 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 70273938bd8..e45c7df0b10 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -602,6 +602,7 @@ public class DefaultErrorMessages { MAP.put(TYPE_CANT_BE_USED_FOR_CONST_VAL, "Const 'val' has type ''{0}''. Only primitives and String are allowed", RENDER_TYPE); MAP.put(CONST_VAL_WITHOUT_INITIALIZER, "Const 'val' should have an initializer"); MAP.put(CONST_VAL_WITH_NON_CONST_INITIALIZER, "Const 'val' initializer should be a constant value"); + MAP.put(NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION, "Only 'const val' can be used in constant expressions"); 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/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index b191e952af8..9ee0c8efb88 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; +import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsPackage; @@ -880,7 +881,7 @@ public class DescriptorResolver { } private void setConstantForVariableIfNeeded( - @NotNull VariableDescriptorWithInitializerImpl variableDescriptor, + @NotNull final VariableDescriptorWithInitializerImpl variableDescriptor, @NotNull final LexicalScope scope, @NotNull final JetVariableDeclaration variable, @NotNull final DataFlowInfo dataFlowInfo, @@ -898,7 +899,15 @@ public class DescriptorResolver { public ConstantValue invoke() { JetExpression initializer = variable.getInitializer(); JetType initializerType = expressionTypingServices.safeGetType(scope, initializer, variableType, dataFlowInfo, trace); - return constantExpressionEvaluator.evaluateToConstantValue(initializer, trace, initializerType); + CompileTimeConstant constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType); + + if (constant == null) return null; + + if (constant.getUsesNonConstValAsConstant() && variableDescriptor.isConst()) { + trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(initializer)); + } + + return constant.toConstantValue(initializerType); } }, null) ); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index 4440303451c..aa7e81cdf8c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -124,6 +124,9 @@ public class ConstantExpressionEvaluator( val constant = ConstantExpressionEvaluator.getConstant(argumentExpression, trace.getBindingContext()) if (constant != null && constant.canBeUsedInAnnotations) { + if (constant.usesNonConstValAsConstant) { + trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(argumentExpression)) + } return } @@ -284,7 +287,7 @@ private class ConstantExpressionEvaluatorVisitor( } ?: return null fun isLongWithSuffix() = nodeElementType == JetNodeTypes.INTEGER_CONSTANT && hasLongSuffix(text) - return createConstant(result, expectedType, CompileTimeConstant.Parameters(true, !isLongWithSuffix(), false)) + return createConstant(result, expectedType, CompileTimeConstant.Parameters(true, !isLongWithSuffix(), false, usesNonConstValAsConstant = false)) } override fun visitParenthesizedExpression(expression: JetParenthesizedExpression, expectedType: JetType?): CompileTimeConstant<*>? { @@ -308,6 +311,7 @@ private class ConstantExpressionEvaluatorVisitor( var interupted = false var canBeUsedInAnnotation = true var usesVariableAsConstant = false + var usesNonConstantVariableAsConstant = false for (entry in expression.getEntries()) { val constant = stringExpressionEvaluator.evaluate(entry) if (constant == null) { @@ -317,6 +321,7 @@ private class ConstantExpressionEvaluatorVisitor( else { if (!constant.canBeUsedInAnnotations) canBeUsedInAnnotation = false if (constant.usesVariableAsConstant) usesVariableAsConstant = true + if (constant.usesNonConstValAsConstant) usesNonConstantVariableAsConstant = true sb.append(constant.constantValue.value) } } @@ -327,7 +332,8 @@ private class ConstantExpressionEvaluatorVisitor( CompileTimeConstant.Parameters( isPure = false, canBeUsedInAnnotation = canBeUsedInAnnotation, - usesVariableAsConstant = usesVariableAsConstant + usesVariableAsConstant = usesVariableAsConstant, + usesNonConstValAsConstant = usesNonConstantVariableAsConstant ) ) else null @@ -363,7 +369,8 @@ private class ConstantExpressionEvaluatorVisitor( CompileTimeConstant.Parameters( canBeUsedInAnnotation = true, isPure = false, - usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant + usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant, + usesNonConstValAsConstant = leftConstant.usesNonConstValAsConstant || rightConstant.usesNonConstValAsConstant ) ) } @@ -388,6 +395,7 @@ private class ConstantExpressionEvaluatorVisitor( val isArgumentPure = isPureConstant(argumentForReceiver.expression) val canBeUsedInAnnotation = canBeUsedInAnnotation(argumentForReceiver.expression) val usesVariableAsConstant = usesVariableAsConstant(argumentForReceiver.expression) + val usesNonConstValAsConstant = usesNonConstValAsConstant(argumentForReceiver.expression) val isNumberConversionMethod = resultingDescriptorName in OperatorConventions.NUMBER_CONVERSIONS return createConstant( result, @@ -395,7 +403,7 @@ private class ConstantExpressionEvaluatorVisitor( CompileTimeConstant.Parameters( canBeUsedInAnnotation, !isNumberConversionMethod && isArgumentPure, - usesVariableAsConstant) + usesVariableAsConstant, usesNonConstValAsConstant) ) } else if (argumentsEntrySet.size() == 1) { @@ -415,7 +423,8 @@ private class ConstantExpressionEvaluatorVisitor( val areArgumentsPure = isPureConstant(argumentForReceiver.expression) && isPureConstant(argumentForParameter.expression) val canBeUsedInAnnotation = canBeUsedInAnnotation(argumentForReceiver.expression) && canBeUsedInAnnotation(argumentForParameter.expression) val usesVariableAsConstant = usesVariableAsConstant(argumentForReceiver.expression) || usesVariableAsConstant(argumentForParameter.expression) - val parameters = CompileTimeConstant.Parameters(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant) + val usesNonConstValAsConstant = usesNonConstValAsConstant(argumentForReceiver.expression) || usesNonConstValAsConstant(argumentForParameter.expression) + val parameters = CompileTimeConstant.Parameters(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant, usesNonConstValAsConstant) return when (resultingDescriptorName) { OperatorConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression, factory)?.wrap(parameters) OperatorConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression, factory)?.wrap(parameters) @@ -429,6 +438,8 @@ private class ConstantExpressionEvaluatorVisitor( } private fun usesVariableAsConstant(expression: JetExpression) = ConstantExpressionEvaluator.getConstant(expression, trace.getBindingContext())?.usesVariableAsConstant ?: false + private fun usesNonConstValAsConstant(expression: JetExpression) + = ConstantExpressionEvaluator.getConstant(expression, trace.bindingContext)?.usesNonConstValAsConstant ?: false private fun canBeUsedInAnnotation(expression: JetExpression) = ConstantExpressionEvaluator.getConstant(expression, trace.getBindingContext())?.canBeUsedInAnnotations ?: false @@ -515,7 +526,8 @@ private class ConstantExpressionEvaluatorVisitor( CompileTimeConstant.Parameters( canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor), isPure = false, - usesVariableAsConstant = true + usesVariableAsConstant = true, + usesNonConstValAsConstant = !callableDescriptor.isConst ) ) } @@ -523,6 +535,7 @@ private class ConstantExpressionEvaluatorVisitor( return null } + // TODO: Should be replaced with descriptor.isConst private fun isPropertyCompileTimeConstant(descriptor: VariableDescriptor): Boolean { if (descriptor.isVar()) { return false @@ -566,7 +579,7 @@ private class ConstantExpressionEvaluatorVisitor( val resultingDescriptor = call.getResultingDescriptor() - // array() + // arrayOf() if (CompileTimeConstantUtils.isArrayMethodCall(call)) { val varargType = resultingDescriptor.getValueParameters().first().getVarargElementType()!! @@ -574,7 +587,8 @@ private class ConstantExpressionEvaluatorVisitor( return factory.createArrayValue(arguments.map { it.toConstantValue(varargType) }, resultingDescriptor.getReturnType()!!). wrap( - usesVariableAsConstant = arguments.any { it.usesVariableAsConstant } + usesVariableAsConstant = arguments.any { it.usesVariableAsConstant }, + usesNonConstValAsConstant = arguments.any { it.usesNonConstValAsConstant } ) } @@ -696,9 +710,10 @@ private class ConstantExpressionEvaluatorVisitor( private fun ConstantValue.wrap( canBeUsedInAnnotation: Boolean = this !is NullValue, isPure: Boolean = false, - usesVariableAsConstant: Boolean = false + usesVariableAsConstant: Boolean = false, + usesNonConstValAsConstant: Boolean = false ): TypedCompileTimeConstant - = wrap(CompileTimeConstant.Parameters(canBeUsedInAnnotation, isPure, usesVariableAsConstant)) + = wrap(CompileTimeConstant.Parameters(canBeUsedInAnnotation, isPure, usesVariableAsConstant, usesNonConstValAsConstant)) } private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L') diff --git a/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.kt b/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.kt index d5618920bdd..638a1728975 100644 --- a/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.kt +++ b/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.kt @@ -1,3 +1,3 @@ // Properties can be recursively annotated annotation class ann(val x: Int) -@ann(x) val x: Int = 1 \ No newline at end of file +@ann(x) const val x: Int = 1 \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.txt b/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.txt index 17fe6e1a627..2340f83fb54 100644 --- a/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.txt +++ b/compiler/testData/diagnostics/tests/annotations/RecursivelyAnnotatedGlobalProperty.txt @@ -1,6 +1,6 @@ package -@ann(x = 1) public val x: kotlin.Int = 1 +@ann(x = 1) public const val x: kotlin.Int = 1 @kotlin.annotation.annotation() public final class ann : kotlin.Annotation { public constructor ann(/*0*/ x: kotlin.Int) diff --git a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.kt b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.kt index b0308605b29..f1e30662de0 100644 --- a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.kt +++ b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.kt @@ -11,8 +11,8 @@ annotation class Ann(vararg val i: Int) class Test var i1 = 1 // var -val i2 = 1 // val +const val i2 = 1 // val val i3 = i1 // val with var in initializer -val i4 = i2 // val with val in initializer +const val i4 = i2 // val with val in initializer var i5 = i1 // var with var in initializer var i6 = i2 // var with val in initializer diff --git a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.txt b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.txt index a553e000e4d..0b2ed7a8122 100644 --- a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.txt +++ b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/kotlinProperties.txt @@ -1,9 +1,9 @@ package public var i1: kotlin.Int -public val i2: kotlin.Int = 1 +public const val i2: kotlin.Int = 1 public val i3: kotlin.Int -public val i4: kotlin.Int = 1 +public const val i4: kotlin.Int = 1 public var i5: kotlin.Int public var i6: kotlin.Int diff --git a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.kt b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.kt index 630a3bbdd54..f9e3e0161eb 100644 --- a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.kt +++ b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE annotation class Ann(vararg val i: String) -val topLevel = "topLevel" +const val topLevel = "topLevel" fun foo() { val a1 = "a" diff --git a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.txt b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.txt index 95e89c559a9..cf2e202495c 100644 --- a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.txt +++ b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/strings.txt @@ -1,6 +1,6 @@ package -public val topLevel: kotlin.String = "topLevel" +public const val topLevel: kotlin.String = "topLevel" public fun foo(): kotlin.Unit @kotlin.annotation.annotation() public final class Ann : kotlin.Annotation { diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt b/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt index 63f0e9dbc16..ce39b853d92 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt @@ -2,7 +2,7 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER annotation class ann(val name: String) -val ok = "OK" +const val ok = "OK" class A diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt b/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt index 8c80dfb53ba..dd583e68284 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt @@ -2,7 +2,7 @@ package public val extensionWithoutName: A.() -> kotlin.Unit public val funfun: () -> () -> kotlin.Int -public val ok: kotlin.String = "OK" +public const val ok: kotlin.String = "OK" public val parentesized: () -> kotlin.Unit public val parentesizedWithType: () -> kotlin.Unit public val withExpression: () -> kotlin.Int diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt index 84fc142e41e..7a56a7076ba 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt @@ -10,7 +10,7 @@ annotation class Ann(val i: IntArray) class Test var i = 1 -val i2 = 1 +const val i2 = 1 val i3 = foo() fun foo(): Int = 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.txt index 533aa7954b1..3527139b05d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.txt @@ -1,7 +1,7 @@ package public var i: kotlin.Int -public val i2: kotlin.Int = 1 +public const val i2: kotlin.Int = 1 public val i3: kotlin.Int public val iAnn: Ann public fun foo(): kotlin.Int diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.kt new file mode 100644 index 00000000000..d09b0f4cb55 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.kt @@ -0,0 +1,16 @@ +val nonConst = 1 + +const val constConst = nonConst * nonConst + 2 + +annotation class Ann(val x: Int, val y: String) + +@Ann(nonConst, "${nonConst}") +fun foo1() {} + +@Ann(nonConst + constConst, "${constConst}") +fun foo2() {} + +annotation class ArrayAnn(val x: IntArray) + +@ArrayAnn(intArrayOf(1, constConst, nonConst)) +fun foo3() {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.txt new file mode 100644 index 00000000000..82ee8aadf45 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.txt @@ -0,0 +1,24 @@ +package + +public const val constConst: kotlin.Int = 3 +public val nonConst: kotlin.Int = 1 +@Ann(x = 1, y = "1") public fun foo1(): kotlin.Unit +@Ann(x = 4, y = "3") public fun foo2(): kotlin.Unit +@ArrayAnn(x = {1, 3, 1}) public fun foo3(): kotlin.Unit + +@kotlin.annotation.annotation() public final class Ann : kotlin.Annotation { + public constructor Ann(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String) + public final val x: kotlin.Int + public final val y: kotlin.String + 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 +} + +@kotlin.annotation.annotation() public final class ArrayAnn : kotlin.Annotation { + public constructor ArrayAnn(/*0*/ x: kotlin.IntArray) + public final val x: kotlin.IntArray + 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/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt index 7113b4810e2..498aa046ccb 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt @@ -13,7 +13,7 @@ annotation class Ann(vararg val i: Int) class Test var i = 1 -val i2 = 1 +const val i2 = 1 val i3 = foo() fun foo(): Int = 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.txt index b04283b3190..7289cae4321 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.txt @@ -1,7 +1,7 @@ package public var i: kotlin.Int -public val i2: kotlin.Int = 1 +public const val i2: kotlin.Int = 1 public val i3: kotlin.Int public val iAnn: Ann public fun foo(): kotlin.Int diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 998baaafe9b..a47a8ecda91 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -162,6 +162,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } + @TestMetadata("useOfNonConstVal.kt") + public void testUseOfNonConstVal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/useOfNonConstVal.kt"); + doTest(fileName); + } + @TestMetadata("vararg.kt") public void testVararg() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt index 7413ae0eb5d..eef3728ddda 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt @@ -34,12 +34,15 @@ public interface CompileTimeConstant { public val usesVariableAsConstant: Boolean get() = parameters.usesVariableAsConstant + public val usesNonConstValAsConstant: Boolean get() = parameters.usesNonConstValAsConstant + public val isPure: Boolean get() = parameters.isPure public class Parameters( public val canBeUsedInAnnotation: Boolean, public val isPure: Boolean, - public val usesVariableAsConstant: Boolean + public val usesVariableAsConstant: Boolean, + public val usesNonConstValAsConstant: Boolean ) } diff --git a/idea/testData/checker/AnnotationOnFile.kt b/idea/testData/checker/AnnotationOnFile.kt index 7f2a7be0e1f..30efb2cdcbd 100644 --- a/idea/testData/checker/AnnotationOnFile.kt +++ b/idea/testData/checker/AnnotationOnFile.kt @@ -16,8 +16,8 @@ package boo -val BAZ = "baz" -val N = 0 +const val BAZ = "baz" +const val N = 0 @Target(AnnotationTarget.FILE) @Retention(AnnotationRetention.SOURCE)