diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 8aa2ca6e52b..d965d5cf3b5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -133,6 +133,14 @@ public interface Errors { DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_ENUM_CONST = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT = DiagnosticFactory0.create(ERROR); + // Const + DiagnosticFactory0 CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 CONST_VAL_WITH_GETTER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 CONST_VAL_WITH_DELEGATE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory1 TYPE_CANT_BE_USED_FOR_CONST_VAL = DiagnosticFactory1.create(ERROR); + DiagnosticFactory0 CONST_VAL_WITHOUT_INITIALIZER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 CONST_VAL_WITH_NON_CONST_INITIALIZER = DiagnosticFactory0.create(ERROR); + 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 1cceb09ed64..70273938bd8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -596,6 +596,13 @@ public class DefaultErrorMessages { MAP.put(ANNOTATION_PARAMETER_MUST_BE_KCLASS_LITERAL, "An annotation parameter must be a class literal (T::class)"); MAP.put(ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT, "Default value of annotation parameter must be a compile-time constant"); + MAP.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level or in objects"); + MAP.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate"); + MAP.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter"); + 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(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/ConstModifierChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ConstModifierChecker.kt new file mode 100644 index 00000000000..2d269bc607d --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ConstModifierChecker.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.lexer.JetTokens +import org.jetbrains.kotlin.psi.* + +public object ConstModifierChecker : DeclarationChecker { + override fun check( + declaration: JetDeclaration, + descriptor: DeclarationDescriptor, + diagnosticHolder: DiagnosticSink, + bindingContext: BindingContext + ) { + if (descriptor !is VariableDescriptor || !declaration.hasModifier(JetTokens.CONST_KEYWORD)) return + + val containingDeclaration = descriptor.containingDeclaration + val constModifierPsiElement = declaration.modifierList!!.getModifier(JetTokens.CONST_KEYWORD)!! + + if (descriptor.isVar) { + diagnosticHolder.report(Errors.WRONG_MODIFIER_TARGET.on(constModifierPsiElement, JetTokens.CONST_KEYWORD, "vars")) + return + } + + if (containingDeclaration is ClassDescriptor && containingDeclaration.kind != ClassKind.OBJECT) { + diagnosticHolder.report(Errors.CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT.on(constModifierPsiElement)) + return + } + + if (declaration !is JetProperty || descriptor !is PropertyDescriptor) return + + if (declaration.hasDelegate()) { + diagnosticHolder.report(Errors.CONST_VAL_WITH_DELEGATE.on(declaration.delegate!!)) + return + } + + if (descriptor is PropertyDescriptor && !descriptor.getter!!.isDefault) { + diagnosticHolder.report(Errors.CONST_VAL_WITH_GETTER.on(declaration.getter!!)) + return + } + + if (!descriptor.type.canBeUsedForConstVal()) { + diagnosticHolder.report(Errors.TYPE_CANT_BE_USED_FOR_CONST_VAL.on(constModifierPsiElement, descriptor.type)) + return + } + + if (declaration.initializer == null) { + diagnosticHolder.report(Errors.CONST_VAL_WITHOUT_INITIALIZER.on(constModifierPsiElement)) + return + } + + if (descriptor.compileTimeInitializer == null) { + diagnosticHolder.report(Errors.CONST_VAL_WITH_NON_CONST_INITIALIZER.on(declaration.initializer!!)) + return + } + } +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt index 207014a5b3f..8dd4efd734e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt @@ -64,7 +64,8 @@ public object ModifierCheckerCore { TAILREC_KEYWORD to EnumSet.of(FUNCTION), EXTERNAL_KEYWORD to EnumSet.of(FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER), ANNOTATION_KEYWORD to EnumSet.of(ANNOTATION_CLASS), - CROSSINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER) + CROSSINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER), + CONST_KEYWORD to EnumSet.of(MEMBER_PROPERTY, TOP_LEVEL_PROPERTY) ) // NOTE: redundant targets must be possible! @@ -87,16 +88,21 @@ public object ModifierCheckerCore { private fun buildCompatibilityMap(): Map, Compatibility> { val result = hashMapOf, Compatibility>() // Variance: in + out are incompatible - result += incompatibilityRegister(listOf(IN_KEYWORD, OUT_KEYWORD)) + result += incompatibilityRegister(IN_KEYWORD, OUT_KEYWORD) // Visibilities: incompatible - result += incompatibilityRegister(listOf(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD)) + result += incompatibilityRegister(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD) // Abstract + open + final + sealed: incompatible - result += incompatibilityRegister(listOf(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, SEALED_KEYWORD)) + result += incompatibilityRegister(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, SEALED_KEYWORD) // open is redundant to abstract & override result += redundantRegister(ABSTRACT_KEYWORD, OPEN_KEYWORD) result += redundantRegister(OVERRIDE_KEYWORD, OPEN_KEYWORD) // abstract is redundant to sealed result += redundantRegister(SEALED_KEYWORD, ABSTRACT_KEYWORD) + + // const is incompatible with abstract, open, override + result += incompatibilityRegister(CONST_KEYWORD, ABSTRACT_KEYWORD) + result += incompatibilityRegister(CONST_KEYWORD, OPEN_KEYWORD) + result += incompatibilityRegister(CONST_KEYWORD, OVERRIDE_KEYWORD) return result } @@ -109,7 +115,7 @@ public object ModifierCheckerCore { } private fun incompatibilityRegister( - list: List + vararg list: JetModifierKeywordToken ): Map, Compatibility> { val result = hashMapOf, Compatibility>() for (first in list) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt index 91f29b65675..2d7d5c7af40 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt @@ -38,7 +38,7 @@ public abstract class TargetPlatform( } } -private val DEFAULT_DECLARATION_CHECKERS = listOf(DataClassAnnotationChecker()) +private val DEFAULT_DECLARATION_CHECKERS = listOf(DataClassAnnotationChecker(), ConstModifierChecker) private val DEFAULT_CALL_CHECKERS = listOf(CapturingInClosureChecker(), InlineCheckerWrapper(), ReifiedTypeParameterSubstitutionChecker()) private val DEFAULT_TYPE_CHECKERS = emptyList() private val DEFAULT_VALIDATORS = listOf(DeprecatedSymbolValidator(), AccessToPrivateTopLevelSymbolValidator()) 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 0961f190faf..4440303451c 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 @@ -529,8 +529,7 @@ private class ConstantExpressionEvaluatorVisitor( } if (DescriptorUtils.isObject(descriptor.getContainingDeclaration()) || DescriptorUtils.isStaticDeclaration(descriptor)) { - val returnType = descriptor.getType() - return KotlinBuiltIns.isPrimitiveType(returnType) || KotlinBuiltIns.isString(returnType) + return descriptor.type.canBeUsedForConstVal() } return false } diff --git a/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt b/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt index 5f9b15c82c2..49c3d625e2a 100644 --- a/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt +++ b/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt @@ -36,6 +36,7 @@ class IllegalModifiers1( reified enum private + const a: Int) //Check multiple illegal modifiers in constructor @@ -110,6 +111,7 @@ class IllegalModifiers7() { in vararg reified + const fun foo() {} } @@ -126,6 +128,7 @@ class IllegalModifiers8 { final vararg reified + const constructor() {} constructor(private enum abstract x: Int) {} @@ -149,6 +152,7 @@ class IllegalModifiers10 in final vararg -reified constructor() +reified +const constructor() class IllegalModifiers11 private protected constructor() diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt new file mode 100644 index 00000000000..0a8d9a08759 --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt @@ -0,0 +1,75 @@ +// !DIAGNOSTICS:-UNUSED_VARIABLE + +const val topLevel: Int = 0 +const val topLevelInferred = 1 +const var topLeveLVar: Int = 2 + +private val privateTopLevel = 3 + +object A { + const val inObject: Int = 4 +} + +class B(const val constructor: Int = 5) + +abstract class C { + open const val x: Int = 6 + + abstract const val y: Int = 7 + + companion object { + const val inCompaionObject = 8 + } +} + +object D : C() { + override const val x: Int = 9 + + const val inObject = 10 + + final const val final = 11 + + const val withoutInitializer: Int + + init { + withoutInitializer = 12 + } +} + +const val delegated: Int by Delegate() + + +const val withGetter: Int +get() = 13 + +fun foo(): Int { + const val local: Int = 14 + return 15 +} + +enum class MyEnum { + A { + const val inEnumEntry = 16 + }; + const val inEnum = 17 +} + +class Outer { + inner class Inner { + object C { + const val a = 18 + } + } +} + +const val defaultGetter = 19 + get + +const val nonConstInitializer = foo() + +// ------------------ +class Delegate { + fun get(thisRef: Any?, prop: PropertyMetadata): Int = 1 + + fun set(thisRef: Any?, prop: PropertyMetadata, value: Int) = Unit +} diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt new file mode 100644 index 00000000000..81fe9e2c6c7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt @@ -0,0 +1,105 @@ +package + +public const val defaultGetter: kotlin.Int = 19 +public const val delegated: kotlin.Int +public const val nonConstInitializer: kotlin.Int +private val privateTopLevel: kotlin.Int = 3 +public const var topLeveLVar: kotlin.Int +public const val topLevel: kotlin.Int = 0 +public const val topLevelInferred: kotlin.Int = 1 +public const val withGetter: kotlin.Int +public fun foo(): kotlin.Int + +public object A { + private constructor A() + public const final val inObject: kotlin.Int = 4 + 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 class B { + public constructor B(/*0*/ constructor: kotlin.Int = ...) + public final val constructor: 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 abstract class C { + public constructor C() + public const open val x: kotlin.Int = 6 + public const abstract val y: kotlin.Int = 7 + 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 companion object Companion { + private constructor Companion() + public const final val inCompaionObject: kotlin.Int = 8 + 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 object D : C { + private constructor D() + public const final val final: kotlin.Int = 11 + public const final val inObject: kotlin.Int = 10 + public const final val withoutInitializer: kotlin.Int + public const open override /*1*/ val x: kotlin.Int = 9 + public const abstract override /*1*/ /*fake_override*/ val y: 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 class Delegate { + public constructor Delegate() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun get(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.PropertyMetadata): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun set(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.PropertyMetadata, /*2*/ value: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final enum class MyEnum : kotlin.Enum { + enum entry A + + private constructor MyEnum() + public const final val inEnum: kotlin.Int = 17 + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final class Outer { + public constructor Outer() + 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 inner class Inner { + public constructor Inner() + 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 object C { + private constructor C() + public const final val a: kotlin.Int = 18 + 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/tests/modifiers/const/constInteraction.kt b/compiler/testData/diagnostics/tests/modifiers/const/constInteraction.kt new file mode 100644 index 00000000000..df6b2eda199 --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/constInteraction.kt @@ -0,0 +1,18 @@ +const val aConst = 1 +const val bConst = aConst + 1 + +const val boolVal = bConst > 1 || (B.boolVal && A.boolVal) +const val stringInterpolation = "Result: ${B.boolVal}" + +object A { + const val boolVal = bConst + 3 == 5 + + const val recursive1: Int = 1 + B.recursive2 +} + +class B { + companion object { + const val boolVal = A.boolVal + const val recursive2: Int = A.recursive1 + 2 + } +} diff --git a/compiler/testData/diagnostics/tests/modifiers/const/constInteraction.txt b/compiler/testData/diagnostics/tests/modifiers/const/constInteraction.txt new file mode 100644 index 00000000000..edecf098796 --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/constInteraction.txt @@ -0,0 +1,31 @@ +package + +public const val aConst: kotlin.Int = 1 +public const val bConst: kotlin.Int = 2 +public const val boolVal: kotlin.Boolean = true +public const val stringInterpolation: kotlin.String = "Result: true" + +public object A { + private constructor A() + public const final val boolVal: kotlin.Boolean = true + public const final val recursive1: 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 class B { + public constructor B() + 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 companion object Companion { + private constructor Companion() + public const final val boolVal: kotlin.Boolean = true + public const final val recursive2: 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 + } +} diff --git a/compiler/testData/diagnostics/tests/modifiers/const/types.kt b/compiler/testData/diagnostics/tests/modifiers/const/types.kt new file mode 100644 index 00000000000..aa49bfdf35e --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/types.kt @@ -0,0 +1,16 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +const val intConst = 1 +const val longConst: Long = 1 +const val boolConst = true +const val stringConst = "empty" + +enum class MyEnum { A } + +const val enumConst: MyEnum = MyEnum.A +const val arrayConst: Array = arrayOf("1") +const val intArrayConst: IntArray = intArrayOf() + +// ------------------------------------------------ +fun arrayOf(vararg x: T): Array = null!! +fun intArrayOf(): IntArray = null!! \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/modifiers/const/types.txt b/compiler/testData/diagnostics/tests/modifiers/const/types.txt new file mode 100644 index 00000000000..4440eff41fa --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/types.txt @@ -0,0 +1,28 @@ +package + +public const val arrayConst: kotlin.Array +public const val boolConst: kotlin.Boolean = true +public const val enumConst: MyEnum +public const val intArrayConst: kotlin.IntArray +public const val intConst: kotlin.Int = 1 +public const val longConst: kotlin.Long = 1.toLong() +public const val stringConst: kotlin.String = "empty" +public fun arrayOf(/*0*/ vararg x: T /*kotlin.Array*/): kotlin.Array +public fun intArrayOf(): kotlin.IntArray + +public final enum class MyEnum : kotlin.Enum { + enum entry A + + private constructor MyEnum() + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 4a419d9c560..06ed4ed2734 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9107,6 +9107,33 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.kt"); doTest(fileName); } + + @TestMetadata("compiler/testData/diagnostics/tests/modifiers/const") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Const extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInConst() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/modifiers/const"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("applicability.kt") + public void testApplicability() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/const/applicability.kt"); + doTest(fileName); + } + + @TestMetadata("constInteraction.kt") + public void testConstInteraction() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/const/constInteraction.kt"); + doTest(fileName); + } + + @TestMetadata("types.kt") + public void testTypes() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/const/types.kt"); + doTest(fileName); + } + } } @TestMetadata("compiler/testData/diagnostics/tests/multimodule") diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ConstUtil.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ConstUtil.kt new file mode 100644 index 00000000000..72ae109fa4c --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ConstUtil.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:JvmName("ConstUtil") + +package org.jetbrains.kotlin.descriptors + +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.types.JetType + +public fun JetType.canBeUsedForConstVal() = KotlinBuiltIns.isPrimitiveType(this) || KotlinBuiltIns.isString(this) +