Add checks for const modifier applicability

1. Must be initialized in-place
2. Can not be open/abstract
3. Can not be an override
4. Can not be delegated
5. Initializer must be a compile-time constant
6. No getters
7. `const` is not applicable to vars or locals
8. `const val` should be whether top-level property or object member
This commit is contained in:
Denis Zharkov
2015-09-21 16:17:42 +03:00
parent bde58d6eb8
commit b2b76d16d0
15 changed files with 432 additions and 9 deletions
@@ -36,6 +36,7 @@ class IllegalModifiers1(
<!WRONG_MODIFIER_TARGET!>reified<!>
<!WRONG_MODIFIER_TARGET!>enum<!>
<!WRONG_MODIFIER_TARGET!>private<!>
<!WRONG_MODIFIER_TARGET!>const<!>
<!UNUSED_PARAMETER!>a<!>: Int)
//Check multiple illegal modifiers in constructor
@@ -110,6 +111,7 @@ class IllegalModifiers7() {
<!INCOMPATIBLE_MODIFIERS!>in<!>
<!WRONG_MODIFIER_TARGET!>vararg<!>
<!WRONG_MODIFIER_TARGET!>reified<!>
<!WRONG_MODIFIER_TARGET!>const<!>
fun foo() {}
}
@@ -126,6 +128,7 @@ class IllegalModifiers8 {
<!INCOMPATIBLE_MODIFIERS!>final<!>
<!WRONG_MODIFIER_TARGET!>vararg<!>
<!WRONG_MODIFIER_TARGET!>reified<!>
<!INCOMPATIBLE_MODIFIERS!>const<!>
constructor() {}
constructor(<!WRONG_MODIFIER_TARGET!>private<!> <!WRONG_MODIFIER_TARGET!>enum<!> <!WRONG_MODIFIER_TARGET!>abstract<!> <!UNUSED_PARAMETER!>x<!>: Int) {}
@@ -149,6 +152,7 @@ class IllegalModifiers10
<!INCOMPATIBLE_MODIFIERS!>in<!>
<!INCOMPATIBLE_MODIFIERS!>final<!>
<!WRONG_MODIFIER_TARGET!>vararg<!>
<!WRONG_MODIFIER_TARGET!>reified<!> constructor()
<!WRONG_MODIFIER_TARGET!>reified<!>
<!INCOMPATIBLE_MODIFIERS!>const<!> constructor()
class IllegalModifiers11 <!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>protected<!> constructor()
@@ -0,0 +1,75 @@
// !DIAGNOSTICS:-UNUSED_VARIABLE
const val topLevel: Int = 0
const val topLevelInferred = 1
<!WRONG_MODIFIER_TARGET!>const<!> var topLeveLVar: Int = 2
private val privateTopLevel = 3
object A {
const val inObject: Int = 4
}
class B(<!CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT!>const<!> val constructor: Int = 5)
abstract class C {
<!INCOMPATIBLE_MODIFIERS!>open<!> <!CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, INCOMPATIBLE_MODIFIERS!>const<!> val x: Int = 6
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, INCOMPATIBLE_MODIFIERS!>const<!> val y: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>7<!>
companion object {
const val inCompaionObject = 8
}
}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>object D<!> : C() {
<!INCOMPATIBLE_MODIFIERS!>override<!> <!INCOMPATIBLE_MODIFIERS!>const<!> val x: Int = 9
const val inObject = 10
final const val final = 11
<!CONST_VAL_WITHOUT_INITIALIZER!>const<!> val withoutInitializer: Int
init {
withoutInitializer = 12
}
}
const val delegated: Int <!CONST_VAL_WITH_DELEGATE!>by Delegate()<!>
const val withGetter: Int
<!CONST_VAL_WITH_GETTER!>get() = 13<!>
fun foo(): Int {
<!WRONG_MODIFIER_TARGET!>const<!> val local: Int = 14
return 15
}
enum class MyEnum {
A {
<!CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT!>const<!> val inEnumEntry = 16
};
<!CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT!>const<!> val inEnum = 17
}
class Outer {
inner class Inner {
object C {
const val a = 18
}
}
}
const val defaultGetter = 19
<!CONST_VAL_WITH_GETTER!>get<!>
const val nonConstInitializer = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>foo()<!>
// ------------------
class Delegate {
fun get(thisRef: Any?, prop: PropertyMetadata): Int = 1
fun set(thisRef: Any?, prop: PropertyMetadata, value: Int) = Unit
}
@@ -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<MyEnum> {
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<MyEnum>
}
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
}
}
}
@@ -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 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>1 + B.recursive2<!>
}
class B {
companion object {
const val boolVal = A.boolVal
const val recursive2: Int = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>A.recursive1 + 2<!>
}
}
@@ -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
}
}
@@ -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 }
<!TYPE_CANT_BE_USED_FOR_CONST_VAL!>const<!> val enumConst: MyEnum = MyEnum.A
<!TYPE_CANT_BE_USED_FOR_CONST_VAL!>const<!> val arrayConst: Array<String> = arrayOf("1")
<!TYPE_CANT_BE_USED_FOR_CONST_VAL!>const<!> val intArrayConst: IntArray = intArrayOf()
// ------------------------------------------------
fun <T> arrayOf(vararg x: T): Array<T> = null!!
fun intArrayOf(): IntArray = null!!
@@ -0,0 +1,28 @@
package
public const val arrayConst: kotlin.Array<kotlin.String>
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 </*0*/ T> arrayOf(/*0*/ vararg x: T /*kotlin.Array<out T>*/): kotlin.Array<T>
public fun intArrayOf(): kotlin.IntArray
public final enum class MyEnum : kotlin.Enum<MyEnum> {
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<MyEnum>
}