[atomicfu-JVM] Preparation for commonization of JVM and K/N transformers
The following updates in the JVM/IR plugin were made: * Lots of refactoring with preparation for K/N support: commonization of transformations. * Improved error handling (checks for visibility constraints, appending message about usage constraints in case of an error). * Explicit requirements for the visibility of atomic properties: to prevent leaking they should be private/internal or be members of private/internal classes. * Fixed visibility of generated properties: volatile properties are always private and atomic updaters have the same visibility as the original atomic property. * Volatile fields are generated from scratch and original atomic properties are removed. * Delegated properties support is fixed (only declaration in the same scope is allowed). * Non-inline atomic extensions are forbidden. * For top-level atomics: only one wrapper class per file (with corresponding visibility) is generated. * Bug fixes. The corresponding tickets: https://github.com/Kotlin/kotlinx-atomicfu/issues/322 KT-60528 Merge-request: KT-MR-10579 Merged-by: Maria Sokolova <maria.sokolova@jetbrains.com>
This commit is contained in:
+150
@@ -0,0 +1,150 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
private val _topLevelInt = atomic(42)
|
||||
var topLevelInt: Int by _topLevelInt
|
||||
|
||||
private var topLevelVolatile by atomic(56)
|
||||
|
||||
class DelegatedProperties {
|
||||
// Delegated properties should be declared in the same scope as the original atomic values
|
||||
private val _a = atomic(42)
|
||||
var a: Int by _a
|
||||
private var privateA: Int by _a
|
||||
|
||||
private val _l = atomic(55555555555)
|
||||
private var l: Long by _l
|
||||
|
||||
private val _b = atomic(false)
|
||||
private var b: Boolean by _b
|
||||
|
||||
private val _ref = atomic(A(B(77)))
|
||||
private var ref: A by _ref
|
||||
|
||||
private var vInt by atomic(77)
|
||||
|
||||
private var vLong by atomic(777777777)
|
||||
|
||||
private var vBoolean by atomic(false)
|
||||
|
||||
private var vRef by atomic(A(B(77)))
|
||||
|
||||
class A (val b: B)
|
||||
class B (val n: Int)
|
||||
|
||||
fun testDelegatedAtomicInt() {
|
||||
assertEquals(42, a)
|
||||
assertEquals(42, privateA)
|
||||
_a.compareAndSet(42, 56)
|
||||
assertEquals(56, a)
|
||||
assertEquals(56, privateA)
|
||||
a = 77
|
||||
_a.compareAndSet(77, 66)
|
||||
privateA = 88
|
||||
_a.compareAndSet(88, 66)
|
||||
assertEquals(66, _a.value)
|
||||
assertEquals(66, a)
|
||||
assertEquals(66, privateA)
|
||||
|
||||
val aValue = a + privateA
|
||||
assertEquals(132, aValue)
|
||||
}
|
||||
|
||||
fun testDelegatedAtomicLong() {
|
||||
assertEquals(55555555555, l)
|
||||
_l.getAndIncrement()
|
||||
assertEquals(55555555556, l)
|
||||
l = 7777777777777
|
||||
assertTrue(_l.compareAndSet(7777777777777, 66666666666))
|
||||
assertEquals(66666666666, _l.value)
|
||||
assertEquals(66666666666, l)
|
||||
}
|
||||
|
||||
fun testDelegatedAtomicBoolean() {
|
||||
assertEquals(false, b)
|
||||
_b.lazySet(true)
|
||||
assertEquals(true, b)
|
||||
b = false
|
||||
assertTrue(_b.compareAndSet(false, true))
|
||||
assertEquals(true, _b.value)
|
||||
assertEquals(true, b)
|
||||
}
|
||||
|
||||
fun testDelegatedAtomicRef() {
|
||||
assertEquals(77, ref.b.n)
|
||||
_ref.lazySet(A(B(66)))
|
||||
assertEquals(66, ref.b.n)
|
||||
assertTrue(_ref.compareAndSet(_ref.value, A(B(56))))
|
||||
assertEquals(56, ref.b.n)
|
||||
ref = A(B(99))
|
||||
assertEquals(99, _ref.value.b.n)
|
||||
}
|
||||
|
||||
fun testVolatileInt() {
|
||||
assertEquals(77, vInt)
|
||||
vInt = 55
|
||||
assertEquals(110, vInt * 2)
|
||||
}
|
||||
|
||||
fun testVolatileLong() {
|
||||
assertEquals(777777777, vLong)
|
||||
vLong = 55
|
||||
assertEquals(55, vLong)
|
||||
}
|
||||
|
||||
fun testVolatileBoolean() {
|
||||
assertEquals(false, vBoolean)
|
||||
vBoolean = true
|
||||
assertEquals(true, vBoolean)
|
||||
}
|
||||
|
||||
fun testVolatileRef() {
|
||||
assertEquals(77, vRef.b.n)
|
||||
vRef = A(B(99))
|
||||
assertEquals(99, vRef.b.n)
|
||||
}
|
||||
|
||||
fun testDelegatedVariablesFlow() {
|
||||
_a.lazySet(55)
|
||||
assertEquals(55, _a.value)
|
||||
assertEquals(55, a)
|
||||
var aValue = a
|
||||
assertEquals(55, aValue)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
testDelegatedAtomicInt()
|
||||
testDelegatedAtomicLong()
|
||||
testDelegatedAtomicBoolean()
|
||||
testDelegatedAtomicRef()
|
||||
testVolatileInt()
|
||||
testVolatileBoolean()
|
||||
testVolatileLong()
|
||||
testVolatileRef()
|
||||
testDelegatedVariablesFlow()
|
||||
}
|
||||
}
|
||||
|
||||
fun testTopLevelDelegatedProperties() {
|
||||
assertEquals(42, topLevelInt)
|
||||
_topLevelInt.compareAndSet(42, 56)
|
||||
assertEquals(56, topLevelInt)
|
||||
topLevelInt = 77
|
||||
_topLevelInt.compareAndSet(77, 66)
|
||||
assertEquals(66, _topLevelInt.value)
|
||||
assertEquals(66, topLevelInt)
|
||||
}
|
||||
|
||||
fun testTopLevelVolatileProperties() {
|
||||
assertEquals(56, topLevelVolatile)
|
||||
topLevelVolatile = 55
|
||||
assertEquals(110, topLevelVolatile * 2)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testClass = DelegatedProperties()
|
||||
testClass.test()
|
||||
testTopLevelDelegatedProperties()
|
||||
testTopLevelVolatileProperties()
|
||||
return "OK"
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
@kotlin.Metadata
|
||||
public final class DelegatedProperties$A {
|
||||
// source: 'DelegatedPropertiesTest.kt'
|
||||
private final @org.jetbrains.annotations.NotNull field b: DelegatedProperties$B
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: DelegatedProperties$B): void
|
||||
public final @org.jetbrains.annotations.NotNull method getB(): DelegatedProperties$B
|
||||
public final inner class DelegatedProperties$A
|
||||
public final inner class DelegatedProperties$B
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class DelegatedProperties$B {
|
||||
// source: 'DelegatedPropertiesTest.kt'
|
||||
private final field n: int
|
||||
public method <init>(p0: int): void
|
||||
public final method getN(): int
|
||||
public final inner class DelegatedProperties$B
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class DelegatedProperties {
|
||||
// source: 'DelegatedPropertiesTest.kt'
|
||||
private synthetic final static field _a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field _a$volatile: int
|
||||
private synthetic final static field _b$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field _b$volatile: int
|
||||
private synthetic final static field _l$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater
|
||||
private synthetic volatile field _l$volatile: long
|
||||
private synthetic final static field _ref$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic volatile field _ref$volatile: java.lang.Object
|
||||
private synthetic volatile field vBoolean$volatile: boolean
|
||||
private synthetic volatile field vInt$volatile: int
|
||||
private synthetic volatile field vLong$volatile: int
|
||||
private synthetic volatile field vRef$volatile: java.lang.Object
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
public final method getA(): int
|
||||
private final method getB(): boolean
|
||||
private final method getL(): long
|
||||
private final method getPrivateA(): int
|
||||
private final method getRef(): DelegatedProperties$A
|
||||
private final method getVBoolean(): boolean
|
||||
private final method getVInt(): int
|
||||
private final method getVLong(): int
|
||||
private final method getVRef(): DelegatedProperties$A
|
||||
private synthetic final static method get_a$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method get_a$volatile(): int
|
||||
private synthetic final static method get_b$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method get_b$volatile(): int
|
||||
private synthetic final static method get_l$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater
|
||||
private synthetic final method get_l$volatile(): long
|
||||
private synthetic final static method get_ref$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater
|
||||
private synthetic final method get_ref$volatile(): java.lang.Object
|
||||
public final method setA(p0: int): void
|
||||
private final method setB(p0: boolean): void
|
||||
private final method setL(p0: long): void
|
||||
private final method setPrivateA(p0: int): void
|
||||
private final method setRef(p0: DelegatedProperties$A): void
|
||||
private final method setVBoolean(p0: boolean): void
|
||||
private final method setVInt(p0: int): void
|
||||
private final method setVLong(p0: int): void
|
||||
private final method setVRef(p0: DelegatedProperties$A): void
|
||||
private synthetic final method set_a$volatile(p0: int): void
|
||||
private synthetic final method set_b$volatile(p0: int): void
|
||||
private synthetic final method set_l$volatile(p0: long): void
|
||||
private synthetic final method set_ref$volatile(p0: java.lang.Object): void
|
||||
public final method test(): void
|
||||
public final method testDelegatedAtomicBoolean(): void
|
||||
public final method testDelegatedAtomicInt(): void
|
||||
public final method testDelegatedAtomicLong(): void
|
||||
public final method testDelegatedAtomicRef(): void
|
||||
public final method testDelegatedVariablesFlow(): void
|
||||
public final method testVolatileBoolean(): void
|
||||
public final method testVolatileInt(): void
|
||||
public final method testVolatileLong(): void
|
||||
public final method testVolatileRef(): void
|
||||
public final inner class DelegatedProperties$A
|
||||
public final inner class DelegatedProperties$B
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
synthetic final class DelegatedPropertiesTest$VolatileWrapper$atomicfu$private {
|
||||
// source: 'DelegatedPropertiesTest.kt'
|
||||
private synthetic final static field _topLevelInt$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic volatile field _topLevelInt$volatile: int
|
||||
static method <clinit>(): void
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic final static method access$get_topLevelInt$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
public synthetic final static method access$get_topLevelInt$volatile$p(p0: DelegatedPropertiesTest$VolatileWrapper$atomicfu$private): int
|
||||
public synthetic final static method access$set_topLevelInt$volatile$p(p0: DelegatedPropertiesTest$VolatileWrapper$atomicfu$private, p1: int): void
|
||||
private synthetic final static method get_topLevelInt$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
||||
private synthetic final method get_topLevelInt$volatile(): int
|
||||
private synthetic final method set_topLevelInt$volatile(p0: int): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class DelegatedPropertiesTestKt {
|
||||
// source: 'DelegatedPropertiesTest.kt'
|
||||
private synthetic final static field delegatedPropertiesTest$VolatileWrapper$atomicfu$private: DelegatedPropertiesTest$VolatileWrapper$atomicfu$private
|
||||
private synthetic volatile static field topLevelVolatile$volatile: int
|
||||
static method <clinit>(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
private synthetic final static method getDelegatedPropertiesTest$VolatileWrapper$atomicfu$private(): DelegatedPropertiesTest$VolatileWrapper$atomicfu$private
|
||||
public final static method getTopLevelInt(): int
|
||||
private final static method getTopLevelVolatile(): int
|
||||
public final static method setTopLevelInt(p0: int): void
|
||||
private final static method setTopLevelVolatile(p0: int): void
|
||||
public final static method testTopLevelDelegatedProperties(): void
|
||||
public final static method testTopLevelVolatileProperties(): void
|
||||
}
|
||||
Reference in New Issue
Block a user