WIP
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicIrBuilder.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicIrBuilder.kt new file mode 100644 index 0000000..1455d73 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicIrBuilder.kt
@@ -0,0 +1,20 @@ +/* + * Copyright 2010-2022 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 org.jetbrains.kotlinx.atomicfu.compiler.backend + +import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope +import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase +import org.jetbrains.kotlin.ir.builders.Scope +import org.jetbrains.kotlin.ir.symbols.IrSymbol + +open class AtomicIrBuilder( + atomicSymbols: AtomicSymbols, + symbol: IrSymbol, + startOffset: Int, + endOffset: Int +) : IrBuilderWithScope(IrGeneratorContextBase(atomicSymbols.irBuiltIns), Scope(symbol), startOffset, endOffset) { + +}
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicSymbols.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicSymbols.kt index 54393a8..f46edf3 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicSymbols.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/AtomicSymbols.kt
@@ -10,18 +10,15 @@ import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.declarations.* -import org.jetbrains.kotlin.ir.builders.irBlockBody -import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.* -import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm.AtomicfuIrBuilder +import org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm.AtomicfuJvmIrBuilder abstract class AtomicSymbols( val irBuiltIns: IrBuiltIns, @@ -83,4 +80,6 @@ parent = irPackage createImplicitParameterDeclarationWithWrappedDescriptor() }.symbol + + abstract fun createBuilder(symbol: IrSymbol, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET): AtomicIrBuilder }
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuIrBuilder.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuJvmIrBuilder.kt similarity index 98% rename from plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuIrBuilder.kt rename to plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuJvmIrBuilder.kt index b5d324b..3938d9e 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuIrBuilder.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuJvmIrBuilder.kt
@@ -11,14 +11,15 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlinx.atomicfu.compiler.backend.AtomicIrBuilder // An IR builder with access to AtomicSymbols and convenience methods to build IR constructions for atomicfu JVM/IR transformation. -class AtomicfuIrBuilder internal constructor( +class AtomicfuJvmIrBuilder internal constructor( val atomicSymbols: JvmAtomicSymbols, symbol: IrSymbol, startOffset: Int, endOffset: Int -) : IrBuilderWithScope(IrGeneratorContextBase(atomicSymbols.irBuiltIns), Scope(symbol), startOffset, endOffset) { +) : AtomicIrBuilder(atomicSymbols, symbol, startOffset, endOffset) { fun getProperty(property: IrProperty, dispatchReceiver: IrExpression?) = irCall(property.getter?.symbol ?: error("Getter is not defined for the property ${property.render()}")).apply {
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuJvmIrTransformer.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuJvmIrTransformer.kt index 553d197..afdebfa 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuJvmIrTransformer.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicfuJvmIrTransformer.kt
@@ -644,7 +644,7 @@ return super.visitContainerExpression(expression, data) } - private fun AtomicfuIrBuilder.getAtomicFieldInfo( + private fun AtomicfuJvmIrBuilder.getAtomicFieldInfo( receiver: IrExpression, parentFunction: IrFunction? ): AtomicFieldInfo? {
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/JvmAtomicSymbols.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/JvmAtomicSymbols.kt index 86291cb..6285549 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/JvmAtomicSymbols.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/JvmAtomicSymbols.kt
@@ -11,12 +11,10 @@ import org.jetbrains.kotlin.ir.builders.declarations.* import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.* import org.jetbrains.kotlinx.atomicfu.compiler.backend.* @@ -32,16 +30,6 @@ private val kotlinJvm: IrPackageFragment = createPackage("kotlin.jvm") val javaLangClass: IrClassSymbol = createClass(javaLang, "Class", ClassKind.CLASS, Modality.FINAL) - // Native classes - private val kotlinNativeConcurrentPackage: IrPackageFragment = createPackage("kotlin.native.concurrent") - - val atomicIntNativeClass: IrClassSymbol = - createClass(kotlinNativeConcurrentPackage, "AtomicInt", ClassKind.CLASS, Modality.FINAL) - - val atomicIntNativeConstructor: IrConstructorSymbol = atomicIntNativeClass.owner.addConstructor().apply { - addValueParameter("value_", irBuiltIns.intType) - }.symbol - // AtomicIntegerFieldUpdater val atomicIntFieldUpdaterClass: IrClassSymbol = createClass(javaUtilConcurrent, "AtomicIntegerFieldUpdater", ClassKind.CLASS, Modality.FINAL) @@ -552,9 +540,9 @@ val volatileAnnotationConstructorCall = IrConstructorCallImpl.fromSymbolOwner(volatileConstructor.returnType, volatileConstructor.symbol) - fun createBuilder( + override fun createBuilder( symbol: IrSymbol, - startOffset: Int = UNDEFINED_OFFSET, - endOffset: Int = UNDEFINED_OFFSET - ) = AtomicfuIrBuilder(this, symbol, startOffset, endOffset) + startOffset: Int, + endOffset: Int + ): AtomicfuJvmIrBuilder = AtomicfuJvmIrBuilder(this, symbol, startOffset, endOffset) }
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/AtomicfuNativeIrTransformer.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/AtomicfuNativeIrTransformer.kt index 22dff96..51e9a6d 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/AtomicfuNativeIrTransformer.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/AtomicfuNativeIrTransformer.kt
@@ -6,41 +6,41 @@ package org.jetbrains.kotlinx.atomicfu.compiler.backend.native import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classFqName import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm.JvmAtomicSymbols import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression +import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall +import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl +import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlinx.atomicfu.compiler.backend.capture +import org.jetbrains.kotlinx.atomicfu.compiler.backend.getValueArguments private const val AFU_PKG = "kotlinx.atomicfu" -private const val TRACE_BASE_TYPE = "TraceBase" private const val ATOMIC_VALUE_FACTORY = "atomic" -private const val INVOKE = "invoke" -private const val APPEND = "append" -private const val GET = "get" -private const val ATOMICFU = "atomicfu" -private const val ATOMIC_ARRAY_RECEIVER_SUFFIX = "\$array" -private const val DISPATCH_RECEIVER = "${ATOMICFU}\$dispatchReceiver" -private const val ATOMIC_HANDLER = "${ATOMICFU}\$handler" -private const val ACTION = "${ATOMICFU}\$action" -private const val INDEX = "${ATOMICFU}\$index" -private const val VOLATILE_WRAPPER_SUFFIX = "\$VolatileWrapper" -private const val LOOP = "loop" -private const val UPDATE = "update" class AtomicfuNativeIrTransformer( val context: IrPluginContext, - val atomicSymbols: JvmAtomicSymbols + val atomicSymbols: NativeAtomicSymbols ) { private val ATOMIC_VALUE_TYPES = setOf("AtomicInt", "AtomicLong", "AtomicBoolean", "AtomicRef") + private val AFU_VALUE_TYPES: Map<String, IrType> = mapOf( + "AtomicInt" to context.irBuiltIns.intType, + "AtomicLong" to context.irBuiltIns.longType, + "AtomicBoolean" to context.irBuiltIns.booleanType, + "AtomicRef" to context.irBuiltIns.anyNType + ) + fun transform(moduleFragment: IrModuleFragment) { transformAtomicFields(moduleFragment) + transformAtomicCalls(moduleFragment) } private fun transformAtomicFields(moduleFragment: IrModuleFragment) { @@ -49,6 +49,12 @@ } } + private fun transformAtomicCalls(moduleFragment: IrModuleFragment) { + for (irFile in moduleFragment.files) { + irFile.transform(AtomicfuTransformer(), null) + } + } + private inner class AtomicHandlerTransformer : IrElementTransformer<IrFunction?> { override fun visitClass(declaration: IrClass, data: IrFunction?): IrStatement { declaration.declarations.filter(::fromKotlinxAtomicfu).forEach { @@ -83,28 +89,54 @@ } } } - - private fun IrProperty.isAtomic(): Boolean = - !isDelegated && backingField?.type?.isAtomicValueType() ?: false - - private fun IrType.isAtomicValueType() = - classFqName?.let { - it.parent().asString() == AFU_PKG && it.shortName().asString() in ATOMIC_VALUE_TYPES - } ?: false - - private fun fromKotlinxAtomicfu(declaration: IrDeclaration): Boolean = - declaration is IrProperty && - declaration.backingField?.type?.isKotlinxAtomicfuPackage() ?: false - - private fun IrType.isKotlinxAtomicfuPackage() = - classFqName?.let { it.parent().asString() == AFU_PKG } ?: false - - private fun IrCall.isAtomicFactory(): Boolean = - symbol.isKotlinxAtomicfuPackage() && symbol.owner.name.asString() == ATOMIC_VALUE_FACTORY && - type.isAtomicValueType() - - // todo abstract - private fun IrSimpleFunctionSymbol.isKotlinxAtomicfuPackage(): Boolean = - owner.parent.kotlinFqName.asString() == AFU_PKG } + + private inner class AtomicfuTransformer : IrElementTransformer<IrFunction?> { + override fun visitCall(expression: IrCall, data: IrFunction?): IrElement { + (expression.extensionReceiver ?: expression.dispatchReceiver)?.transform(this, data)?.let { + with(atomicSymbols.createBuilder(expression.symbol)) { + val receiver = if (it is IrTypeOperatorCallImpl) it.argument else it + if (receiver.type.isAtomicValueType()) { // todo only AtomicInt is supported + val functionName = expression.symbol.owner.name.asString() + val irCall = irCall(atomicSymbols.atomicIntNativeClass.getSimpleFunction(functionName)!!).apply { + this.dispatchReceiver = (receiver as IrCall).dispatchReceiver + expression.getValueArguments().forEachIndexed { index, arg -> + putValueArgument(index, arg) + } + } + return super.visitCall(irCall, data) + } + } + } + return super.visitCall(expression, data) + } + } + + private fun IrProperty.isAtomic(): Boolean = + !isDelegated && backingField?.type?.isAtomicValueType() ?: false + + private fun IrType.isAtomicValueType() = + classFqName?.let { + it.parent().asString() == AFU_PKG && it.shortName().asString() in ATOMIC_VALUE_TYPES + } ?: false + + private fun IrType.atomicToValueType(): IrType = + classFqName?.let { + AFU_VALUE_TYPES[it.shortName().asString()] + } ?: error("No corresponding value type was found for this atomic type: ${this.render()}") + + private fun fromKotlinxAtomicfu(declaration: IrDeclaration): Boolean = + declaration is IrProperty && + declaration.backingField?.type?.isKotlinxAtomicfuPackage() ?: false + + private fun IrType.isKotlinxAtomicfuPackage() = + classFqName?.let { it.parent().asString() == AFU_PKG } ?: false + + private fun IrCall.isAtomicFactory(): Boolean = + symbol.isKotlinxAtomicfuPackage() && symbol.owner.name.asString() == ATOMIC_VALUE_FACTORY && + type.isAtomicValueType() + + // todo abstract + private fun IrSimpleFunctionSymbol.isKotlinxAtomicfuPackage(): Boolean = + owner.parent.kotlinFqName.asString() == AFU_PKG }
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/NativeAtomicSymbols.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/NativeAtomicSymbols.kt index 156d06b..7ab9515 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/NativeAtomicSymbols.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/native/NativeAtomicSymbols.kt
@@ -5,8 +5,19 @@ package org.jetbrains.kotlinx.atomicfu.compiler.backend.native +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrBuiltIns +import org.jetbrains.kotlin.ir.builders.declarations.addConstructor +import org.jetbrains.kotlin.ir.builders.declarations.addFunction +import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.IrPackageFragment +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlinx.atomicfu.compiler.backend.AtomicIrBuilder import org.jetbrains.kotlinx.atomicfu.compiler.backend.AtomicSymbols class NativeAtomicSymbols( @@ -14,4 +25,39 @@ moduleFragment: IrModuleFragment ) : AtomicSymbols(irBuiltIns, moduleFragment) { + private val nativeConcurrentPackage: IrPackageFragment = createPackage("kotlin.native.concurrent") + + // kotlin.native.concurrent.AtomicInt + val atomicIntNativeClass: IrClassSymbol = + createClass(nativeConcurrentPackage, "AtomicInt", ClassKind.CLASS, Modality.FINAL) + + val atomicIntNativeConstructor: IrConstructorSymbol = atomicIntNativeClass.owner.addConstructor().apply { + addValueParameter("value_", irBuiltIns.intType) + }.symbol + + val atomicIntCompareAndSet: IrSimpleFunctionSymbol = + atomicIntNativeClass.owner.addFunction(name = "compareAndSet", returnType = irBuiltIns.booleanType).apply { + addValueParameter("expect", irBuiltIns.intType) + addValueParameter("new", irBuiltIns.intType) + }.symbol + + val atomicIntAddAndGet: IrSimpleFunctionSymbol = + atomicIntNativeClass.owner.addFunction(name = "addAndGet", returnType = irBuiltIns.intType).apply { + addValueParameter("delta", irBuiltIns.intType) + }.symbol + + val atomicIntGet: IrSimpleFunctionSymbol = + atomicIntNativeClass.owner.addFunction(name = "get", returnType = irBuiltIns.intType).symbol + + val atomicIntSet: IrSimpleFunctionSymbol = + atomicIntNativeClass.owner.addFunction(name = "set", returnType = irBuiltIns.unitType).apply { + addValueParameter("new", irBuiltIns.intType) + }.symbol + + // TODO: getAndAdd, incrementAndGet, getAndIncrement, decrementAndGet, getAndDecrement, lazySet, getAndSet + + override fun createBuilder(symbol: IrSymbol, startOffset: Int, endOffset: Int): AtomicIrBuilder = + AtomicIrBuilder(this, symbol, startOffset, endOffset) + + }
diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuLoweringExtension.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuLoweringExtension.kt index a1c49d4..a41b4c4 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuLoweringExtension.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/extensions/AtomicfuLoweringExtension.kt
@@ -22,6 +22,7 @@ import org.jetbrains.kotlinx.atomicfu.compiler.backend.js.AtomicfuJsIrTransformer import org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm.AtomicfuJvmIrTransformer import org.jetbrains.kotlinx.atomicfu.compiler.backend.native.AtomicfuNativeIrTransformer +import org.jetbrains.kotlinx.atomicfu.compiler.backend.native.NativeAtomicSymbols public open class AtomicfuLoweringExtension : IrGenerationExtension { override fun generate( @@ -35,7 +36,7 @@ AtomicfuJvmIrTransformer(pluginContext, atomicSymbols).transform(moduleFragment) } platform.isNative() -> { - val atomicSymbols = JvmAtomicSymbols(pluginContext.irBuiltIns, moduleFragment) + val atomicSymbols = NativeAtomicSymbols(pluginContext.irBuiltIns, moduleFragment) AtomicfuNativeIrTransformer(pluginContext, atomicSymbols).transform(moduleFragment) } platform.isJs() -> {
diff --git a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlin/konan/blackboxtest/AtomicfuNativeTestGenerated.java b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlin/konan/blackboxtest/AtomicfuNativeTestGenerated.java index 2bc637c..e96b662 100644 --- a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlin/konan/blackboxtest/AtomicfuNativeTestGenerated.java +++ b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlin/konan/blackboxtest/AtomicfuNativeTestGenerated.java
@@ -18,175 +18,19 @@ /** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box") +@TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/nativeBox") @TestDataPath("$PROJECT_ROOT") @Tag("codegen") @UseStandardTestCaseGroupProvider() public class AtomicfuNativeTestGenerated extends AbstractNativeBlackBoxTest { @Test public void testAllFilesPresentInBox() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/nativeBox"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); } @Test @TestMetadata("ArithmeticTest.kt") public void testArithmeticTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.kt"); + runTest("plugins/atomicfu/atomicfu-compiler/testData/nativeBox/ArithmeticTest.kt"); } - - //@Test - //@TestMetadata("ArrayInlineExtensionTest.kt") - //public void testArrayInlineExtensionTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.kt"); - //} - // - //@Test - //@TestMetadata("ArrayLoopTest.kt") - //public void testArrayLoopTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.kt"); - //} - // - //@Test - //@TestMetadata("AtomicArrayTest.kt") - //public void testAtomicArrayTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.kt"); - //} - // - //@Test - //@TestMetadata("ComplexLoopTest.kt") - //public void testComplexLoopTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.kt"); - //} - // - //@Test - //@TestMetadata("DelegatedPropertiesTest.kt") - //public void testDelegatedPropertiesTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.kt"); - //} - // - //@Test - //@TestMetadata("ExtensionLoopTest.kt") - //public void testExtensionLoopTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionLoopTest.kt"); - //} - // - //@Test - //@TestMetadata("ExtensionsTest.kt") - //public void testExtensionsTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionsTest.kt"); - //} - // - //@Test - //@TestMetadata("IndexArrayElementGetterTest.kt") - //public void testIndexArrayElementGetterTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/IndexArrayElementGetterTest.kt"); - //} - // - //@Test - //@TestMetadata("InlineExtensionWithTypeParameterTest.kt") - //public void testInlineExtensionWithTypeParameterTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/InlineExtensionWithTypeParameterTest.kt"); - //} - // - //@Test - //@TestMetadata("LambdaTest.kt") - //public void testLambdaTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LambdaTest.kt"); - //} - // - //@Test - //@TestMetadata("LateinitPropertiesTest.kt") - //public void testLateinitPropertiesTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LateinitPropertiesTest.kt"); - //} - // - //@Test - //@TestMetadata("LockFreeIntBitsTest.kt") - //public void testLockFreeIntBitsTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeIntBitsTest.kt"); - //} - // - //@Test - //@TestMetadata("LockFreeLongCounterTest.kt") - //public void testLockFreeLongCounterTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeLongCounterTest.kt"); - //} - // - //@Test - //@TestMetadata("LockFreeQueueTest.kt") - //public void testLockFreeQueueTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeQueueTest.kt"); - //} - // - //@Test - //@TestMetadata("LockFreeStackTest.kt") - //public void testLockFreeStackTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeStackTest.kt"); - //} - // - //@Test - //@TestMetadata("LockTest.kt") - //public void testLockTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LockTest.kt"); - //} - // - //@Test - //@TestMetadata("LoopTest.kt") - //public void testLoopTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/LoopTest.kt"); - //} - // - //@Test - //@TestMetadata("MultiInitTest.kt") - //public void testMultiInitTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/MultiInitTest.kt"); - //} - // - //@Test - //@TestMetadata("ParameterizedInlineFunExtensionTest.kt") - //public void testParameterizedInlineFunExtensionTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ParameterizedInlineFunExtensionTest.kt"); - //} - // - //@Test - //@TestMetadata("ReentrantLockTest.kt") - //public void testReentrantLockTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ReentrantLockTest.kt"); - //} - // - //@Test - //@TestMetadata("ScopeTest.kt") - //public void testScopeTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ScopeTest.kt"); - //} - // - //@Test - //@TestMetadata("SimpleLockTest.kt") - //public void testSimpleLockTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/SimpleLockTest.kt"); - //} - // - //@Test - //@TestMetadata("SynchronizedObjectTest.kt") - //public void testSynchronizedObjectTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/SynchronizedObjectTest.kt"); - //} - // - //@Test - //@TestMetadata("TopLevelTest.kt") - //public void testTopLevelTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/TopLevelTest.kt"); - //} - // - //@Test - //@TestMetadata("TraceTest.kt") - //public void testTraceTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/TraceTest.kt"); - //} - // - //@Test - //@TestMetadata("UncheckedCastTest.kt") - //public void testUncheckedCastTest() throws Exception { - // runTest("plugins/atomicfu/atomicfu-compiler/testData/box/UncheckedCastTest.kt"); - //} }
diff --git a/plugins/atomicfu/atomicfu-compiler/testData/nativeBox/ArithmeticTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/nativeBox/ArithmeticTest.kt index 6440e55..798cb01 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/nativeBox/ArithmeticTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/nativeBox/ArithmeticTest.kt
@@ -4,145 +4,20 @@ import kotlin.test.* class IntArithmetic { - val _x = atomic(0) - val x get() = _x.value -} - -class LongArithmetic { - val _x = atomic(4294967296) - val x get() = _x.value - val y = atomic(5000000000) - val z = atomic(2424920024888888848) - val max = atomic(9223372036854775807) -} - -class BooleanArithmetic { - val _x = atomic(false) - val x get() = _x.value -} - -class ReferenceArithmetic { - val _x = atomic<String?>(null) -} - -class VisibilitiesTest { - val a = atomic(0) - public val b = atomic(1) - private val c = atomic(2) - internal val d = atomic(3) - - fun test() { - a.lazySet(45) - b.lazySet(56) - c.lazySet(46) - d.lazySet(67) - } + val x = atomic(0) } class ArithmeticTest { - val local = atomic(0) - - fun testGetValue() { - val a = IntArithmetic() - a._x.value = 5 - assertEquals(5, a._x.value) - var aValue = a._x.value - assertEquals(5, aValue) - assertEquals(5, a.x) - - local.value = 555 - aValue = local.value - assertEquals(aValue, local.value) - } - - fun testAtomicCallPlaces(): Boolean { - val a = IntArithmetic() - a._x.value = 5 - a._x.compareAndSet(5, 42) - val res = a._x.compareAndSet(42, 45) - assertTrue(res) - assertTrue(a._x.compareAndSet(45, 77)) - assertFalse(a._x.compareAndSet(95, 77)) - return a._x.compareAndSet(77, 88) - } fun testInt() { val a = IntArithmetic() - assertEquals(0, a.x) - val update = 3 - assertEquals(0, a._x.getAndSet(update)) - assertTrue(a._x.compareAndSet(update, 8)) - a._x.lazySet(1) - assertEquals(1, a.x) - assertEquals(1, a._x.getAndSet(2)) - assertEquals(2, a.x) - assertEquals(2, a._x.getAndIncrement()) - assertEquals(3, a.x) - assertEquals(3, a._x.getAndDecrement()) - assertEquals(2, a.x) - assertEquals(2, a._x.getAndAdd(2)) - assertEquals(4, a.x) - assertEquals(7, a._x.addAndGet(3)) - assertEquals(7, a.x) - assertEquals(8, a._x.incrementAndGet()) - assertEquals(8, a.x) - assertEquals(7, a._x.decrementAndGet()) - assertEquals(7, a.x) - assertTrue(a._x.compareAndSet(7, 10)) - } - - fun testLong() { - val a = LongArithmetic() - assertEquals(2424920024888888848, a.z.value) - a.z.lazySet(8424920024888888848) - assertEquals(8424920024888888848, a.z.value) - assertEquals(8424920024888888848, a.z.getAndSet(8924920024888888848)) - assertEquals(8924920024888888848, a.z.value) - assertEquals(8924920024888888849, a.z.incrementAndGet()) - assertEquals(8924920024888888849, a.z.value) - assertEquals(8924920024888888849, a.z.getAndDecrement()) - assertEquals(8924920024888888848, a.z.value) - assertEquals(8924920024888888848, a.z.getAndAdd(100000000000000000)) - assertEquals(9024920024888888848, a.z.value) - assertEquals(-198452011965886959, a.z.addAndGet(-9223372036854775807)) - assertEquals(-198452011965886959, a.z.value) - assertEquals(-198452011965886958, a.z.incrementAndGet()) - assertEquals(-198452011965886958, a.z.value) - assertEquals(-198452011965886959, a.z.decrementAndGet()) - assertEquals(-198452011965886959, a.z.value) - } - - fun testBoolean() { - val a = BooleanArithmetic() - assertEquals(false, a._x.value) - assertFalse(a.x) - a._x.lazySet(true) - assertTrue(a.x) - assertTrue(a._x.getAndSet(true)) - assertTrue(a._x.compareAndSet(true, false)) - assertFalse(a.x) - } - - fun testReference() { - val a = ReferenceArithmetic() - a._x.value = "aaa" - assertEquals("aaa", a._x.value) - a._x.lazySet("bb") - assertEquals("bb", a._x.value) - assertEquals("bb", a._x.getAndSet("ccc")) - assertEquals("ccc", a._x.value) + assertTrue(a.x.compareAndSet(0, 3)) + assertEquals(5, a.x.addAndGet(3)) } } fun box(): String { val testClass = ArithmeticTest() - - testClass.testGetValue() - if (!testClass.testAtomicCallPlaces()) return "testAtomicCallPlaces: FAILED" - testClass.testInt() - testClass.testLong() - testClass.testBoolean() - testClass.testReference() return "OK" }