0f4173cdfa
Add `@SharedImmutable` or `@ThreadLocal` where required.
215 lines
6.1 KiB
Kotlin
215 lines
6.1 KiB
Kotlin
/*
|
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
*/
|
|
|
|
package test.properties.delegation.references
|
|
|
|
import kotlin.reflect.*
|
|
import kotlin.test.*
|
|
import kotlin.internal.*
|
|
import kotlin.native.concurrent.ThreadLocal
|
|
import kotlin.random.*
|
|
|
|
open class Data(val stringVal: String, var intVar: Int, var builderVar: StringBuilder = StringBuilder("default"))
|
|
val Data.formattedVal: String get() = "Hello $stringVal"
|
|
var Data.displacedVar: Int
|
|
get() = intVar + 2
|
|
set(value) { intVar = value - 2 }
|
|
|
|
@ThreadLocal
|
|
val data = Data("bound string", 42)
|
|
|
|
val topVal: Double get() = 3.14
|
|
@ThreadLocal
|
|
var topVar: ULong = 0xFFFFUL
|
|
|
|
// top-level properties
|
|
|
|
// val to bound val
|
|
@ThreadLocal
|
|
val tlValBoundVal by data::stringVal
|
|
// val to bound var
|
|
@ThreadLocal
|
|
val tlValBoundVar by data::intVar
|
|
// var to bound var
|
|
@ThreadLocal
|
|
var tlVarBoundVar by data::intVar
|
|
|
|
// val to top-level val
|
|
@ThreadLocal
|
|
val tlValTopLevelVal by ::topVal
|
|
// val to top-level var
|
|
@ThreadLocal
|
|
val tlValTopLevelVar by ::topVar
|
|
// var to top-level var
|
|
@ThreadLocal
|
|
var tlVarTopLevelVar by ::topVar
|
|
|
|
// member properties
|
|
class DataExt : Data("member string", -1) {
|
|
|
|
// val to top-level val
|
|
val valTopLevelVal by ::topVal
|
|
|
|
// val to top-level var
|
|
val valTopLevelVar by ::topVar
|
|
|
|
// var to top-level var
|
|
var varTopLevelVar by ::topVar
|
|
|
|
|
|
// val to bound val
|
|
val valBoundVal by this::stringVal
|
|
|
|
// val to bound var
|
|
val valBoundVar by data::intVar
|
|
|
|
// var to bound var
|
|
var varBoundVar by ::intVar
|
|
|
|
|
|
// val to extension val
|
|
val valExtVal by Data::formattedVal
|
|
|
|
// val to extension var
|
|
val valExtVar by Data::displacedVar
|
|
|
|
// var to extension var
|
|
var varExtVar by Data::displacedVar
|
|
}
|
|
|
|
|
|
// extension properties
|
|
// val to bound val
|
|
@ThreadLocal
|
|
val Data.extValBoundVal by data::stringVal
|
|
// val to bound var
|
|
@ThreadLocal
|
|
val Data.extValBoundVar by data::intVar
|
|
// var to bound var
|
|
@ThreadLocal
|
|
var Data.extVarBoundVar by data::intVar
|
|
|
|
// val to top-level val
|
|
@ThreadLocal
|
|
val Data.extValTopLevelVal by ::topVal
|
|
// val to top-level var
|
|
@ThreadLocal
|
|
val Data.extValTopLevelVar by ::topVar
|
|
// var to top-level var
|
|
@ThreadLocal
|
|
var Data.extVarTopLevelVar by ::topVar
|
|
|
|
// val to member val
|
|
@ThreadLocal
|
|
val Data.extValMemberVal by Data::stringVal
|
|
// val to member var
|
|
@ThreadLocal
|
|
val Data.extValMemberVar by Data::intVar
|
|
// var to member var
|
|
@ThreadLocal
|
|
var Data.extVarMemberVar by Data::intVar
|
|
|
|
// val to extension val
|
|
@ThreadLocal
|
|
val Data.extValExtVal by Data::formattedVal
|
|
// val to extension var
|
|
@ThreadLocal
|
|
val Data.extValExtVar by Data::displacedVar
|
|
// var to extension var
|
|
@ThreadLocal
|
|
var Data.extVarExtVar by Data::displacedVar
|
|
|
|
|
|
// covariance
|
|
@ThreadLocal
|
|
val covariantVal: Number by ::topVal
|
|
@ThreadLocal
|
|
val Data.extCovariantVal: CharSequence by Data::builderVar
|
|
|
|
|
|
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
|
class PropertyReferenceTest {
|
|
|
|
private fun <V> checkDelegate0(delegated: KProperty0<@NoInfer V>, source: KProperty0<V>) {
|
|
assertEquals(delegated.get(), source.get())
|
|
}
|
|
|
|
private fun <V> checkDelegate1(delegated: KProperty0<@NoInfer V>, source: KMutableProperty0<V>, newValue: @NoInfer V) {
|
|
assertEquals(delegated.get(), source.get())
|
|
source.set(newValue)
|
|
assertEquals(newValue, source.get())
|
|
assertEquals(newValue, delegated.get())
|
|
}
|
|
|
|
private fun <V> checkDelegate2(delegated: KMutableProperty0<@NoInfer V>, source: KMutableProperty0<V>, newValue1: @NoInfer V, newValue2: @NoInfer V) {
|
|
assertEquals(delegated.get(), source.get())
|
|
source.set(newValue1)
|
|
assertEquals(newValue1, source.get())
|
|
assertEquals(newValue1, delegated.get())
|
|
|
|
delegated.set(newValue2)
|
|
assertEquals(newValue2, source.get())
|
|
assertEquals(newValue2, delegated.get())
|
|
}
|
|
|
|
private fun int(): Int = Random.nextInt()
|
|
private fun ulong(): ULong = Random.nextULong()
|
|
|
|
|
|
@Test
|
|
fun topLevelProperties() {
|
|
checkDelegate0(::tlValBoundVal, data::stringVal)
|
|
checkDelegate1(::tlValBoundVar, data::intVar, int())
|
|
checkDelegate2(::tlVarBoundVar, data::intVar, int(), int())
|
|
|
|
checkDelegate0(::tlValTopLevelVal, ::topVal)
|
|
checkDelegate1(::tlValTopLevelVar, ::topVar, ulong())
|
|
checkDelegate2(::tlVarTopLevelVar, ::topVar, ulong(), ulong())
|
|
}
|
|
|
|
@Test
|
|
fun memberProperties() {
|
|
val local = DataExt()
|
|
checkDelegate0(local::valBoundVal, local::stringVal)
|
|
checkDelegate1(local::valBoundVar, data::intVar, int())
|
|
checkDelegate2(local::varBoundVar, local::intVar, int(), int())
|
|
|
|
checkDelegate0(local::valTopLevelVal, ::topVal)
|
|
checkDelegate1(local::valTopLevelVar, ::topVar, ulong())
|
|
checkDelegate2(local::varTopLevelVar, ::topVar, ulong(), ulong())
|
|
|
|
checkDelegate0(local::valExtVal, local::formattedVal)
|
|
checkDelegate1(local::valExtVar, local::displacedVar, int())
|
|
checkDelegate2(local::varExtVar, local::displacedVar, int(), int())
|
|
}
|
|
|
|
@Test
|
|
fun extensionProperties() {
|
|
val local = Data("ext", Int.MAX_VALUE)
|
|
|
|
checkDelegate0(local::extValBoundVal, data::stringVal)
|
|
checkDelegate1(local::extValBoundVar, data::intVar, int())
|
|
checkDelegate2(local::extVarBoundVar, data::intVar, int(), int())
|
|
|
|
checkDelegate0(local::extValMemberVal, local::stringVal)
|
|
checkDelegate1(local::extValMemberVar, local::intVar, int())
|
|
checkDelegate2(local::extVarMemberVar, local::intVar, int(), int())
|
|
|
|
checkDelegate0(local::extValTopLevelVal, ::topVal)
|
|
checkDelegate1(local::extValTopLevelVar, ::topVar, ulong())
|
|
checkDelegate2(local::extVarTopLevelVar, ::topVar, ulong(), ulong())
|
|
|
|
checkDelegate0(local::extValExtVal, local::formattedVal)
|
|
checkDelegate1(local::extValExtVar, local::displacedVar, int())
|
|
checkDelegate2(local::extVarExtVar, local::displacedVar, int(), int())
|
|
}
|
|
|
|
@Test
|
|
fun covariantProperties() {
|
|
checkDelegate0<Number>(::covariantVal, ::topVal)
|
|
checkDelegate0<CharSequence>(data::extCovariantVal, data::builderVar)
|
|
}
|
|
|
|
} |