diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt index c0fd110c634..051712dbc5e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt @@ -139,6 +139,17 @@ inline fun IrProperty.addGetter(builder: IrFunctionBuilder.() -> Unit = {}): IrS } } +inline fun IrProperty.addSetter(builder: IrFunctionBuilder.() -> Unit = {}): IrSimpleFunction = + IrFunctionBuilder().run { + name = Name.special("") + builder() + factory.buildFunction(this).also { setter -> + this@addSetter.setter = setter + setter.correspondingPropertySymbol = this@addSetter.symbol + setter.parent = this@addSetter.parent + } + } + fun IrProperty.addDefaultGetter(parentClass: IrClass, builtIns: IrBuiltIns) { val field = backingField!! addGetter { diff --git a/gradle.properties b/gradle.properties index 87f0915737e..4759961c817 100644 --- a/gradle.properties +++ b/gradle.properties @@ -138,4 +138,4 @@ kotlin.build.internal.gradle.setup=true # ===================== # Enable new dependency resolution | KT-58319 -kotlin.mpp.import.enableKgpDependencyResolution=true \ No newline at end of file +kotlin.mpp.import.enableKgpDependencyResolution=true diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicSymbols.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicSymbols.kt new file mode 100644 index 00000000000..497ac25a2c8 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicSymbols.kt @@ -0,0 +1,101 @@ +/* + * 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.common + +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.IrBuiltIns +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.declarations.addConstructor +import org.jetbrains.kotlin.ir.builders.declarations.buildClass +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall +import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.types.IrSimpleType +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.ir.util.createImplicitParameterDeclarationWithWrappedDescriptor +import org.jetbrains.kotlin.ir.util.getSimpleFunction +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.Variance + +abstract class AbstractAtomicSymbols( + val context: IrPluginContext, + private val moduleFragment: IrModuleFragment +) { + val irBuiltIns: IrBuiltIns = context.irBuiltIns + protected val irFactory: IrFactory = IrFactoryImpl + + abstract val volatileAnnotationClass: IrClass + val volatileAnnotationConstructorCall: IrConstructorCall + get() { + val volatileAnnotationConstructor = buildAnnotationConstructor(volatileAnnotationClass) + return IrConstructorCallImpl.fromSymbolOwner(volatileAnnotationConstructor.returnType, volatileAnnotationConstructor.symbol) + } + + abstract fun createBuilder( + symbol: IrSymbol, + startOffset: Int = UNDEFINED_OFFSET, + endOffset: Int = UNDEFINED_OFFSET + ): AbstractAtomicfuIrBuilder + + val invoke1Symbol = irBuiltIns.functionN(1).getSimpleFunction("invoke")!! + + fun function1Type(argType: IrType, returnType: IrType) = buildSimpleType( + irBuiltIns.functionN(1).symbol, + listOf(argType, returnType) + ) + + object ATOMICFU_GENERATED_CLASS : IrDeclarationOriginImpl("ATOMICFU_GENERATED_CLASS", isSynthetic = true) + object ATOMICFU_GENERATED_FUNCTION : IrDeclarationOriginImpl("ATOMICFU_GENERATED_FUNCTION", isSynthetic = true) + object ATOMICFU_GENERATED_FIELD : IrDeclarationOriginImpl("ATOMICFU_GENERATED_FIELD", isSynthetic = true) + object ATOMICFU_GENERATED_PROPERTY : IrDeclarationOriginImpl("ATOMICFU_GENERATED_PROPERTY", isSynthetic = true) + object ATOMICFU_GENERATED_PROPERTY_ACCESSOR : IrDeclarationOriginImpl("ATOMICFU_GENERATED_PROPERTY_ACCESSOR", isSynthetic = true) + + protected fun createPackage(packageName: String): IrPackageFragment = + IrExternalPackageFragmentImpl.createEmptyExternalPackageFragment( + moduleFragment.descriptor, + FqName(packageName) + ) + + protected fun createClass( + irPackage: IrPackageFragment, + shortName: String, + classKind: ClassKind, + classModality: Modality, + isValueClass: Boolean = false, + ): IrClassSymbol = irFactory.buildClass { + name = Name.identifier(shortName) + kind = classKind + modality = classModality + isValue = isValueClass + }.apply { + parent = irPackage + createImplicitParameterDeclarationWithWrappedDescriptor() + }.symbol + + private fun buildAnnotationConstructor(annotationClass: IrClass): IrConstructor = + annotationClass.addConstructor { isPrimary = true } + + private fun buildSimpleType( + symbol: IrClassifierSymbol, + typeParameters: List + ): IrSimpleType = + IrSimpleTypeImpl( + classifier = symbol, + hasQuestionMark = false, + arguments = typeParameters.map { makeTypeProjection(it, Variance.INVARIANT) }, + annotations = emptyList() + ) +} diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicfuIrBuilder.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicfuIrBuilder.kt new file mode 100644 index 00000000000..f1a8e4eff69 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicfuIrBuilder.kt @@ -0,0 +1,225 @@ +/* + * 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.common + +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.DescriptorVisibility +import org.jetbrains.kotlin.ir.IrBuiltIns +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.builders.declarations.* +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeAsciiOnly + +abstract class AbstractAtomicfuIrBuilder( + private val irBuiltIns: IrBuiltIns, + symbol: IrSymbol, + startOffset: Int, + endOffset: Int +) : IrBuilderWithScope(IrGeneratorContextBase(irBuiltIns), Scope(symbol), startOffset, endOffset) { + + abstract val atomicSymbols: AbstractAtomicSymbols + + fun irGetProperty(property: IrProperty, dispatchReceiver: IrExpression?) = + irCall(property.getter?.symbol ?: error("Getter is not defined for the property ${property.render()}")).apply { + this.dispatchReceiver = dispatchReceiver?.deepCopyWithSymbols() + } + + fun irCallWithArgs(symbol: IrSimpleFunctionSymbol, dispatchReceiver: IrExpression?, extensionReceiver: IrExpression?, valueArguments: List) = + irCall(symbol).apply { + this.dispatchReceiver = dispatchReceiver + this.extensionReceiver = extensionReceiver + valueArguments.forEachIndexed { i, arg -> + putValueArgument(i, arg) + } + } + + fun irVolatileField( + name: String, + type: IrType, + initValue: IrExpression?, + annotations: List, + parentContainer: IrDeclarationContainer + ): IrField = + context.irFactory.buildField { + this.name = Name.identifier(name) + this.type = type + isFinal = false + isStatic = parentContainer is IrFile + visibility = DescriptorVisibilities.PRIVATE + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_FIELD + }.apply { + initializer = initValue?.let { IrExpressionBodyImpl(it) } + this.annotations = annotations + atomicSymbols.volatileAnnotationConstructorCall + this.parent = parentContainer + } + + fun buildClassInstance( + irClass: IrClass, + parentContainer: IrDeclarationContainer, + isStatic: Boolean + ): IrField = + context.irFactory.buildField { + this.name = Name.identifier(irClass.name.asString().decapitalizeAsciiOnly()) + type = irClass.defaultType + isFinal = true + this.isStatic = isStatic + this.visibility = DescriptorVisibilities.PRIVATE + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_FIELD + }.apply { + initializer = IrExpressionBodyImpl( + IrConstructorCallImpl.fromSymbolOwner( + irClass.defaultType, + irClass.primaryConstructor!!.symbol + ) + ) + this.parent = parentContainer + } + + fun IrExpression.toBoolean() = irNotEquals(this, irInt(0)) as IrCall + + fun irClassWithPrivateConstructor( + name: String, + visibility: DescriptorVisibility, + parentContainer: IrDeclarationContainer + ): IrClass = context.irFactory.buildClass { + this.name = Name.identifier(name) + kind = ClassKind.CLASS + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_CLASS + }.apply { + val irClass = this + this.parent = parentContainer + parentContainer.addChild(irClass) + thisReceiver = buildValueParameter(irClass) { + this.name = Name.identifier("\$this") + type = IrSimpleTypeImpl(irClass.symbol, false, emptyList(), emptyList()) + } + irClass.visibility = visibility + addConstructor { + isPrimary = true + }.apply { + body = atomicSymbols.createBuilder(symbol).irBlockBody(startOffset, endOffset) { + +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single()) + +IrInstanceInitializerCallImpl(startOffset, endOffset, irClass.symbol, context.irBuiltIns.unitType) + } + this.visibility = DescriptorVisibilities.PRIVATE // constructor of the wrapper class should be private + } + } + + fun IrDeclarationContainer.replacePropertyAtIndex( + field: IrField, + visibility: DescriptorVisibility, + isVar: Boolean, + isStatic: Boolean, + index: Int + ): IrProperty = buildPropertyWithAccessors(field, visibility, isVar, isStatic, this).also { declarations[index] = it } + + fun IrDeclarationContainer.addProperty( + field: IrField, + visibility: DescriptorVisibility, + isVar: Boolean, + isStatic: Boolean + ): IrProperty = buildPropertyWithAccessors(field, visibility, isVar, isStatic, this).also { declarations.add(it) } + + private fun buildPropertyWithAccessors( + field: IrField, + visibility: DescriptorVisibility, + isVar: Boolean, + isStatic: Boolean, + parentContainer: IrDeclarationContainer + ) = context.irFactory.buildProperty { + this.name = field.name + this.visibility = visibility + this.isVar = isVar + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_PROPERTY + }.apply { + backingField = field + field.correspondingPropertySymbol = this.symbol + parent = parentContainer + addGetter(isStatic, parentContainer, irBuiltIns) + if (isVar) { + addSetter(isStatic, parentContainer, irBuiltIns) + } + } + + private fun IrProperty.addGetter(isStatic: Boolean, parentContainer: IrDeclarationContainer, irBuiltIns: IrBuiltIns) { + val property = this + val field = requireNotNull(backingField) { "BackingField of the property $property should not be null"} + addGetter { + visibility = property.visibility + returnType = field.type + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_PROPERTY_ACCESSOR + }.apply { + dispatchReceiverParameter = if (isStatic) null else (parentContainer as? IrClass)?.thisReceiver?.deepCopyWithSymbols(this) + body = factory.createBlockBody( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf( + IrReturnImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + irBuiltIns.nothingType, + symbol, + IrGetFieldImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + field.symbol, + field.type, + dispatchReceiverParameter?.let { + IrGetValueImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + it.type, + it.symbol + ) + } + ) + ) + ) + ) + } + } + + private fun IrProperty.addSetter(isStatic: Boolean, parentClass: IrDeclarationContainer, irBuiltIns: IrBuiltIns) { + val property = this + val field = requireNotNull(property.backingField) { "BackingField of the property $property should not be null"} + this@addSetter.addSetter { + visibility = property.visibility + returnType = irBuiltIns.unitType + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_PROPERTY_ACCESSOR + }.apply { + dispatchReceiverParameter = if (isStatic) null else (parentClass as? IrClass)?.thisReceiver?.deepCopyWithSymbols(this) + addValueParameter("value", field.type) + val value = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueParameters[0].type, valueParameters[0].symbol) + body = factory.createBlockBody( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf( + IrReturnImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + irBuiltIns.unitType, + symbol, + IrSetFieldImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + field.symbol, + dispatchReceiverParameter?.let { + IrGetValueImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + it.type, + it.symbol + ) + }, + value, + irBuiltIns.unitType + ) + ) + ) + ) + } + } +} diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicfuTransformer.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicfuTransformer.kt new file mode 100644 index 00000000000..bccc68dcd92 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/common/AbstractAtomicfuTransformer.kt @@ -0,0 +1,736 @@ +/* + * 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.common + +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.backend.common.lower.parents +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.DescriptorVisibility +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.builders.irExprBody +import org.jetbrains.kotlin.ir.builders.irGetField +import org.jetbrains.kotlin.ir.builders.irSetField +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl +import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol +import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol +import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.visitors.* +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance + +private const val ATOMICFU = "atomicfu" +private const val ARRAY = "array" +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 VOLATILE = "\$volatile" +private const val VOLATILE_WRAPPER_SUFFIX = "\$VolatileWrapper\$$ATOMICFU" + +abstract class AbstractAtomicfuTransformer(val pluginContext: IrPluginContext) { + + companion object { + const val CONSTRAINTS_MESSAGE = + "\n\nPlease make sure that you follow these constraints for using atomic properties:\n" + + " * To ensure that atomic properties are not accessed out of the current Kotlin module, it is necessary to declare atomic properties as private or internal,\n" + + " or make the containing class private or internal.\n" + + " To expose the atomic property value to the public, use a delegated property declared in the same scope, e.g: \n" + + " ```\n" + + " private val _a = atomic(initial) \n" + + " public var a: T by _a \n" + + " ```\n" + + " * Only perform operations directly on atomic values:\n" + + " * Avoid storing references to atomic values in local variables, e.g.\n" + + " ```\n" + + " val top = atomic(null)\n" + + " top.compareAndSet(null, Node(1)) // OK: direct invocation on the atomic property is allowed \n" + + " ```\n" + + " ```\n" + + " val tmp = top\n" + + " tmp.compareAndSet(null, Node(1)) // DON'T DO THIS: invocation on a local variable is NOT allowed \n" + + " ```\n" + + " * Do not leak references to atomic values in other way (return, pass as params, etc).\n" + + " * Avoid introducing complex data flow within parameters of atomic operations:\n" + + " Instead of top.compareAndSet(cur, ) use \n" + + " ```\n" + + " val newValue = \n" + + " top.compareAndSet(cur, newValue) \n" + + " ```\n" + + "\n" + } + + abstract val atomicSymbols: AbstractAtomicSymbols + protected val irBuiltIns = pluginContext.irBuiltIns + + private val ATOMICFU_INLINE_FUNCTIONS = setOf("loop", "update", "getAndUpdate", "updateAndGet") + private val ATOMIC_VALUE_TYPES = setOf("AtomicInt", "AtomicLong", "AtomicBoolean", "AtomicRef") + private val ATOMIC_ARRAY_TYPES = setOf("AtomicIntArray", "AtomicLongArray", "AtomicBooleanArray", "AtomicArray") + + protected val atomicPropertyToVolatile = mutableMapOf() + protected val propertyToAtomicHandler = mutableMapOf() + + fun transform(moduleFragment: IrModuleFragment) { + transformAtomicProperties(moduleFragment) + transformAtomicExtensions(moduleFragment) + transformAtomicFunctions(moduleFragment) + finalTransformationCheck(moduleFragment) + for (irFile in moduleFragment.files) { + irFile.patchDeclarationParents() + } + } + + protected abstract val atomicPropertiesTransformer: AtomicPropertiesTransformer + protected abstract val atomicExtensionsTransformer: AtomicExtensionTransformer + protected abstract val atomicFunctionsTransformer: AtomicFunctionCallTransformer + + private fun transformAtomicProperties(moduleFragment: IrModuleFragment) { + for (irFile in moduleFragment.files) { + irFile.transform(atomicPropertiesTransformer, null) + } + } + + private fun transformAtomicExtensions(moduleFragment: IrModuleFragment) { + for (irFile in moduleFragment.files) { + irFile.transform(atomicExtensionsTransformer, null) + } + } + + private fun transformAtomicFunctions(moduleFragment: IrModuleFragment) { + for (irFile in moduleFragment.files) { + irFile.transform(atomicFunctionsTransformer, null) + } + } + + private fun finalTransformationCheck(moduleFragment: IrModuleFragment) { + val finalTransformationChecker = FinalTransformationChecker() + for (irFile in moduleFragment.files) { + irFile.accept(finalTransformationChecker, null) + } + } + + protected abstract inner class AtomicPropertiesTransformer : IrElementTransformer { + + override fun visitClass(declaration: IrClass, data: IrFunction?): IrStatement { + val declarationsToBeRemoved = mutableListOf() + declaration.declarations.withIndex().filter { isPropertyOfAtomicfuType(it.value) }.forEach { + transformAtomicProperty(it.value as IrProperty, it.index, declarationsToBeRemoved) + } + declaration.declarations.removeAll(declarationsToBeRemoved) + return super.visitClass(declaration, data) + } + + override fun visitFile(declaration: IrFile, data: IrFunction?): IrFile { + val declarationsToBeRemoved = mutableListOf() + declaration.declarations.withIndex().filter { isPropertyOfAtomicfuType(it.value) }.forEach { + transformAtomicProperty(it.value as IrProperty, it.index, declarationsToBeRemoved) + } + declaration.declarations.removeAll(declarationsToBeRemoved) + return super.visitFile(declaration, data) + } + + private fun transformAtomicProperty(atomicProperty: IrProperty, index: Int, declarationsToBeRemoved: MutableList) { + val parentContainer = atomicProperty.parents.firstIsInstance() + val isTopLevel = parentContainer is IrFile || (parentContainer is IrClass && parentContainer.kind == ClassKind.OBJECT) + when { + atomicProperty.isAtomic() -> { + if (isTopLevel) { + atomicProperty.checkVisibility() + parentContainer.addTransformedStaticAtomic(atomicProperty, index) + } else { + atomicProperty.checkVisibility() + (parentContainer as IrClass).addTransformedInClassAtomic(atomicProperty, index) + }.also { + declarationsToBeRemoved.add(atomicProperty) + } + } + atomicProperty.isAtomicArray() -> { + atomicProperty.checkVisibility() + parentContainer.addTransformedAtomicArray(atomicProperty, index)?.also { + declarationsToBeRemoved.add(atomicProperty) + } + } + atomicProperty.isDelegatedToAtomic() -> parentContainer.transformDelegatedAtomic(atomicProperty) + atomicProperty.isTrace() -> declarationsToBeRemoved.add(atomicProperty) + else -> {} + } + } + + /** + * Generates a volatile property that can be atomically updated instead of the given atomic property + * and adds it to the parent class. + * Returns the volatile property. + */ + abstract fun IrClass.addTransformedInClassAtomic(atomicProperty: IrProperty, index: Int): IrProperty + + /** + * Generates a volatile property that can be atomically updated instead of the given static atomic property + * and adds it to the parent container. + * Returns the voaltile property. + */ + abstract fun IrDeclarationContainer.addTransformedStaticAtomic(atomicProperty: IrProperty, index: Int): IrProperty + + /** + * Generates an array that can be atomically updated instead of the given atomic array + * and adds it to the parent class. + * Returns the new property or null if transformation was skipped. + * NOTE: skipping transformation is supported for K/N backend, because arrays are currently not supported there. + */ + abstract fun IrDeclarationContainer.addTransformedAtomicArray(atomicProperty: IrProperty, index: Int): IrProperty? + + /** + * Transforms the given property that was delegated to the atomic property: + * delegates accessors to the volatile property that was generated instead of the atomic property. + */ + private fun IrDeclarationContainer.transformDelegatedAtomic(atomicProperty: IrProperty) { + val getDelegate = atomicProperty.backingField?.initializer?.expression + require(getDelegate is IrCall) { "Expected initializer of the delegated property ${this.render()} is IrCall but found ${getDelegate?.render()}" } + val delegateVolatileField = when { + getDelegate.isAtomicFactoryCall() -> { + /** + * 1. Property delegated to atomic factory invocation is transformed to the volatile property: + * + * var a by atomic(0) --> @Volatile var a = 0 + * get() = a + * set(value: Int) { a = value } + */ + with(atomicSymbols.createBuilder(atomicProperty.symbol)) { + buildVolatileBackingField(atomicProperty, this@transformDelegatedAtomic, false).also { + declarations.add(it) + } + } + } + getDelegate.symbol.owner.isGetter -> { + /** + * 2. Property delegated to another atomic property: + * it's accessors should get/set the value of the delegate (that is already transformed to the atomically updated volatile property). + * + * val _a = atomic(0) @Volatile _a = 0 (+ atomic updaters) + * var a by _a --> @Volatile var a = 0 + * get() = _a + * set(value: Int) { _a = value } + */ + val delegate = getDelegate.getCorrespondingProperty() + check(delegate.parent == atomicProperty.parent) { + "The delegated property [${atomicProperty.render()}] declared in [${atomicProperty.parent.render()}] should be declared in the same scope " + + "as the corresponding atomic property [${delegate.render()}] declared in [${delegate.parent.render()}]." + CONSTRAINTS_MESSAGE} + val volatileProperty = atomicPropertyToVolatile[delegate] ?: error("The delegate property was not transformed: ${delegate.render()}.") + volatileProperty.backingField ?: error("Transformed atomic field should have a non-null backingField.") + } + else -> error("Unexpected initializer of the delegated property ${this.render()}") + } + atomicProperty.getter?.transformAccessor(delegateVolatileField) + atomicProperty.setter?.transformAccessor(delegateVolatileField) + atomicProperty.backingField = null + } + + private fun IrSimpleFunction.transformAccessor(delegateVolatileField: IrField) { + val dispatchReceiver = + if (delegateVolatileField.parent is IrClass && delegateVolatileField.parentAsClass.name.asString().contains(VOLATILE_WRAPPER_SUFFIX)) { + getStaticVolatileWrapperInstance(delegateVolatileField.parentAsClass) + } else { + dispatchReceiverParameter?.capture() + } + with(atomicSymbols.createBuilder(symbol)) { + body = irExprBody( + if (this@transformAccessor.isGetter) { + irGetField(dispatchReceiver, delegateVolatileField) + } else { + irSetField(dispatchReceiver, delegateVolatileField, this@transformAccessor.valueParameters[0].capture()) + } + ) + } + } + + /** + * Generates a private volatile field initialized with the initial value of the given atomic property: + * private val a = atomic(0) --> private @Volatile a: Int = 0 + */ + protected fun AbstractAtomicfuIrBuilder.buildVolatileBackingField( + atomicProperty: IrProperty, + parentContainer: IrDeclarationContainer, + tweakBooleanToInt: Boolean + ): IrField { + val atomicField = requireNotNull(atomicProperty.backingField) { "BackingField of atomic property $atomicProperty should not be null." } + val fieldType = atomicField.type.atomicToPrimitiveType() + val initializer = atomicField.initializer?.expression + if (initializer == null) { + val initBlock = atomicField.getInitBlockForField(parentContainer) + val initExprWithIndex = initBlock.getInitExprWithIndexFromInitBlock(atomicField.symbol) + ?: error("Expected property ${atomicProperty.render()} initialization in init block ${initBlock.render()}.") + val atomicFactoryCall = initExprWithIndex.value.value + val initExprIndex = initExprWithIndex.index + val initValue = atomicFactoryCall.getAtomicFactoryValueArgument() + return irVolatileField( + atomicProperty.name.asString() + VOLATILE, + // JVM: AtomicBoolean is transformed to a volatile Int field (boolean fields can only be updated with AtomicIntegerFieldUpdater) + // K/N: AtomicBoolean should be a volatile Boolean field + if (tweakBooleanToInt && fieldType.isBoolean()) irBuiltIns.intType else fieldType, + null, + atomicField.annotations, + parentContainer + ).also { + initBlock.updateFieldInitialization(atomicField.symbol, it.symbol, initValue, initExprIndex) + } + } else { + val initValue = initializer.getAtomicFactoryValueArgument() + return irVolatileField( + atomicProperty.name.asString() + VOLATILE, + // JVM: AtomicBoolean is transformed to a volatile Int field (boolean fields can only be updated with AtomicIntegerFieldUpdater) + // K/N: AtomicBoolean should be a volatile Boolean field + if (tweakBooleanToInt && fieldType.isBoolean()) irBuiltIns.intType else fieldType, + initValue, + atomicField.annotations, + parentContainer + ) + } + } + + /** + * In case if atomic property is initialized in init block it's declaration is replaced with the volatile property + * and initialization of the backing field is also performed in the init block: + * + * private val _a: AtomicInt --> @Volatile var _a: Int + * + * init { init { + * _a = atomic(0) _a = 0 + * } } + */ + protected fun IrAnonymousInitializer.getInitExprWithIndexFromInitBlock( + oldFieldSymbol: IrFieldSymbol + ): IndexedValue? = + body.statements.withIndex().singleOrNull { it.value is IrSetField && (it.value as IrSetField).symbol == oldFieldSymbol }?.let { + @Suppress("UNCHECKED_CAST") + it as IndexedValue + } + + protected fun IrAnonymousInitializer.updateFieldInitialization( + oldFieldSymbol: IrFieldSymbol, + volatileFieldSymbol: IrFieldSymbol, + initExpr: IrExpression, + index: Int + ) { + // save the order of field initialization in init block + body.statements.singleOrNull { + it is IrSetField && it.symbol == oldFieldSymbol + }?.let { + it as IrSetField + with(atomicSymbols.createBuilder(it.symbol)) { + body.statements[index] = irSetField(it.receiver, volatileFieldSymbol.owner, initExpr) + } + } + } + + protected fun IrField.getInitBlockForField(parentContainer: IrDeclarationContainer): IrAnonymousInitializer { + for (declaration in parentContainer.declarations) { + if (declaration is IrAnonymousInitializer) { + if (declaration.body.statements.any { it is IrSetField && it.symbol == this.symbol }) { + return declaration + } + } + } + error( + "Failed to find initialization of the property [${this.correspondingPropertySymbol?.owner?.render()}] in the init block of the class [${this.parent.render()}].\n" + + "Please avoid complex data flow in property initialization, e.g. instead of this:\n" + + "```\n" + + "val a: AtomicInt\n" + + "init {\n" + + " if (foo()) {\n" + + " a = atomic(0)\n" + + " } else { \n" + + " a = atomic(1)\n" + + " }\n" + + "}\n" + + "use simple direct assignment expression to initialize the property:\n" + + "```\n" + + "val a: AtomicInt\n" + + "init {\n" + + " val initValue = if (foo()) 0 else 1\n" + + " a = atomic(initValue)\n" + + "}\n" + + "```\n" + CONSTRAINTS_MESSAGE + ) + } + + // atomic(value = 0) -> 0 + private fun IrExpression.getAtomicFactoryValueArgument(): IrExpression { + require(this is IrCall) { "Expected atomic factory invocation but found: ${this.render()}." } + return getValueArgument(0)?.deepCopyWithSymbols() + ?: error("Atomic factory should take at least one argument: ${this.render()}.") + } + + // AtomicIntArray(size = 10) -> 10 + protected fun IrExpression.getArraySizeArgument(): IrExpression { + require(this is IrFunctionAccessExpression) { + "Expected atomic array factory invocation, but found: ${this.render()}." + } + return getValueArgument(0)?.deepCopyWithSymbols() + ?: error("Atomic array factory should take at least one argument: ${this.render()}.") + } + + private fun IrProperty.checkVisibility() = + check((visibility == DescriptorVisibilities.PRIVATE || visibility == DescriptorVisibilities.INTERNAL) || + (parent is IrClass && + (parentAsClass.visibility == DescriptorVisibilities.PRIVATE || parentAsClass.visibility == DescriptorVisibilities.INTERNAL))) { + "To ensure that atomic properties are not accessed out of the current Kotlin module, it is necessary to declare atomic properties as private or internal.\n" + + "Please consider declaring [${this.atomicfuRender()}] from [${this.parent.render()}] as a private or internal property." + + if (parent is IrClass) ",\nYou may also make the containing class [${parentAsClass.render()}] private or internal.\n" else "\n" + + "Alternatively, if you need to expose the atomic property value to the public, you can use a delegated property declared within the same scope, e.g:\n" + + "```\n" + + "private val _a = atomic(initial) \n" + + "public var a: T by _a \n" + + "```\n" + } + + protected fun IrProperty.getMinVisibility(): DescriptorVisibility { + // To protect atomic properties from leaking out of the current sourceSet, they are required to be internal or private, + // or the containing class may be internal or private. + // This method returns the minimal visibility between the property visibility and the class visibility applied to atomic updaters or volatile wrappers. + val classVisibility = if (this.parent is IrClass) parentAsClass.visibility else DescriptorVisibilities.PUBLIC + val compare = visibility.compareTo(classVisibility) ?: -1 // in case of non-comparable visibilities (e.g. local and private) return property visibility + return if (compare > 0) classVisibility else visibility + } + } + + protected abstract inner class AtomicExtensionTransformer : IrElementTransformerVoid() { + override fun visitFile(declaration: IrFile): IrFile { + declaration.transformAllAtomicExtensions() + return super.visitFile(declaration) + } + + override fun visitClass(declaration: IrClass): IrStatement { + declaration.transformAllAtomicExtensions() + return super.visitClass(declaration) + } + + abstract fun IrDeclarationContainer.transformAllAtomicExtensions() + } + + protected abstract inner class AtomicFunctionCallTransformer : IrElementTransformer { + + override fun visitFunction(declaration: IrFunction, data: IrFunction?): IrStatement { + return super.visitFunction(declaration, declaration) + } + + override fun visitCall(expression: IrCall, data: IrFunction?): IrElement { + (expression.extensionReceiver ?: expression.dispatchReceiver)?.transform(this, data)?.let { + val propertyGetterCall = if (it is IrTypeOperatorCallImpl) it.argument else it // () + if (propertyGetterCall.type.isAtomicValueType()) { + val valueType = if (it is IrTypeOperatorCallImpl) { + // If receiverExpression is a cast `s as AtomicRef` + // then valueType is the type argument of Atomic* class `String` + (it.type as IrSimpleType).arguments[0] as IrSimpleType + } else { + propertyGetterCall.type.atomicToPrimitiveType() + } + val isArrayReceiver = propertyGetterCall.isArrayElementReceiver(data) + if (expression.symbol.owner.isFromKotlinxAtomicfuPackage()) { + /** + * Transform invocations of functions from kotlinx.atomicfu on atomics properties or atomic array elements: + * + * ().compareAndSet(10, 45) + * ()[1].getAndSet(10) + * ().updateAndGet { cur -> cur + 100 } + */ + val functionName = expression.symbol.owner.name.asString() + if (functionName in ATOMICFU_INLINE_FUNCTIONS) { + val loopCall = transformedAtomicfuInlineFunctionCall( + expression = expression, + functionName = functionName, + valueType = valueType, + getPropertyReceiver = propertyGetterCall, + isArrayReceiver = isArrayReceiver, + parentFunction = data + ) + return super.visitCall(loopCall, data) + } + val irCall = if (isArrayReceiver) { + transformAtomicUpdateCallOnArrayElement( + expression = expression, + functionName = functionName, + valueType = valueType, + getPropertyReceiver = propertyGetterCall, + parentFunction = data + ) + } else { + transformAtomicUpdateCallOnProperty( + expression = expression, + functionName = functionName, + valueType = valueType, + castType = if (it is IrTypeOperatorCall) valueType else null, + getPropertyReceiver = propertyGetterCall, + parentFunction = data + ) + } + return super.visitExpression(irCall, data) + } + if (expression.symbol.owner.isInline && expression.extensionReceiver != null) { + /** + * Transform invocation of Atomic* extension functions, delegating them to the corresponding transformed atomic extensions: + * + * val _a = atomic(0) + * inline fun AtomicInt.foo() { ... } + * _a.foo() + */ + val declaration = expression.symbol.owner + val irCall = transformAtomicExtensionCall( + expression = expression, + originalAtomicExtension = declaration, + getPropertyReceiver = propertyGetterCall, + isArrayReceiver = isArrayReceiver, + parentFunction = data + ) + return super.visitCall(irCall, data) + } + } + } + return super.visitCall(expression, data) + } + + abstract fun transformAtomicUpdateCallOnProperty( + expression: IrCall, + functionName: String, + valueType: IrType, + castType: IrType?, + getPropertyReceiver: IrExpression, + parentFunction: IrFunction? + ): IrExpression + + abstract fun transformAtomicUpdateCallOnArrayElement( + expression: IrCall, + functionName: String, + valueType: IrType, + getPropertyReceiver: IrExpression, + parentFunction: IrFunction? + ): IrExpression + + abstract fun transformedAtomicfuInlineFunctionCall( + expression: IrCall, + functionName: String, + valueType: IrType, + getPropertyReceiver: IrExpression, + isArrayReceiver: Boolean, + parentFunction: IrFunction? + ): IrCall + + abstract fun transformAtomicExtensionCall( + expression: IrCall, + originalAtomicExtension: IrSimpleFunction, + getPropertyReceiver: IrExpression, + isArrayReceiver: Boolean, + parentFunction: IrFunction? + ): IrCall + + abstract fun IrDeclarationContainer.getTransformedAtomicExtension( + declaration: IrSimpleFunction, + isArrayReceiver: Boolean + ): IrSimpleFunction + + override fun visitGetValue(expression: IrGetValue, data: IrFunction?): IrExpression { + /** + * During transformation of atomic extensions value parameters are changed, though the body is just copied from the original declaration. + * This function replaces capturing of old value parameters with new parameters in the body of a transformed atomic extension. + * + * JVM example: + * + * inline fun AtomicInt.foo(to: Int) { --> inline fun foo$atomicfu(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, to': Int) { + * compareAndSet(0, to) handler.compareAndSet(0, to) // there is no parameter `to` in the new signature, + * // it should be replaced with `to'` + * } } + */ + if (expression.symbol is IrValueParameterSymbol) { + val valueParameter = expression.symbol.owner as IrValueParameter + val parent = valueParameter.parent + // skip value parameters of lambdas + if (parent is IrFunctionImpl && parent.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) return expression + if (data != null && data.isTransformedAtomicExtension() && + parent is IrFunctionImpl && !parent.isTransformedAtomicExtension()) { + return valueParameter.remapValueParameter(data)?.capture() ?: super.visitGetValue(expression, data) + } + } + return super.visitGetValue(expression, data) + } + + abstract fun IrValueParameter.remapValueParameter(transformedExtension: IrFunction): IrValueParameter? + + abstract fun IrFunction.isTransformedAtomicExtension(): Boolean + + abstract fun IrExpression.isArrayElementReceiver( + parentFunction: IrFunction? + ): Boolean + + override fun visitBlockBody(body: IrBlockBody, data: IrFunction?): IrBody { + // Erase messages added by the Trace object from the function body: + // val trace = Trace(size) + // Messages may be added via trace invocation: + // trace { "Doing something" } + // or via multi-append of arguments: + // trace.append(index, "CAS", value) + body.statements.removeIf { + it.isTraceCall() + } + return super.visitBlockBody(body, data) + } + + override fun visitContainerExpression(expression: IrContainerExpression, data: IrFunction?): IrExpression { + // Erase messages added by the Trace object from blocks. + expression.statements.removeIf { + it.isTraceCall() + } + return super.visitContainerExpression(expression, data) + } + } + + private inner class FinalTransformationChecker: IrElementTransformer { + override fun visitFunction(declaration: IrFunction, data: IrFunction?): IrStatement { + return super.visitFunction(declaration, declaration) + } + + override fun visitCall(expression: IrCall, data: IrFunction?): IrElement { + if (expression.symbol.owner.isGetter && (expression.type.isAtomicValueType() || expression.type.isAtomicArrayType())) { + val atomicProperty = expression.getCorrespondingProperty() + if ((atomicProperty.parent as IrDeclarationContainer).declarations.contains(atomicProperty)) { + error("Untransformed atomic property [${atomicProperty.atomicfuRender()}] is found in ${data?.render()}.\n" + + "Probably some constraints on usage of atomic properties were violated." + CONSTRAINTS_MESSAGE) + } else { + error("Function invocation is expected on the atomic property [${atomicProperty.atomicfuRender()}] in ${data?.render()}.\n" + + "Please invoke atomic get or update function." + CONSTRAINTS_MESSAGE) + } + } + return super.visitCall(expression, data) + } + } + + // Util transformer functions + + protected fun getStaticVolatileWrapperInstance(volatileWrapperClass: IrClass): IrExpression { + val volatileWrapperClassInstance = volatileWrapperClass.parentDeclarationContainer.declarations.find { + it is IrProperty && it.backingField?.type?.classOrNull == volatileWrapperClass.symbol + } ?: error("Instance of ${volatileWrapperClass.name.asString()} was not found in the parent class ${volatileWrapperClass.parentDeclarationContainer.render()}") + return with(atomicSymbols.createBuilder(volatileWrapperClass.symbol)) { + irGetProperty(volatileWrapperClassInstance as IrProperty, null) + } + } + + private fun IrFunction.isFromKotlinxAtomicfuPackage(): Boolean = parentDeclarationContainer.kotlinFqName.asString().startsWith(AFU_PKG) + + private fun isPropertyOfAtomicfuType(declaration: IrDeclaration): Boolean = + declaration is IrProperty && declaration.backingField?.type?.classFqName?.parent()?.asString() == AFU_PKG + + private fun IrProperty.isAtomic(): Boolean = + !isDelegated && backingField?.type?.isAtomicValueType() ?: false + + private fun IrProperty.isDelegatedToAtomic(): Boolean = + isDelegated && backingField?.type?.isAtomicValueType() ?: false + + private fun IrProperty.isAtomicArray(): Boolean = + backingField?.type?.isAtomicArrayType() ?: false + + private fun IrProperty.isTrace(): Boolean = + backingField?.type?.isTraceBaseType() ?: false + + protected fun IrType.isAtomicValueType() = + classFqName?.let { + it.parent().asString() == AFU_PKG && it.shortName().asString() in ATOMIC_VALUE_TYPES + } ?: false + + private fun IrType.isAtomicArrayType() = + classFqName?.let { + it.parent().asString() == AFU_PKG && it.shortName().asString() in ATOMIC_ARRAY_TYPES + } ?: false + + private fun IrType.isTraceBaseType() = + classFqName?.let { + it.parent().asString() == AFU_PKG && it.shortName().asString() == TRACE_BASE_TYPE + } ?: false + + private fun IrCall.isTraceInvoke(): Boolean = + symbol.owner.isFromKotlinxAtomicfuPackage() && + symbol.owner.name.asString() == INVOKE && + symbol.owner.dispatchReceiverParameter?.type?.isTraceBaseType() == true + + private fun IrCall.isTraceAppend(): Boolean = + symbol.owner.isFromKotlinxAtomicfuPackage() && + symbol.owner.name.asString() == APPEND && + symbol.owner.dispatchReceiverParameter?.type?.isTraceBaseType() == true + + private fun IrStatement.isTraceCall() = this is IrCall && (isTraceInvoke() || isTraceAppend()) + + protected fun IrCall.isArrayElementGetter(): Boolean = + dispatchReceiver?.let { + it.type.isAtomicArrayType() && symbol.owner.name.asString() == GET + } ?: false + + protected fun IrType.atomicToPrimitiveType(): IrType = + when(classFqName?.shortName()?.asString()) { + "AtomicInt" -> irBuiltIns.intType + "AtomicLong" -> irBuiltIns.longType + "AtomicBoolean" -> irBuiltIns.booleanType + "AtomicRef" -> irBuiltIns.anyNType + else -> error("Expected kotlinx.atomicfu.(AtomicInt|AtomicLong|AtomicBoolean|AtomicRef) type, but found ${this.render()}" + CONSTRAINTS_MESSAGE) + } + + protected fun IrCall.isAtomicFactoryCall(): Boolean = + symbol.owner.isFromKotlinxAtomicfuPackage() && symbol.owner.name.asString() == ATOMIC_VALUE_FACTORY && + type.isAtomicValueType() + + protected fun IrFunction.isAtomicExtension(): Boolean = + if (extensionReceiverParameter != null && extensionReceiverParameter!!.type.isAtomicValueType()) { + require(this.isInline) { "Non-inline extension functions on kotlinx.atomicfu.Atomic* classes are not allowed, " + + "please add inline modifier to the function ${this.render()}." } + require(this.visibility == DescriptorVisibilities.PRIVATE || this.visibility == DescriptorVisibilities.INTERNAL) { + "Only private or internal extension functions on kotlinx.atomicfu.Atomic* classes are allowed, " + + "please make the extension function ${this.render()} private or internal." + } + true + } else false + + protected fun IrCall.getCorrespondingProperty(): IrProperty = + symbol.owner.correspondingPropertySymbol?.owner + ?: error("Atomic property accessor ${this.render()} expected to have non-null correspondingPropertySymbol" + CONSTRAINTS_MESSAGE) + + protected fun IrExpression.isThisReceiver() = + this is IrGetValue && symbol.owner.name.asString() == "" + + protected val IrDeclaration.parentDeclarationContainer: IrDeclarationContainer + get() = parents.filterIsInstance().firstOrNull() + ?: error("In the sequence of parents for ${this.render()} no IrDeclarationContainer was found") + + protected val IrFunction.containingFunction: IrFunction + get() { + if (this.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) return this + return parents.filterIsInstance().firstOrNull { + it.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA + } ?: error("In the sequence of parents for the local function ${this.render()} no containing function was found") + } + + // A.kt -> A$VolatileWrapper$atomicfu + // B -> B$VolatileWrapper$atomicfu + protected fun mangleVolatileWrapperClassName(parent: IrDeclarationContainer): String = + ((if (parent is IrFile) parent.name else (parent as IrClass).name.asString())).substringBefore(".") + VOLATILE_WRAPPER_SUFFIX + + protected fun mangleAtomicExtensionName(name: String, isArrayReceiver: Boolean) = + if (isArrayReceiver) "$name$$ATOMICFU$$ARRAY" else "$name$$ATOMICFU" + + protected fun String.isMangledAtomicArrayExtension() = endsWith("$$ATOMICFU$$ARRAY") + + protected fun IrClass.isVolatileWrapper(v: DescriptorVisibility): Boolean = + this.name.asString() == mangleVolatileWrapperClassName(this.parent as IrDeclarationContainer) + "$" + v + + protected fun IrValueParameter.capture(): IrGetValue = IrGetValueImpl(startOffset, endOffset, symbol.owner.type, symbol) + + protected fun IrType.isObject() = classOrNull?.owner?.kind == ClassKind.OBJECT + + protected fun IrProperty.atomicfuRender(): String = + "val " + name.asString() + ": " + backingField?.type?.render() +} diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/js/AtomicfuJsIrTransformer.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/js/AtomicfuJsIrTransformer.kt index bce499ade31..80aa9191d6e 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/js/AtomicfuJsIrTransformer.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/js/AtomicfuJsIrTransformer.kt @@ -19,11 +19,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.expressions.IrTypeOperator.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.platform.isJs -import org.jetbrains.kotlinx.atomicfu.compiler.backend.* -import org.jetbrains.kotlinx.atomicfu.compiler.backend.buildCall -import org.jetbrains.kotlinx.atomicfu.compiler.backend.buildGetterType -import org.jetbrains.kotlinx.atomicfu.compiler.backend.buildSetterType -import org.jetbrains.kotlinx.atomicfu.compiler.backend.getBackingField private const val AFU_PKG = "kotlinx.atomicfu" private const val LOCKS = "locks" diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/TransformerUtil.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/js/TransformerUtil.kt similarity index 70% rename from plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/TransformerUtil.kt rename to plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/js/TransformerUtil.kt index a65b8a6743d..d521c048d52 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/TransformerUtil.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/js/TransformerUtil.kt @@ -1,9 +1,9 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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 +package org.jetbrains.kotlinx.atomicfu.compiler.backend.js import org.jetbrains.kotlin.backend.common.extensions.* import org.jetbrains.kotlin.descriptors.* @@ -61,7 +61,7 @@ internal fun buildCall( internal fun IrFactory.buildBlockBody(statements: List) = createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET, statements) -internal fun buildSetField( +internal fun IrPluginContext.buildSetField( symbol: IrFieldSymbol, receiver: IrExpression?, value: IrExpression, @@ -73,7 +73,7 @@ internal fun buildSetField( symbol, receiver, value, - value.type, + irBuiltIns.unitType, IrStatementOrigin.GET_PROPERTY, superQualifierSymbol ) @@ -94,7 +94,7 @@ internal fun buildGetField( superQualifierSymbol ) -internal fun buildFunctionSimpleType( +internal fun buildSimpleType( symbol: IrClassifierSymbol, typeParameters: List ): IrSimpleType = @@ -124,9 +124,6 @@ internal fun IrExpression.isConstNull() = this is IrConst<*> && this.kind.asStri internal fun IrField.getterName() = "" internal fun IrField.setterName() = "" -internal fun String.getFieldName() = "".toRegex().find(this)?.groupValues?.get(1) - ?: error("Getter name $this does not match special name pattern ") - internal fun IrFunctionAccessExpression.getValueArguments() = (0 until valueArgumentsCount).map { i -> getValueArgument(i) @@ -135,18 +132,18 @@ internal fun IrFunctionAccessExpression.getValueArguments() = internal fun IrValueParameter.capture() = buildGetValue(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol) internal fun IrPluginContext.buildGetterType(valueType: IrType): IrSimpleType = - buildFunctionSimpleType( + buildSimpleType( irBuiltIns.functionN(0).symbol, listOf(valueType) ) internal fun IrPluginContext.buildSetterType(valueType: IrType): IrSimpleType = - buildFunctionSimpleType( + buildSimpleType( irBuiltIns.functionN(1).symbol, listOf(valueType, irBuiltIns.unitType) ) -private fun buildSetField(backingField: IrField, ownerClass: IrExpression?, value: IrGetValue): IrSetField { +private fun IrPluginContext.buildSetField(backingField: IrField, ownerClass: IrExpression?, value: IrGetValue): IrSetField { val receiver = if (ownerClass is IrTypeOperatorCall) ownerClass.argument as IrGetValue else ownerClass return buildSetField( symbol = backingField.symbol, @@ -260,10 +257,6 @@ internal fun IrCall.getBackingField(): IrField = propertySymbol.owner.backingField ?: error("Property expected to have backing field") } ?: error("Atomic property accessor ${this.render()} expected to have non-null correspondingPropertySymbol") -internal fun IrCall.getCorrespondingProperty(): IrProperty = - symbol.owner.correspondingPropertySymbol?.owner - ?: error("Atomic property accessor ${this.render()} expected to have non-null correspondingPropertySymbol") - @OptIn(FirIncompatiblePluginAPI::class) internal fun IrPluginContext.referencePackageFunction( packageName: String, @@ -304,119 +297,6 @@ internal fun IrPluginContext.getArrayConstructorSymbol( } } -internal fun IrPluginContext.buildPropertyForBackingField( - field: IrField, - parent: IrDeclarationContainer, - visibility: DescriptorVisibility, - isStatic: Boolean -): IrProperty = - irFactory.buildProperty { - name = field.name - this.visibility = visibility // equal to the atomic property visibility - }.apply { - backingField = field - this.parent = parent - if (!isStatic) { - addDefaultGetter(this, field.parent as IrClass) - } else { - addStaticGetter(this) - } - parent.declarations.add(this) - } - -internal fun IrPluginContext.addDefaultGetter(property: IrProperty, parentClass: IrDeclarationContainer) { - val field = property.backingField!! - property.addGetter { - origin = IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR - visibility = property.visibility - returnType = field.type - }.apply { - dispatchReceiverParameter = if (parentClass is IrClass && parentClass.kind == ClassKind.OBJECT) { - null - } else { - (parentClass as? IrClass)?.thisReceiver?.deepCopyWithSymbols(this) - } - body = factory.createBlockBody( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf( - IrReturnImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - irBuiltIns.nothingType, - symbol, - IrGetFieldImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - field.symbol, - field.type, - dispatchReceiverParameter?.let { - IrGetValueImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - it.type, - it.symbol - ) - } - ) - ) - ) - ) - } -} - -internal fun IrPluginContext.addStaticGetter(property: IrProperty) { - val field = property.backingField!! - property.addGetter { - origin = IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR - visibility = property.visibility - returnType = field.type - }.apply { - dispatchReceiverParameter = null - body = factory.createBlockBody( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf( - IrReturnImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - irBuiltIns.nothingType, - symbol, - IrGetFieldImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - symbol = field.symbol, - type = field.type, - receiver = null - ) - ) - ) - ) - } -} - -internal fun IrPluginContext.buildClassInstance( - irClass: IrClass, - parent: IrDeclarationContainer, - visibility: DescriptorVisibility, - isStatic: Boolean -): IrProperty = - buildPropertyForBackingField( - field = buildClassInstanceField(irClass, parent), - parent = parent, - visibility = visibility, - isStatic = isStatic - ) - -private fun IrPluginContext.buildClassInstanceField(irClass: IrClass, parent: IrDeclarationContainer) = - // build a backing field for the wrapper class instance property - irFactory.buildField { - this.name = Name.identifier(irClass.name.asString().decapitalizeAsciiOnly()) - type = irClass.defaultType - isFinal = true - isStatic = true - visibility = DescriptorVisibilities.PRIVATE - }.apply { - initializer = IrExpressionBodyImpl( - IrConstructorCallImpl.fromSymbolOwner( - irClass.defaultType, - irClass.primaryConstructor!!.symbol - ) - ) - this.parent = parent - } - private fun IrSimpleType.getArrayClassFqName(): FqName = classifier.signature?.let { signature -> signature.getDeclarationNameBySignature().let { name -> @@ -430,4 +310,3 @@ internal fun IdSignature.getDeclarationNameBySignature(): String? { val commonSignature = if (this is IdSignature.AccessorSignature) accessorSignature else asPublic() return commonSignature?.declarationFqName } - 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 caec0958df4..2dfe9973a91 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 @@ -6,464 +6,233 @@ package org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm import org.jetbrains.kotlin.backend.common.extensions.* -import org.jetbrains.kotlin.backend.common.lower.parents -import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.ir.* +import org.jetbrains.kotlin.ir.backend.js.utils.valueArguments 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.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.name.* -import org.jetbrains.kotlin.util.capitalizeDecapitalize.* -import org.jetbrains.kotlinx.atomicfu.compiler.backend.* +import org.jetbrains.kotlinx.atomicfu.compiler.backend.common.AbstractAtomicSymbols +import org.jetbrains.kotlinx.atomicfu.compiler.backend.common.AbstractAtomicfuTransformer import kotlin.collections.set -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 DISPATCH_RECEIVER = "dispatchReceiver\$$ATOMICFU" +private const val ATOMIC_HANDLER = "handler\$$ATOMICFU" +private const val ACTION = "action\$$ATOMICFU" +private const val INDEX = "index\$$ATOMICFU" private const val LOOP = "loop" private const val UPDATE = "update" class AtomicfuJvmIrTransformer( - private val context: IrPluginContext, - private val atomicSymbols: AtomicSymbols -) { - private val irBuiltIns = context.irBuiltIns + pluginContext: IrPluginContext, + override val atomicSymbols: JvmAtomicSymbols +) : AbstractAtomicfuTransformer(pluginContext) { - private val AFU_VALUE_TYPES: Map = mapOf( - "AtomicInt" to irBuiltIns.intType, - "AtomicLong" to irBuiltIns.longType, - "AtomicBoolean" to irBuiltIns.booleanType, - "AtomicRef" to irBuiltIns.anyNType - ) + override val atomicPropertiesTransformer: AtomicPropertiesTransformer + get() = JvmAtomicPropertiesTransformer() - private val ATOMICFU_INLINE_FUNCTIONS = setOf("loop", "update", "getAndUpdate", "updateAndGet") - protected val ATOMIC_VALUE_TYPES = setOf("AtomicInt", "AtomicLong", "AtomicBoolean", "AtomicRef") - protected val ATOMIC_ARRAY_TYPES = setOf("AtomicIntArray", "AtomicLongArray", "AtomicBooleanArray", "AtomicArray") + override val atomicExtensionsTransformer: AtomicExtensionTransformer + get() = JvmAtomicExtensionTransformer() - fun transform(moduleFragment: IrModuleFragment) { - transformAtomicFields(moduleFragment) - transformAtomicExtensions(moduleFragment) - transformAtomicfuDeclarations(moduleFragment) - for (irFile in moduleFragment.files) { - irFile.patchDeclarationParents() - } - } + override val atomicFunctionsTransformer: AtomicFunctionCallTransformer + get() = JvmAtomicFunctionCallTransformer() - private fun transformAtomicFields(moduleFragment: IrModuleFragment) { - for (irFile in moduleFragment.files) { - irFile.transform(AtomicHandlerTransformer(), null) - } - } + private inner class JvmAtomicPropertiesTransformer : AtomicPropertiesTransformer() { - private fun transformAtomicExtensions(moduleFragment: IrModuleFragment) { - for (irFile in moduleFragment.files) { - irFile.transform(AtomicExtensionTransformer(), null) - } - } - - private fun transformAtomicfuDeclarations(moduleFragment: IrModuleFragment) { - for (irFile in moduleFragment.files) { - irFile.transform(AtomicfuTransformer(), null) - } - } - - private val propertyToAtomicHandler = mutableMapOf() - - private inner class AtomicHandlerTransformer : IrElementTransformer { - override fun visitClass(declaration: IrClass, data: IrFunction?): IrStatement { - declaration.declarations.filter(::fromKotlinxAtomicfu).forEach { - (it as IrProperty).transformAtomicfuProperty(declaration) - } - return super.visitClass(declaration, data) + override fun IrClass.addTransformedInClassAtomic(atomicProperty: IrProperty, index: Int): IrProperty { + /** + * Atomic property is replaced with the private volatile field that is atomically updated via + * java.util.concurrent.Atomic*FieldUpdater class. + * Volatile field is private and the atomic updater has the minimal visibility level + * among the visibility of the atomic property and the visibility of the containing class. + * + * private val a = atomic(0) --> private @Volatile var a: Int = 0 + * private static val a$FU = AtomicIntegerFieldUpdater.newUpdater(parentClass, "a") + */ + return addVolatilePropertyWithAtomicUpdater(atomicProperty, index) } - override fun visitFile(declaration: IrFile, data: IrFunction?): IrFile { - declaration.declarations.filter(::fromKotlinxAtomicfu).forEach { - (it as IrProperty).transformAtomicfuProperty(declaration) - } - return super.visitFile(declaration, data) + override fun IrDeclarationContainer.addTransformedStaticAtomic(atomicProperty: IrProperty, index: Int): IrProperty { + /** + * Atomic property is replaced with the private volatile field that is atomically updated via + * java.util.concurrent.Atomic*FieldUpdater class. Atomic*FieldUpdater can only update a field that is a member of a class. + * For this reason, all volatile fields are placed inside the generated `VolatileWrapper` class. + * VolatileWrapper class and it's instance have the minimal visibility level + * among the visibility of the atomic property and the visibility of the containing object (if the atomic property is member of the object). + * + * One wrapper class contains all properties of the same visibility, e.g.: + * + * internal class AVolatileWrapper$internal { + * private @Volatile var a: Int = 0 + * + * companion object { + * internal static val a$FU = AtomicIntegerFieldUpdater.newUpdater(AVolatileWrapper::class, "a") + * } + * } + * internal val wrapperClassInstance = AVolatileWrapper$internal() + */ + val wrapperClass = getOrBuildVolatileWrapper(atomicProperty) + return wrapperClass.addVolatilePropertyWithAtomicUpdater(atomicProperty, index) } - private fun IrProperty.transformAtomicfuProperty(parent: IrDeclarationContainer) { - val atomicfuProperty = this - val isTopLevel = parent is IrFile || (parent is IrClass && parent.kind == ClassKind.OBJECT) - when { - isAtomic() -> { - if (isTopLevel) { - val wrapperClass = buildWrapperClass(atomicfuProperty, parent).also { - // add a static instance of the generated wrapper class to the parent container - context.buildClassInstance(it, parent, atomicfuProperty.visibility, true) - } - transformAtomicProperty(wrapperClass) - moveFromFileToClass(parent, wrapperClass) - } else { - transformAtomicProperty(parent as IrClass) - } - } - isDelegatedToAtomic() -> transformDelegatedProperty(parent) - isAtomicArray() -> transformAtomicArrayProperty(parent) - isTrace() -> parent.declarations.remove(atomicfuProperty) - else -> {} - } - } - - private fun IrProperty.moveFromFileToClass( - parentFile: IrDeclarationContainer, - parentClass: IrClass - ) { - parentFile.declarations.remove(this) - parentClass.declarations.add(this) - parent = parentClass - } - - private fun IrProperty.transformAtomicProperty(parentClass: IrClass) { - // Atomic property transformation: - // 1. replace it's backingField with a volatile property of atomic value type - // 2. create j.u.c.a.Atomic*FieldUpdater for this volatile property to handle it's value atomically - // val a = atomic(0) -> - // volatile var a: Int = 0 - // val a$FU = AtomicIntegerFieldUpdater.newUpdater(parentClass, "a") - // - // Top-level atomic properties transformation: - // 1. replace it's backingField with a volatile property of atomic value type - // 2. wrap this volatile property into the generated class - // 3. create j.u.c.a.Atomic*FieldUpdater for the volatile property to handle it's value atomically - // val a = atomic(0) -> - // class A$ParentFile$VolatileWrapper { volatile var a: Int = 0 } - // val a$FU = AtomicIntegerFieldUpdater.newUpdater(A$ParentFile$VolatileWrapper::class, "a") - backingField = buildVolatileRawField(this, parentClass) - // update property accessors - context.addDefaultGetter(this, parentClass) - val fieldUpdater = addJucaAFUProperty(this, parentClass) - registerAtomicHandler(fieldUpdater) - } - - private fun IrProperty.transformAtomicArrayProperty(parent: IrDeclarationContainer) { - // Replace atomicfu array classes with the corresponding atomic arrays from j.u.c.a.: - // val intArr = atomicArrayOfNulls(5) -> - // val intArr = AtomicReferenceArray(5) - backingField = buildJucaArrayField(this, parent) - // update property accessors - context.addDefaultGetter(this, parent) - registerAtomicHandler(this) - } - - private fun IrProperty.transformDelegatedProperty(parent: IrDeclarationContainer) { - backingField?.let { - it.initializer?.let { - val initializer = it.expression as IrCall - if (initializer.isAtomicFactory()) { - // Property delegated to atomic factory invocation: - // 1. replace it's backingField with a volatile property of value type - // 2. transform getter/setter - // var a by atomic(0) -> - // volatile var a: Int = 0 - val volatileField = buildVolatileRawField(this, parent).also { - parent.declarations.add(it) - } - backingField = null - getter?.transformAccessor(volatileField, getter?.dispatchReceiverParameter?.capture()) - setter?.transformAccessor(volatileField, setter?.dispatchReceiverParameter?.capture()) - } else { - // Property delegated to the atomic property: - // 1. delegate it's accessors to get/set of the backingField of the atomic delegate - // (that is already transformed to a volatile field of value type) - // val _a = atomic(0) - // var a by _a -> - // volatile var _a: Int = 0 - // var a by _a - val atomicProperty = initializer.getCorrespondingProperty() - val volatileField = atomicProperty.backingField!! - backingField = null - if (atomicProperty.isTopLevel()) { - with(atomicSymbols.createBuilder(symbol)) { - val wrapper = getStaticVolatileWrapperInstance(atomicProperty) - getter?.transformAccessor(volatileField, getProperty(wrapper, null)) - setter?.transformAccessor(volatileField, getProperty(wrapper, null)) - } - } else { - if (this.parent == atomicProperty.parent) { - //class A { - // val _a = atomic() - // var a by _a - //} - getter?.transformAccessor(volatileField, getter?.dispatchReceiverParameter?.capture()) - setter?.transformAccessor(volatileField, setter?.dispatchReceiverParameter?.capture()) - } else { - //class A { - // val _a = atomic() - // inner class B { - // var a by _a - // } - //} - val thisReceiver = atomicProperty.parentAsClass.thisReceiver - getter?.transformAccessor(volatileField, thisReceiver?.capture()) - setter?.transformAccessor(volatileField, thisReceiver?.capture()) - } - } - } + override fun IrDeclarationContainer.addTransformedAtomicArray(atomicProperty: IrProperty, index: Int): IrProperty { + /** + * Atomic arrays are replaced with corresponding java.util.concurrent.Atomic*Array: + * + * val intArr = kotlinx.atomicfu.AtomicIntArray(45) --> val intArr = java.util.concurrent.AtomicIntegerArray(45) + */ + val parentContainer = this + with(atomicSymbols.createBuilder(atomicProperty.symbol)) { + val javaAtomicArrayField = buildJavaAtomicArrayField(atomicProperty, parentContainer) + return parentContainer.replacePropertyAtIndex( + javaAtomicArrayField, + atomicProperty.visibility, + isVar = false, + isStatic = parentContainer is IrFile, + index + ).also { + propertyToAtomicHandler[atomicProperty] = it } } } - private fun IrFunction.transformAccessor(volatileField: IrField, parent: IrExpression?) { - val accessor = this - with(atomicSymbols.createBuilder(symbol)) { - body = irExprBody( - irReturn( - if (accessor.isGetter) { - irGetField(parent, volatileField) - } else { - irSetField(parent, volatileField, accessor.valueParameters[0].capture()) - } - ) + private fun IrClass.addVolatilePropertyWithAtomicUpdater(from: IrProperty, index: Int): IrProperty { + /** + * Generates a volatile property and an atomic updater for this property, + * adds both to the parent class and returns the volatile property. + */ + val parentClass = this + with(atomicSymbols.createBuilder(from.symbol)) { + /** + * Property initialization order matters, + * the new volatile property should be inserted in parent declarations in place of the original property. + * Consider the case when the transformed property is added to the end of parent.declarations: + * + * class A { class A { + * private val _a = atomic(5) // _a is removed + * init { ---> init { + * assertEquals(5, _a.value) assertEquals(5, _a$volatile$FU.get(this)) // FAILS, _a$volatile$FU.get(this) == 0 + * } } + * // transformed volatile property + updater are added to the end of class declarations -> + * // wrong order of initialization + * @Volatile var _a$volatile = 5 + * companion object { + * val _a$volatile$FU = AtomicIntegerFieldUpdater.newUpdater(A::class.java, "_a$volatile") + * } + * } } + */ + val volatileField = buildVolatileBackingField(from, parentClass, true) + val volatileProperty = if (volatileField.parent == from.parent) { + // The index is relevant only if the property belongs to the same class as the original atomic property (not the generated wrapper). + parentClass.replacePropertyAtIndex(volatileField, DescriptorVisibilities.PRIVATE, isVar = true, isStatic = false, index) + } else { + parentClass.addProperty(volatileField, DescriptorVisibilities.PRIVATE, isVar = true, isStatic = false) + } + atomicPropertyToVolatile[from] = volatileProperty + val atomicUpdaterField = irJavaAtomicFieldUpdater(volatileField, parentClass) + parentClass.addProperty(atomicUpdaterField, from.getMinVisibility(), isVar = false, isStatic = true).also { + propertyToAtomicHandler[from] = it + } + return volatileProperty + } + } + + private fun JvmAtomicfuIrBuilder.buildJavaAtomicArrayField( + atomicProperty: IrProperty, + parentContainer: IrDeclarationContainer + ): IrField { + val atomicArrayField = + requireNotNull(atomicProperty.backingField) { "BackingField of atomic array $atomicProperty should not be null" } + val initializer = atomicArrayField.initializer?.expression + if (initializer == null) { + // replace field initialization in the init block + val initBlock = atomicArrayField.getInitBlockForField(parentContainer) + // property initialization order in the init block matters -> transformed initializer should be placed at the same position + val initExprWithIndex = initBlock.getInitExprWithIndexFromInitBlock(atomicArrayField.symbol) + ?: error("Expected atomic array ${atomicProperty.render()} initialization in init block ${initBlock.render()}" + CONSTRAINTS_MESSAGE) + val atomicFactoryCall = initExprWithIndex.value.value + val initExprIndex = initExprWithIndex.index + val arraySize = atomicFactoryCall.getArraySizeArgument() + return irJavaAtomicArrayField( + atomicArrayField.name, + atomicSymbols.getAtomicArrayClassByAtomicfuArrayType(atomicArrayField.type), + atomicArrayField.isStatic, + atomicArrayField.annotations, + arraySize, + (atomicFactoryCall as IrFunctionAccessExpression).dispatchReceiver, + parentContainer + ).also { + val initExpr = it.initializer?.expression ?: error("Initializer of the generated field ${it.render()} can not be null" + CONSTRAINTS_MESSAGE) + it.initializer = null + initBlock.updateFieldInitialization(atomicArrayField.symbol, it.symbol, initExpr, initExprIndex) + } + } else { + val arraySize = initializer.getArraySizeArgument() + return irJavaAtomicArrayField( + atomicArrayField.name, + atomicSymbols.getAtomicArrayClassByAtomicfuArrayType(atomicArrayField.type), + atomicArrayField.isStatic, + atomicArrayField.annotations, + arraySize, + (initializer as IrFunctionAccessExpression).dispatchReceiver, + parentContainer ) } } - private fun IrProperty.registerAtomicHandler(atomicHandlerProperty: IrProperty) { - propertyToAtomicHandler[this] = atomicHandlerProperty - } - - private fun buildVolatileRawField(property: IrProperty, parent: IrDeclarationContainer): IrField = - // Generate a new backing field for the given property: - // a volatile variable of the atomic value type - // val a = atomic(0) - // volatile var a: Int = 0 - property.backingField?.let { backingField -> - val init = backingField.initializer?.expression - val valueType = backingField.type.atomicToValueType() - context.irFactory.buildField { - name = property.name - type = if (valueType.isBoolean()) irBuiltIns.intType else valueType - isFinal = false - isStatic = parent is IrFile - visibility = DescriptorVisibilities.PRIVATE - }.apply { - if (init != null) { - val value = (init as IrCall).getAtomicFactoryValueArgument() - initializer = IrExpressionBodyImpl(value) - } else { - // if lateinit field -> initialize it in IrAnonymousInitializer - transformLateInitializer(backingField, parent) { init -> - val value = (init as IrCall).getAtomicFactoryValueArgument() - with(atomicSymbols.createBuilder(this.symbol)) { - irSetField((parent as? IrClass)?.thisReceiver?.capture(), this@apply, value) - } - } - } - annotations = backingField.annotations + atomicSymbols.volatileAnnotationConstructorCall - this.parent = parent - } - } ?: error("Backing field of the atomic property ${property.render()} is null") - - private fun addJucaAFUProperty(atomicProperty: IrProperty, parentClass: IrClass): IrProperty = - // Generate an atomic field updater for the volatile backing field of the given property: - // val a = atomic(0) - // volatile var a: Int = 0 - // val a$FU = AtomicIntegerFieldUpdater.newUpdater(parentClass, "a") - atomicProperty.backingField?.let { volatileField -> - val fuClass = atomicSymbols.getJucaAFUClass(volatileField.type) - val fieldName = volatileField.name.asString() - val fuField = context.irFactory.buildField { - name = Name.identifier(mangleFUName(fieldName)) - type = fuClass.defaultType - isFinal = true - isStatic = true - visibility = DescriptorVisibilities.PRIVATE - }.apply { - initializer = IrExpressionBodyImpl( - with(atomicSymbols.createBuilder(symbol)) { - newUpdater(fuClass, parentClass, irBuiltIns.anyNType, fieldName) - } - ) - parent = parentClass - } - return context.buildPropertyForBackingField(fuField, parentClass, atomicProperty.visibility, true) - } ?: error("Atomic property ${atomicProperty.render()} should have a non-null generated volatile backingField") - - private fun buildJucaArrayField(atomicfuArrayProperty: IrProperty, parent: IrDeclarationContainer) = - atomicfuArrayProperty.backingField?.let { atomicfuArray -> - val init = atomicfuArray.initializer?.expression as? IrFunctionAccessExpression - val atomicArrayClass = atomicSymbols.getAtomicArrayClassByAtomicfuArrayType(atomicfuArray.type) - context.irFactory.buildField { - name = atomicfuArray.name - type = atomicArrayClass.defaultType - isFinal = atomicfuArray.isFinal - isStatic = atomicfuArray.isStatic - visibility = DescriptorVisibilities.PRIVATE - }.apply { - if (init != null) { - this.initializer = IrExpressionBodyImpl( - with(atomicSymbols.createBuilder(symbol)) { - val size = init.getArraySizeArgument() - newJucaAtomicArray(atomicArrayClass, size, init.dispatchReceiver) - } - ) - } else { - // if lateinit field -> initialize it in IrAnonymousInitializer - transformLateInitializer(atomicfuArray, parent) { init -> - init as IrFunctionAccessExpression - val size = init.getArraySizeArgument() - with(atomicSymbols.createBuilder(this.symbol)) { - irSetField( - (parent as? IrClass)?.thisReceiver?.capture(), - this@apply, - newJucaAtomicArray(atomicArrayClass, size, init.dispatchReceiver) - ) - } - } - } - annotations = atomicfuArray.annotations - this.parent = parent - } - } ?: error("Atomic property does not have backingField") - - private fun buildWrapperClass(atomicProperty: IrProperty, parentContainer: IrDeclarationContainer): IrClass = - atomicSymbols.buildClass( - FqName(getVolatileWrapperClassName(atomicProperty)), - ClassKind.CLASS, - parentContainer - ).apply { - val irClass = this - irClass.visibility = atomicProperty.visibility - addConstructor { - isPrimary = true - }.apply { - body = atomicSymbols.createBuilder(symbol).irBlockBody(startOffset, endOffset) { - +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single()) - +IrInstanceInitializerCallImpl(startOffset, endOffset, irClass.symbol, context.irBuiltIns.unitType) - } - this.visibility = DescriptorVisibilities.PRIVATE // constructor of the wrapper class should be private - } - } - - private fun transformLateInitializer( - field: IrField, - parent: IrDeclarationContainer, - generateIrSetField: (init: IrExpression) -> IrExpression - ) { - for (declaration in parent.declarations) { - if (declaration is IrAnonymousInitializer) { - declaration.body.statements.singleOrNull { - it is IrSetField && it.symbol == field.symbol - }?.let { - declaration.body.statements.remove(it) - val init = (it as IrSetField).value - declaration.body.statements.add( - generateIrSetField(init) - ) - } + private fun IrDeclarationContainer.getOrBuildVolatileWrapper(atomicProperty: IrProperty): IrClass { + val visibility = atomicProperty.getMinVisibility() + findDeclaration { it.isVolatileWrapper(visibility) && it.visibility == visibility }?.let { return it } + val parentContainer = this + return with(atomicSymbols.createBuilder((this as IrSymbolOwner).symbol)) { + irClassWithPrivateConstructor( + mangleVolatileWrapperClassName(parentContainer) + "\$${visibility.name}", + visibility, + parentContainer + ).also { + val wrapperInstance = buildClassInstance(it, parentContainer, true) + addProperty(wrapperInstance, atomicProperty.getMinVisibility(), isVar = false, isStatic = true) } } } - - private fun IrCall.getAtomicFactoryValueArgument() = - getValueArgument(0)?.deepCopyWithSymbols() - ?: error("Atomic factory should take at least one argument: ${this.render()}") - - private fun IrFunctionAccessExpression.getArraySizeArgument() = - getValueArgument(0)?.deepCopyWithSymbols() - ?: error("Atomic array constructor should take at least one argument: ${this.render()}") - - private fun fromKotlinxAtomicfu(declaration: IrDeclaration): Boolean = - declaration is IrProperty && - declaration.backingField?.type?.isKotlinxAtomicfuPackage() ?: false - - private fun IrProperty.isAtomic(): Boolean = - !isDelegated && backingField?.type?.isAtomicValueType() ?: false - - private fun IrProperty.isDelegatedToAtomic(): Boolean = - isDelegated && backingField?.type?.isAtomicValueType() ?: false - - private fun IrProperty.isAtomicArray(): Boolean = - backingField?.type?.isAtomicArrayType() ?: false - - private fun IrProperty.isTrace(): Boolean = - backingField?.type?.isTraceBaseType() ?: false - - private fun IrProperty.isTopLevel(): Boolean = - parent is IrClass && (parent as IrClass).name.asString().endsWith(VOLATILE_WRAPPER_SUFFIX) - - private fun mangleFUName(fieldName: String) = "$fieldName\$FU" } - private inner class AtomicExtensionTransformer : IrElementTransformerVoid() { - override fun visitFile(declaration: IrFile): IrFile { - declaration.transformAllAtomicExtensions() - return super.visitFile(declaration) - } + private inner class JvmAtomicExtensionTransformer : AtomicExtensionTransformer() { - override fun visitClass(declaration: IrClass): IrStatement { - declaration.transformAllAtomicExtensions() - return super.visitClass(declaration) - } - - private fun IrDeclarationContainer.transformAllAtomicExtensions() { - // Transform the signature of kotlinx.atomicfu.Atomic* class extension functions: - // inline fun AtomicInt.foo(arg: T) - // For every signature there are 2 new declarations generated (because of different types of atomic handlers): - // 1. for the case of atomic value receiver at the invocation: - // inline fun foo$atomicfu(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, arg': T) - // 2. for the case of atomic array element receiver at the invocation: - // inline fun foo$atomicfu$array(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerArray, index: Int, arg': T) + override fun IrDeclarationContainer.transformAllAtomicExtensions() { declarations.filter { it is IrFunction && it.isAtomicExtension() }.forEach { atomicExtension -> atomicExtension as IrFunction - declarations.add(generateAtomicExtension(atomicExtension, this, false)) - declarations.add(generateAtomicExtension(atomicExtension, this, true)) + declarations.add(transformAtomicExtension(atomicExtension, this, false)) + declarations.add(transformAtomicExtension(atomicExtension, this, true)) + // the original atomic extension is removed declarations.remove(atomicExtension) } } - private fun generateAtomicExtension( - atomicExtension: IrFunction, - parent: IrDeclarationParent, - isArrayReceiver: Boolean - ): IrFunction { - val mangledName = mangleFunctionName(atomicExtension.name.asString(), isArrayReceiver) - val valueType = atomicExtension.extensionReceiverParameter!!.type.atomicToValueType() - return context.irFactory.buildFun { - name = Name.identifier(mangledName) - isInline = true - visibility = atomicExtension.visibility - }.apply { - val newDeclaration = this - extensionReceiverParameter = null - dispatchReceiverParameter = atomicExtension.dispatchReceiverParameter?.deepCopyWithSymbols(this) - if (isArrayReceiver) { - addValueParameter(DISPATCH_RECEIVER, irBuiltIns.anyNType) - addValueParameter(ATOMIC_HANDLER, atomicSymbols.getAtomicArrayClassByValueType(valueType).defaultType) - addValueParameter(INDEX, irBuiltIns.intType) - } else { - addValueParameter(DISPATCH_RECEIVER, irBuiltIns.anyNType) - addValueParameter(ATOMIC_HANDLER, atomicSymbols.getFieldUpdaterType(valueType)) - } - atomicExtension.valueParameters.forEach { addValueParameter(it.name, it.type) } + private fun transformAtomicExtension(atomicExtension: IrFunction, parent: IrDeclarationContainer, isArrayReceiver: Boolean): IrFunction { + /** + * At this step, only signature of the atomic extension is changed, + * the body is just copied and will be transformed at the next step by JvmAtomicFunctionCallTransformer. + * + * Two different signatures are generated for the case of atomic property receiver + * and for the case of atomic array element receiver, due to different atomic updaters. + * + * inline fun AtomicInt.foo(arg: Int) --> inline fun foo$atomicfu(dispatchReceiver: Any?, atomicHandler: AtomicIntegerFieldUpdater, arg': Int) + * inline fun foo$atomicfu$array(dispatchReceiver: Any?, atomicHandler: AtomicIntegerArray, index: Int, arg': Int) + */ + return buildTransformedAtomicExtensionDeclaration(atomicExtension, isArrayReceiver).apply { // the body will be transformed later by `AtomicFUTransformer` body = atomicExtension.body?.deepCopyWithSymbols(this) body?.transform( object : IrElementTransformerVoid() { override fun visitReturn(expression: IrReturn): IrExpression = super.visitReturn( if (expression.returnTargetSymbol == atomicExtension.symbol) { - with(atomicSymbols.createBuilder(newDeclaration.symbol)) { + with(atomicSymbols.createBuilder(this@apply.symbol)) { irReturn(expression.value) } } else { @@ -472,258 +241,291 @@ class AtomicfuJvmIrTransformer( ) }, null ) - returnType = atomicExtension.returnType this.parent = parent } } } - private data class AtomicFieldInfo(val dispatchReceiver: IrExpression?, val atomicHandler: IrExpression) + private inner class JvmAtomicFunctionCallTransformer : AtomicFunctionCallTransformer() { - private inner class AtomicfuTransformer : IrElementTransformer { - override fun visitFunction(declaration: IrFunction, data: IrFunction?): IrStatement { - return super.visitFunction(declaration, declaration) - } - - 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()) { - val valueType = if (it is IrTypeOperatorCallImpl) { - // If receiverExpression is a cast `s as AtomicRef` - // then valueType is the type argument of Atomic* class `String` - (it.type as IrSimpleType).arguments[0] as IrSimpleType - } else { - receiver.type.atomicToValueType() - } - getAtomicFieldInfo(receiver, data)?.let { (dispatchReceiver, atomicHandler) -> - val isArrayReceiver = atomicSymbols.isAtomicArrayHandlerType(atomicHandler.type) - if (expression.symbol.isKotlinxAtomicfuPackage()) { - // Transform invocations of atomic functions, delegating them to the atomicHandler. - // 1. For atomic properties (j.u.c.a.Atomic*FieldUpdater): - // a.compareAndSet(expect, update) -> a$FU.compareAndSet(dispatchReceiver, expect, update) - // 2. For atomic array elements (j.u.c.a.Atomic*Array): - // intArr[0].compareAndSet(expect, update) -> intArr.compareAndSet(index, expect, update) - val functionName = expression.symbol.owner.name.asString() - if (functionName in ATOMICFU_INLINE_FUNCTIONS) { - // If the inline atomicfu loop function was invoked - // a.loop { value -> a.compareAndSet(value, 777) } - // then loop function is generated to replace this declaration. - // `AtomicInt.loop(action: (Int) -> Unit)` for example will be replaced with - // inline fun atomicfu$loop(atomicHandler: AtomicIntegerFieldUpdater, action: (Int) -> Unit) { - // while (true) { - // val cur = atomicfu$handler.get() - // atomicfu$action(cur) - // } - // } - // And the invocation in place will be transformed: - // a.atomicfu$loop(atomicHandler, action) - require(data != null) { "Function containing loop invocation ${expression.render()} is null" } - val loopFunc = data.parentDeclarationContainer.getOrBuildInlineLoopFunction( - functionName = functionName, - valueType = if (valueType.isBoolean()) irBuiltIns.intType else valueType, - isArrayReceiver = isArrayReceiver - ) - val action = (expression.getValueArgument(0) as IrFunctionExpression).apply { - function.body?.transform(this@AtomicfuTransformer, data) - if (function.valueParameters[0].type.isBoolean()) { - function.valueParameters[0].type = irBuiltIns.intType - function.returnType = irBuiltIns.intType - } - } - val loopCall = irCallWithArgs( - symbol = loopFunc.symbol, - dispatchReceiver = data.containingFunction.dispatchReceiverParameter?.capture(), - valueArguments = if (isArrayReceiver) { - val index = receiver.getArrayElementIndex(data) - listOf(atomicHandler, index, action) - } else { - listOf(atomicHandler, action, dispatchReceiver) - } - ) - return super.visitCall(loopCall, data) - } - val irCall = if (isArrayReceiver) { - callAtomicArray( - arrayClassSymbol = atomicHandler.type.classOrNull!!, - functionName = functionName, - dispatchReceiver = atomicHandler, - index = receiver.getArrayElementIndex(data), - valueArguments = expression.getValueArguments(), - isBooleanReceiver = valueType.isBoolean() - ) - } else { - callFieldUpdater( - fieldUpdaterSymbol = atomicSymbols.getJucaAFUClass(valueType), - functionName = functionName, - dispatchReceiver = atomicHandler, - obj = dispatchReceiver, - valueArguments = expression.getValueArguments(), - castType = if (it is IrTypeOperatorCall) valueType else null, - isBooleanReceiver = valueType.isBoolean() - ) - } - return super.visitExpression(irCall, data) - } - if (expression.symbol.owner.isInline && expression.extensionReceiver != null) { - // Transform invocation of the kotlinx.atomicfu.Atomic* class extension functions, - // delegating them to the corresponding transformed atomic extensions: - // for atomic property recevers: - // inline fun foo$atomicfu(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, arg': Int) { ... } - // for atomic array element receivers: - // inline fun foo$atomicfu$array(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerArray, index: Int, arg': Int) { ... } - - // The invocation on the atomic property will be transformed: - // a.foo(arg) -> a.foo$atomicfu(dispatchReceiver, atomicHandler, arg) - // The invocation on the atomic array element will be transformed: - // a.foo(arg) -> a.foo$atomicfu$array(dispatchReceiver, atomicHandler, index, arg) - val declaration = expression.symbol.owner - val parent = declaration.parent as IrDeclarationContainer - val transformedAtomicExtension = parent.getTransformedAtomicExtension(declaration, isArrayReceiver) - require(data != null) { "Function containing invocation of the extension function ${expression.render()} is null" } - val irCall = callAtomicExtension( - symbol = transformedAtomicExtension.symbol, - dispatchReceiver = expression.dispatchReceiver, - syntheticValueArguments = if (isArrayReceiver) { - listOf(dispatchReceiver, atomicHandler, receiver.getArrayElementIndex(data)) - } else { - listOf(dispatchReceiver, atomicHandler) - }, - valueArguments = expression.getValueArguments() - ) - return super.visitCall(irCall, data) - } - } ?: return expression - } - } - } - return super.visitCall(expression, data) - } - - override fun visitGetValue(expression: IrGetValue, data: IrFunction?): IrExpression { - // For transformed atomic extension functions - // replace old value parameters with the new parameters of the transformed declaration: - // inline fun foo$atomicfu(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, arg': Int) { - // arg -> arg` - //} - if (expression.symbol is IrValueParameterSymbol) { - val valueParameter = expression.symbol.owner as IrValueParameter - val parent = valueParameter.parent - if (data != null && data.isTransformedAtomicExtension() && - parent is IrFunctionImpl && !parent.isTransformedAtomicExtension() && - parent.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA - ) { - val index = valueParameter.index - if (index < 0 && !valueParameter.type.isAtomicValueType()) { - // index == -1 for `this` parameter - return data.dispatchReceiverParameter?.capture() ?: error { "Dispatchreceiver of ${data.render()} is null" } - } - if (index >= 0) { - val shift = if (data.name.asString().endsWith(ATOMIC_ARRAY_RECEIVER_SUFFIX)) 3 else 2 - val transformedValueParameter = data.valueParameters[index + shift] - return buildGetValue( - expression.startOffset, - expression.endOffset, - transformedValueParameter.symbol - ) - } - } - } - return super.visitGetValue(expression, data) - } - - override fun visitBlockBody(body: IrBlockBody, data: IrFunction?): IrBody { - // Erase messages added by the Trace object from the function body: - // val trace = Trace(size) - // Messages may be added via trace invocation: - // trace { "Doing something" } - // or via multi-append of arguments: - // trace.append(index, "CAS", value) - body.statements.removeIf { - it.isTraceCall() - } - return super.visitBlockBody(body, data) - } - - override fun visitContainerExpression(expression: IrContainerExpression, data: IrFunction?): IrExpression { - // Erase messages added by the Trace object from blocks. - expression.statements.removeIf { - it.isTraceCall() - } - return super.visitContainerExpression(expression, data) - } - - private fun AtomicfuIrBuilder.getAtomicFieldInfo( - receiver: IrExpression, + override fun transformAtomicUpdateCallOnProperty( + expression: IrCall, + functionName: String, + valueType: IrType, + castType: IrType?, + getPropertyReceiver: IrExpression, parentFunction: IrFunction? - ): AtomicFieldInfo? { - // For the given function call receiver of atomic type returns: - // the dispatchReceiver and the atomic handler of the corresponding property - when { - receiver is IrCall -> { - // Receiver is a property getter call - val isArrayReceiver = receiver.isArrayElementGetter() - val getAtomicProperty = if (isArrayReceiver) receiver.dispatchReceiver as IrCall else receiver - val atomicProperty = getAtomicProperty.getCorrespondingProperty() - val dispatchReceiver = getAtomicProperty.dispatchReceiver.let { - val isObjectReceiver = it?.type?.classOrNull?.owner?.kind == ClassKind.OBJECT - if (it == null || isObjectReceiver) { - if (getAtomicProperty.symbol.owner.returnType.isAtomicValueType()) { - // for top-level atomic properties get wrapper class instance as a parent - getProperty(getStaticVolatileWrapperInstance(atomicProperty), null) - } else if (isObjectReceiver && getAtomicProperty.symbol.owner.returnType.isAtomicArrayType()) { - it - } - else null - } else it + ): IrExpression { + with(atomicSymbols.createBuilder(expression.symbol)) { + /** + * Atomic update call on the atomic property is replaced + * with the call on the AtomicFieldUpdater field: + * + * 1. Function call receiver is atomic property getter call. + * + * The call is replaced with the call on the corresponding field updater: + * + * val a = atomic(0) @Volatile var a$volatile = 0 + * ().compareAndSet(0, 5) ---> a$volatile$FU.compareAndSetField(dispatchReceiver, 0, 5) + * + * + * 2. Function is called in the body of the transformed atomic extension, + * the call receiver is the old receiver of the extension: + * + * inline fun AtomicInt.foo(new: Int) { inline fun foo$atomicfu(dispatchReceiver: Any?, atomicHandler: AtomicIntegerFieldUpdater, new: Int) { + * this.compareAndSet(value, new) ---> atomicHandler.compareAndSet(dispatchReceiver, atomicHandler.get(dispatchReceiver), new) + * } } + */ + return callFieldUpdater( + fieldUpdaterSymbol = atomicSymbols.getJucaAFUClass(valueType), + functionName = functionName, + getAtomicHandler = getAtomicHandler(getPropertyReceiver, parentFunction), + classInstanceContainingField = getDispatchReceiver(getPropertyReceiver, parentFunction), + valueArguments = expression.valueArguments, + castType = castType, + isBooleanReceiver = valueType.isBoolean() + ) + } + } + + override fun transformAtomicUpdateCallOnArrayElement( + expression: IrCall, + functionName: String, + valueType: IrType, + getPropertyReceiver: IrExpression, + parentFunction: IrFunction? + ): IrCall { + with(atomicSymbols.createBuilder(expression.symbol)) { + /** + * Atomic update call on the atomic array element is replaced + * with the call on the j.u.c.a.Atomic*Array field: + * + * 1. Function call receiver is atomic property getter call. + * + * The call is replaced with the call on the corresponding field updater: + * + * val intArr = AtomicIntArray(10) val intArr = AtomicIntegerArray(10) + * ()[5].compareAndSet(0, 5) ---> intArr.compareAndSet(5, 0, 5) + * + * + * 2. Function is called in the body of the transformed atomic extension, + * the call receiver is the old receiver of the extension: + * + * inline fun AtomicInt.foo(new: Int) { inline fun foo$atomicfu$array(dispatchReceiver: Any?, atomicHandler: AtomicIntegerArray, index: Int, arg': Int) + * this.getAndSet(value, new) ---> atomicHandler.getAndSet(index, new) + * } } + */ + val getJavaAtomicArray = getAtomicHandler(getPropertyReceiver, parentFunction) + return callAtomicArray( + arrayClassSymbol = getJavaAtomicArray.type.classOrNull!!, + functionName = functionName, + dispatchReceiver = getJavaAtomicArray, + index = getPropertyReceiver.getArrayElementIndex(parentFunction), + valueArguments = expression.valueArguments, + isBooleanReceiver = valueType.isBoolean() + ) + } + } + + override fun transformedAtomicfuInlineFunctionCall( + expression: IrCall, + functionName: String, + valueType: IrType, + getPropertyReceiver: IrExpression, + isArrayReceiver: Boolean, + parentFunction: IrFunction? + ): IrCall { + with(atomicSymbols.createBuilder(expression.symbol)) { + val dispatchReceiver = getDispatchReceiver(getPropertyReceiver, parentFunction) + val getAtomicHandler = getAtomicHandler(getPropertyReceiver, parentFunction) + /** + * a.loop { value -> a.compareAndSet(value, 777) } --> + * + * inline fun atomicfu$loop(atomicfu$handler: AtomicIntegerFieldUpdater, atomicfu$action: (Int) -> Unit, dispatchReceiver: Any?) { + * while (true) { + * val cur = atomicfu$handler.get() + * atomicfu$action(cur) + * } + * } + * + * a.atomicfu$loop(dispatchReceiver, atomicHandler) { ... } + */ + requireNotNull(parentFunction) { "Parent function of this call ${expression.render()} is null" + CONSTRAINTS_MESSAGE } + val loopFunc = parentFunction.parentDeclarationContainer.getOrBuildInlineLoopFunction( + functionName = functionName, + valueType = if (valueType.isBoolean()) irBuiltIns.intType else valueType, + isArrayReceiver = isArrayReceiver + ) + val action = (expression.getValueArgument(0) as IrFunctionExpression).apply { + function.body?.transform(this@JvmAtomicFunctionCallTransformer, parentFunction) + if (function.valueParameters[0].type.isBoolean()) { + function.valueParameters[0].type = irBuiltIns.intType + function.returnType = irBuiltIns.intType } - // atomic property is handled by the Atomic*FieldUpdater instance - // atomic array elements handled by the Atomic*Array instance - val atomicHandler = propertyToAtomicHandler[atomicProperty] - ?: error("No atomic handler found for the atomic property ${atomicProperty.render()}") - return AtomicFieldInfo( - dispatchReceiver = dispatchReceiver, - atomicHandler = getProperty( - atomicHandler, - if (isArrayReceiver && dispatchReceiver?.type?.classOrNull?.owner?.kind != ClassKind.OBJECT) dispatchReceiver else null - ) - ) + } + return irCallWithArgs( + symbol = loopFunc.symbol, + dispatchReceiver = parentFunction.containingFunction.dispatchReceiverParameter?.capture(), + extensionReceiver = null, + valueArguments = if (isArrayReceiver) { + val index = getPropertyReceiver.getArrayElementIndex(parentFunction) + listOf(getAtomicHandler, index, action) + } else { + listOf(getAtomicHandler, action, dispatchReceiver) + } + ) + } + } + + override fun transformAtomicExtensionCall( + expression: IrCall, + originalAtomicExtension: IrSimpleFunction, + getPropertyReceiver: IrExpression, + isArrayReceiver: Boolean, + parentFunction: IrFunction? + ): IrCall { + with(atomicSymbols.createBuilder(expression.symbol)) { + /** + * Atomic extension call is replaced with the call to transformed atomic extension: + * + * 1. Function call receiver is atomic property getter call. + * Transformation variant of the atomic extension is chosen accorfin to the type of receiver + * (atomic property -> foo$atomicfu, atomic array element -> foo$atomicfu$array) + * + * inline fun AtomicInt.foo(atg: Int) {..} + * aClass._a.foo(arg) --> foo$atomicfu(aClass, _a$volatile$FU, arg) + * + * + * 2. Function is called in the body of the transformed atomic extension, + * the call receiver is the old receiver of the extension. + * In this case value parameters captured from the parent function are passed as arguments. + * + * inline fun AtomicInt.bar(new: Int) inline fun bar$atomicfu(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, arg': Int) + * inline fun AtomicInt.foo(new: Int) { inline fun foo$atomicfu(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, arg': Int) + * bar(new) ---> bar$atomicfu(dispatchReceiver, handler, new) + * } } + */ + val parent = originalAtomicExtension.parent as IrDeclarationContainer + val transformedAtomicExtension = parent.getTransformedAtomicExtension(originalAtomicExtension, isArrayReceiver) + val dispatchReceiver = getDispatchReceiver(getPropertyReceiver, parentFunction) + val getAtomicHandler = getAtomicHandler(getPropertyReceiver, parentFunction) + return callAtomicExtension( + symbol = transformedAtomicExtension.symbol, + dispatchReceiver = expression.dispatchReceiver, + syntheticValueArguments = if (isArrayReceiver) { + listOf(dispatchReceiver, getAtomicHandler, getPropertyReceiver.getArrayElementIndex(parentFunction)) + } else { + listOf(dispatchReceiver, getAtomicHandler) + }, + valueArguments = expression.valueArguments + ) + } + } + + override fun IrDeclarationContainer.getTransformedAtomicExtension( + declaration: IrSimpleFunction, + isArrayReceiver: Boolean + ): IrSimpleFunction { + // Try find the transformed atomic extension in the parent container + findDeclaration { + it.name.asString() == mangleAtomicExtensionName(declaration.name.asString(), isArrayReceiver) && + it.isTransformedAtomicExtension() + }?.let { return it } + /** + * If the transformed declaration is not found then the call may be performed from another module + * which depends on the module where declarations are generated from untransformed metadata (real transformed declarations are not there). + * This happens if the call is performed from the test module or in case of incremental compilation. + * + * We build a fake declaration here: it's signature equals the one of the real transformed declaration, + * it doesn't have body and won't be generated. It is placed in the call site and + * during compilation this fake declaration will be resolved to the real transformed declaration. + */ + return buildTransformedAtomicExtensionDeclaration(declaration, isArrayReceiver) + } + + override fun IrFunction.isTransformedAtomicExtension(): Boolean { + val isArrayReceiver = name.asString().isMangledAtomicArrayExtension() + return if (isArrayReceiver) checkSyntheticArrayElementExtensionParameter() else checkSyntheticAtomicExtensionParameters() + } + + override fun IrValueParameter.remapValueParameter(transformedExtension: IrFunction): IrValueParameter? { + if (index < 0 && !type.isAtomicValueType()) { + // data is a transformed function + // index == -1 for `this` parameter + return transformedExtension.dispatchReceiverParameter ?: error("Dispatch receiver of ${transformedExtension.render()} is null" + CONSTRAINTS_MESSAGE) + } + if (index >= 0) { + val shift = if (transformedExtension.name.asString().isMangledAtomicArrayExtension()) 3 else 2 + return transformedExtension.valueParameters[index + shift] + } + return null + } + + override fun IrExpression.isArrayElementReceiver(parentFunction: IrFunction?): Boolean { + val receiver = this + return when { + receiver is IrCall -> { + receiver.isArrayElementGetter() } receiver.isThisReceiver() -> { - // Receiver is extension receiver of transformed atomic extesnion declaration. - // The old function before `AtomicExtensionTransformer` application: - // inline fun foo(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, arg': Int) { - // this().lazySet(arg) - //} - // By this moment the atomic extension has it's signature transformed, - // but still has the untransformed body copied from the old declaration: - // inline fun foo$atomicfu(dispatchReceiver: Any?, handler: j.u.c.a.AtomicIntegerFieldUpdater, arg': Int) { - // this().lazySet(arg) <---- - //} - // The dispatchReceiver and the atomic handler for this receiver are the corresponding arguments - // passed to the transformed declaration/ - return if (parentFunction != null && parentFunction.isTransformedAtomicExtension()) { - val params = parentFunction.valueParameters.take(2).map { it.capture() } - AtomicFieldInfo(params[0], params[1]) - } else null + if (parentFunction != null && parentFunction.isTransformedAtomicExtension()) { + val atomicHandler = parentFunction.valueParameters[1].capture() + atomicSymbols.isAtomicArrayHandlerType(atomicHandler.type) + } else false } - else -> error("Unsupported type of atomic receiver expression: ${receiver.render()}") + else -> false } } - private val IrDeclaration.parentDeclarationContainer: IrDeclarationContainer - get() = parents.filterIsInstance().firstOrNull() - ?: error("In the sequence of parents for ${this.render()} no IrDeclarationContainer was found") - - private val IrFunction.containingFunction: IrFunction - get() { - if (this.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) return this - return parents.filterIsInstance().firstOrNull { - it.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA - } ?: error("In the sequence of parents for the local function ${this.render()} no containing function was found") + private fun getDispatchReceiver(atomicCallReceiver: IrExpression, parentFunction: IrFunction?) = + when { + atomicCallReceiver is IrCall -> atomicCallReceiver.getDispatchReceiver() + atomicCallReceiver.isThisReceiver() -> { + if (parentFunction != null && parentFunction.isTransformedAtomicExtension()) { + parentFunction.valueParameters[0].capture() + } else null + } + else -> error("Unexpected type of atomic function call receiver: ${atomicCallReceiver.render()}" + CONSTRAINTS_MESSAGE) } + private fun getAtomicHandler(atomicCallReceiver: IrExpression, parentFunction: IrFunction?): IrExpression = + when { + atomicCallReceiver is IrCall -> { + val isArrayReceiver = atomicCallReceiver.isArrayElementGetter() + val getAtomicProperty = if (isArrayReceiver) atomicCallReceiver.dispatchReceiver as IrCall else atomicCallReceiver + val atomicProperty = getAtomicProperty.getCorrespondingProperty() + val atomicHandlerProperty = propertyToAtomicHandler[atomicProperty] + ?: error("No atomic handler found for the atomic property ${atomicProperty.render()}, \n" + + "these properties were registered: ${ + propertyToAtomicHandler.keys.toList().joinToString("\n") { it.render() } + }" + CONSTRAINTS_MESSAGE) + with(atomicSymbols.createBuilder(atomicCallReceiver.symbol)) { + // dispatchReceiver for get-a$FU() is null, because a$FU is a static property + // dispatchReceiver for get-arr'() is equal to the dispatchReceiver of the original getter + irGetProperty(atomicHandlerProperty, if (isArrayReceiver) getAtomicProperty.dispatchReceiver else null) + } + } + atomicCallReceiver.isThisReceiver() -> { + requireNotNull(parentFunction) { "Containing function of the atomic call with receiver should not be null" + CONSTRAINTS_MESSAGE} + require(parentFunction.isTransformedAtomicExtension()) + parentFunction.valueParameters[1].capture() + } + else -> error("Unexpected type of atomic function call receiver: ${atomicCallReceiver.render()} \n" + CONSTRAINTS_MESSAGE) + } + + private fun IrCall.getDispatchReceiver(): IrExpression? { + val isArrayReceiver = isArrayElementGetter() + val getAtomicProperty = if (isArrayReceiver) dispatchReceiver as IrCall else this + val atomicProperty = getAtomicProperty.getCorrespondingProperty() + val dispatchReceiver = getAtomicProperty.dispatchReceiver + // top-level atomics + if (!isArrayReceiver && (dispatchReceiver == null || dispatchReceiver.type.isObject())) { + val volatileProperty = atomicPropertyToVolatile[atomicProperty]!! + return getStaticVolatileWrapperInstance(volatileProperty.parentAsClass) + } + return dispatchReceiver + } + private fun IrExpression.getArrayElementIndex(parentFunction: IrFunction?): IrExpression = when { this is IrCall -> getValueArgument(0)!! @@ -731,17 +533,9 @@ class AtomicfuJvmIrTransformer( require(parentFunction != null) parentFunction.valueParameters[2].capture() } - else -> error("Unsupported type of atomic receiver expression: ${this.render()}") + else -> error("Unexpected type of atomic receiver expression: ${this.render()} \n" + CONSTRAINTS_MESSAGE) } - private fun IrExpression.isThisReceiver() = - this is IrGetValue && symbol.owner.name.asString() == "" - - private fun IrFunction.isTransformedAtomicExtension(): Boolean { - val isArrayReceiver = name.asString().endsWith(ATOMIC_ARRAY_RECEIVER_SUFFIX) - return if (isArrayReceiver) checkSyntheticArrayElementExtensionParameter() else checkSyntheticAtomicExtensionParameters() - } - private fun IrFunction.checkSyntheticArrayElementExtensionParameter(): Boolean { if (valueParameters.size < 3) return false return valueParameters[0].name.asString() == DISPATCH_RECEIVER && valueParameters[0].type == irBuiltIns.anyNType && @@ -761,39 +555,29 @@ class AtomicfuJvmIrTransformer( isArrayReceiver: Boolean ): IrSimpleFunction { val parent = this - val mangledName = mangleFunctionName(functionName, isArrayReceiver) + val mangledName = mangleAtomicExtensionName(functionName, isArrayReceiver) val updaterType = if (isArrayReceiver) atomicSymbols.getAtomicArrayType(valueType) else atomicSymbols.getFieldUpdaterType(valueType) findDeclaration { it.name.asString() == mangledName && it.valueParameters[0].type == updaterType }?.let { return it } - return context.irFactory.buildFun { + return pluginContext.irFactory.buildFun { name = Name.identifier(mangledName) isInline = true visibility = DescriptorVisibilities.PRIVATE + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_FUNCTION }.apply { dispatchReceiverParameter = (parent as? IrClass)?.thisReceiver?.deepCopyWithSymbols(this) if (functionName == LOOP) { if (isArrayReceiver) generateAtomicfuArrayLoop(valueType) else generateAtomicfuLoop(valueType) } else { - if (isArrayReceiver) generateAtomicfuArrayUpdate(functionName, valueType) else generateAtomicfuUpdate( - functionName, - valueType - ) + if (isArrayReceiver) generateAtomicfuArrayUpdate(functionName, valueType) else generateAtomicfuUpdate(functionName, valueType) } this.parent = parent parent.declarations.add(this) } } - private fun IrDeclarationContainer.getTransformedAtomicExtension( - declaration: IrSimpleFunction, - isArrayReceiver: Boolean - ): IrSimpleFunction = findDeclaration { - it.name.asString() == mangleFunctionName(declaration.name.asString(), isArrayReceiver) && - it.isTransformedAtomicExtension() - } ?: error("Could not find corresponding transformed declaration for the atomic extension ${declaration.render()}") - private fun IrSimpleFunction.generateAtomicfuLoop(valueType: IrType) { addValueParameter(ATOMIC_HANDLER, atomicSymbols.getFieldUpdaterType(valueType)) addValueParameter(ACTION, atomicSymbols.function1Type(valueType, irBuiltIns.unitType)) @@ -837,72 +621,28 @@ class AtomicfuJvmIrTransformer( } } - private fun getStaticVolatileWrapperInstance(atomicProperty: IrProperty): IrProperty { - val volatileWrapperClass = atomicProperty.parent as IrClass - return (volatileWrapperClass.parent as IrDeclarationContainer).declarations.singleOrNull { - it is IrProperty && it.backingField != null && - it.backingField!!.type.classOrNull == volatileWrapperClass.symbol - } as? IrProperty - ?: error("Static instance of ${volatileWrapperClass.name.asString()} is missing in ${volatileWrapperClass.parent}") + private fun buildTransformedAtomicExtensionDeclaration(atomicExtension: IrFunction, isArrayReceiver: Boolean): IrSimpleFunction { + val mangledName = mangleAtomicExtensionName(atomicExtension.name.asString(), isArrayReceiver) + val valueType = atomicExtension.extensionReceiverParameter!!.type.atomicToPrimitiveType() + return pluginContext.irFactory.buildFun { + name = Name.identifier(mangledName) + isInline = true + visibility = atomicExtension.visibility + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_FUNCTION + }.apply { + extensionReceiverParameter = null + dispatchReceiverParameter = atomicExtension.dispatchReceiverParameter?.deepCopyWithSymbols(this) + if (isArrayReceiver) { + addValueParameter(DISPATCH_RECEIVER, irBuiltIns.anyNType) + addValueParameter(ATOMIC_HANDLER, atomicSymbols.getAtomicArrayClassByValueType(valueType).defaultType) + addValueParameter(INDEX, irBuiltIns.intType) + } else { + addValueParameter(DISPATCH_RECEIVER, irBuiltIns.anyNType) + addValueParameter(ATOMIC_HANDLER, atomicSymbols.getFieldUpdaterType(valueType)) + } + atomicExtension.valueParameters.forEach { addValueParameter(it.name, it.type) } + returnType = atomicExtension.returnType + this.parent = atomicExtension.parent + } } - - private fun IrType.isKotlinxAtomicfuPackage() = - classFqName?.let { it.parent().asString() == AFU_PKG } ?: false - - private fun IrSimpleFunctionSymbol.isKotlinxAtomicfuPackage(): Boolean = - owner.parentClassOrNull?.classId?.let { - it.packageFqName.asString() == AFU_PKG - } ?: false - - private fun IrType.isAtomicValueType() = - classFqName?.let { - it.parent().asString() == AFU_PKG && it.shortName().asString() in ATOMIC_VALUE_TYPES - } ?: false - - private fun IrType.isAtomicArrayType() = - classFqName?.let { - it.parent().asString() == AFU_PKG && it.shortName().asString() in ATOMIC_ARRAY_TYPES - } ?: false - - private fun IrType.isTraceBaseType() = - classFqName?.let { - it.parent().asString() == AFU_PKG && it.shortName().asString() == TRACE_BASE_TYPE - } ?: false - - private fun IrCall.isArrayElementGetter(): Boolean = - dispatchReceiver?.let { - it.type.isAtomicArrayType() && symbol.owner.name.asString() == GET - } ?: 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 IrCall.isAtomicFactory(): Boolean = - symbol.isKotlinxAtomicfuPackage() && symbol.owner.name.asString() == ATOMIC_VALUE_FACTORY && - type.isAtomicValueType() - - private fun IrFunction.isAtomicExtension(): Boolean = - extensionReceiverParameter?.let { it.type.isAtomicValueType() && this.isInline } ?: false - - private fun IrStatement.isTraceCall() = this is IrCall && (isTraceInvoke() || isTraceAppend()) - - private fun IrCall.isTraceInvoke(): Boolean = - symbol.isKotlinxAtomicfuPackage() && - symbol.owner.name.asString() == INVOKE && - symbol.owner.dispatchReceiverParameter?.type?.isTraceBaseType() == true - - private fun IrCall.isTraceAppend(): Boolean = - symbol.isKotlinxAtomicfuPackage() && - symbol.owner.name.asString() == APPEND && - symbol.owner.dispatchReceiverParameter?.type?.isTraceBaseType() == true - - private fun getVolatileWrapperClassName(property: IrProperty) = - property.name.asString().capitalizeAsciiOnly() + '$' + - (if (property.parent is IrFile) (property.parent as IrFile).name else property.parent.kotlinFqName.asString()).substringBefore('.') + - VOLATILE_WRAPPER_SUFFIX - - private fun mangleFunctionName(name: String, isArrayReceiver: Boolean) = - if (isArrayReceiver) "$name$$ATOMICFU$ATOMIC_ARRAY_RECEIVER_SUFFIX" else "$name$$ATOMICFU" } diff --git a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicSymbols.kt b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/JvmAtomicSymbols.kt similarity index 90% rename from plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicSymbols.kt rename to plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/JvmAtomicSymbols.kt index a1791a83e23..7a92cf2ccda 100644 --- a/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/AtomicSymbols.kt +++ b/plugins/atomicfu/atomicfu-compiler/src/org/jetbrains/kotlinx/atomicfu/compiler/backend/jvm/JvmAtomicSymbols.kt @@ -5,27 +5,24 @@ package org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.builders.declarations.* 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.* +import org.jetbrains.kotlinx.atomicfu.compiler.backend.common.AbstractAtomicSymbols -// Contains IR declarations needed by the atomicfu plugin. -class AtomicSymbols( - val irBuiltIns: IrBuiltIns, - private val moduleFragment: IrModuleFragment -) { - private val irFactory: IrFactory = IrFactoryImpl +class JvmAtomicSymbols( + context: IrPluginContext, + moduleFragment: IrModuleFragment +): AbstractAtomicSymbols(context, moduleFragment) { private val javaLang: IrPackageFragment = createPackage("java.lang") private val javaUtilConcurrent: IrPackageFragment = createPackage("java.util.concurrent.atomic") private val kotlinJvm: IrPackageFragment = createPackage("kotlin.jvm") @@ -439,6 +436,9 @@ class AtomicSymbols( atomicRefFieldUpdaterClass ) + override fun createBuilder(symbol: IrSymbol, startOffset: Int, endOffset: Int) = + JvmAtomicfuIrBuilder(this, symbol, startOffset, endOffset) + fun getJucaAFUClass(valueType: IrType): IrClassSymbol = when { valueType.isInt() -> atomicIntFieldUpdaterClass @@ -503,19 +503,6 @@ class AtomicSymbols( UNDEFINED_OFFSET, UNDEFINED_OFFSET, irBuiltIns.kClassClass.starProjectedType, irBuiltIns.kClassClass, classType ) - fun function0Type(returnType: IrType) = buildFunctionSimpleType( - irBuiltIns.functionN(0).symbol, - listOf(returnType) - ) - - fun function1Type(argType: IrType, returnType: IrType) = buildFunctionSimpleType( - irBuiltIns.functionN(1).symbol, - listOf(argType, returnType) - ) - - val invoke0Symbol = irBuiltIns.functionN(0).getSimpleFunction("invoke")!! - val invoke1Symbol = irBuiltIns.functionN(1).getSimpleFunction("invoke")!! - private fun buildIrGet( type: IrType, receiver: IrExpression?, @@ -531,55 +518,7 @@ class AtomicSymbols( dispatchReceiver = receiver } - private val volatileConstructor = buildAnnotationConstructor(buildClass(JvmNames.VOLATILE_ANNOTATION_FQ_NAME, ClassKind.ANNOTATION_CLASS, kotlinJvm)) - val volatileAnnotationConstructorCall = - IrConstructorCallImpl.fromSymbolOwner(volatileConstructor.returnType, volatileConstructor.symbol) - - fun buildClass( - fqName: FqName, - classKind: ClassKind, - parent: IrDeclarationContainer - ): IrClass = irFactory.buildClass { - name = fqName.shortName() - kind = classKind - }.apply { - val irClass = this - this.parent = parent - parent.addChild(irClass) - thisReceiver = buildValueParameter(irClass) { - name = Name.identifier("\$this") - type = IrSimpleTypeImpl(irClass.symbol, false, emptyList(), emptyList()) - } - } - - private fun buildAnnotationConstructor(annotationClass: IrClass): IrConstructor = - annotationClass.addConstructor { isPrimary = true } - - private fun createPackage(packageName: String): IrPackageFragment = - IrExternalPackageFragmentImpl.createEmptyExternalPackageFragment( - moduleFragment.descriptor, - FqName(packageName) - ) - - private fun createClass( - irPackage: IrPackageFragment, - shortName: String, - classKind: ClassKind, - classModality: Modality, - isValueClass: Boolean = false, - ): IrClassSymbol = irFactory.buildClass { - name = Name.identifier(shortName) - kind = classKind - modality = classModality - isValue = isValueClass - }.apply { - parent = irPackage - createImplicitParameterDeclarationWithWrappedDescriptor() - }.symbol - - fun createBuilder( - symbol: IrSymbol, - startOffset: Int = UNDEFINED_OFFSET, - endOffset: Int = UNDEFINED_OFFSET - ) = AtomicfuIrBuilder(this, symbol, startOffset, endOffset) + override val volatileAnnotationClass: IrClass + get() = context.referenceClass(ClassId(FqName("kotlin.jvm"), Name.identifier("Volatile")))?.owner + ?: error("kotlin.jvm.Volatile class is not found") } 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/JvmAtomicfuIrBuilder.kt similarity index 81% 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/JvmAtomicfuIrBuilder.kt index aeda51c479e..9076d9858f3 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/JvmAtomicfuIrBuilder.kt @@ -5,25 +5,25 @@ package org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlinx.atomicfu.compiler.backend.common.AbstractAtomicSymbols +import org.jetbrains.kotlinx.atomicfu.compiler.backend.common.AbstractAtomicfuIrBuilder // An IR builder with access to AtomicSymbols and convenience methods to build IR constructions for atomicfu JVM/IR transformation. -class AtomicfuIrBuilder internal constructor( - val atomicSymbols: AtomicSymbols, +class JvmAtomicfuIrBuilder internal constructor( + override val atomicSymbols: JvmAtomicSymbols, symbol: IrSymbol, startOffset: Int, endOffset: Int -) : IrBuilderWithScope(IrGeneratorContextBase(atomicSymbols.irBuiltIns), Scope(symbol), startOffset, endOffset) { - - fun getProperty(property: IrProperty, dispatchReceiver: IrExpression?) = - irCall(property.getter?.symbol ?: error("Getter is not defined for the property ${property.render()}")).apply { - this.dispatchReceiver = dispatchReceiver?.deepCopyWithSymbols() - } +) : AbstractAtomicfuIrBuilder(atomicSymbols.irBuiltIns, symbol, startOffset, endOffset) { // a$FU.get(obj) fun atomicGetValue(valueType: IrType, receiver: IrExpression, obj: IrExpression) = @@ -39,14 +39,50 @@ class AtomicfuIrBuilder internal constructor( putValueArgument(0, index) } - fun irCallWithArgs(symbol: IrSimpleFunctionSymbol, dispatchReceiver: IrExpression?, valueArguments: List) = - irCall(symbol).apply { - this.dispatchReceiver = dispatchReceiver - valueArguments.forEachIndexed { i, arg -> - putValueArgument(i, arg) - } + fun irJavaAtomicArrayField( + name: Name, + arrayClass: IrClassSymbol, + isStatic: Boolean, + annotations: List, + size: IrExpression, + dispatchReceiver: IrExpression?, + parentContainer: IrDeclarationContainer + ): IrField = + context.irFactory.buildField { + this.name = name + type = arrayClass.defaultType + this.isFinal = true + this.isStatic = isStatic + visibility = DescriptorVisibilities.PRIVATE + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_FIELD + }.apply { + this.initializer = IrExpressionBodyImpl( + newJavaAtomicArray(arrayClass, size, dispatchReceiver) + ) + this.annotations = annotations + this.parent = parentContainer } + fun irJavaAtomicFieldUpdater(volatileField: IrField, parentClass: IrClass): IrField { + // Generate an atomic field updater for the volatile backing field of the given property: + // val a = atomic(0) + // volatile var a: Int = 0 + // val a$FU = AtomicIntegerFieldUpdater.newUpdater(parentClass, "a") + val fuClass = atomicSymbols.getJucaAFUClass(volatileField.type) + val fieldName = volatileField.name.asString() + return context.irFactory.buildField { + name = Name.identifier("$fieldName\$FU") + type = fuClass.defaultType + isFinal = true + isStatic = true + visibility = DescriptorVisibilities.PRIVATE + origin = AbstractAtomicSymbols.ATOMICFU_GENERATED_FIELD + }.apply { + initializer = irExprBody(newJavaAtomicFieldUpdater(fuClass, parentClass, atomicSymbols.irBuiltIns.anyNType, fieldName)) + parent = parentClass + } + } + // atomicArr.compareAndSet(index, expect, update) fun callAtomicArray( arrayClassSymbol: IrClassSymbol, @@ -70,15 +106,15 @@ class AtomicfuIrBuilder internal constructor( fun callFieldUpdater( fieldUpdaterSymbol: IrClassSymbol, functionName: String, - dispatchReceiver: IrExpression?, - obj: IrExpression?, + getAtomicHandler: IrExpression, + classInstanceContainingField: IrExpression?, valueArguments: List, castType: IrType?, isBooleanReceiver: Boolean, ): IrExpression { val irCall = irCall(atomicSymbols.getAtomicHandlerFunctionSymbol(fieldUpdaterSymbol, functionName)).apply { - this.dispatchReceiver = dispatchReceiver - putValueArgument(0, obj) // instance of the class, containing the field + this.dispatchReceiver = getAtomicHandler + putValueArgument(0, classInstanceContainingField) // instance of the class, containing the field valueArguments.forEachIndexed { index, arg -> putValueArgument(index + 1, arg) // function arguments } @@ -91,17 +127,15 @@ class AtomicfuIrBuilder internal constructor( return if (isBooleanReceiver && irCall.type.isInt()) irCall.toBoolean() else irCall } - private fun IrExpression.toBoolean() = irNotEquals(this, irInt(0)) as IrCall - fun callAtomicExtension( symbol: IrSimpleFunctionSymbol, dispatchReceiver: IrExpression?, syntheticValueArguments: List, valueArguments: List - ) = irCallWithArgs(symbol, dispatchReceiver, syntheticValueArguments + valueArguments) + ) = irCallWithArgs(symbol, dispatchReceiver, null, syntheticValueArguments + valueArguments) // val a$FU = j.u.c.a.AtomicIntegerFieldUpdater.newUpdater(A::class, "a") - fun newUpdater( + private fun newJavaAtomicFieldUpdater( fieldUpdaterClass: IrClassSymbol, parentClass: IrClass, valueType: IrType, @@ -117,7 +151,7 @@ class AtomicfuIrBuilder internal constructor( } // val atomicArr = j.u.c.a.AtomicIntegerArray(size) - fun newJucaAtomicArray( + fun newJavaAtomicArray( atomicArrayClass: IrClassSymbol, size: IrExpression, dispatchReceiver: IrExpression? 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 cdb0a158b56..b12bd4bc0c2 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 @@ -17,7 +17,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.platform.isJs import org.jetbrains.kotlin.platform.jvm.isJvm -import org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm.AtomicSymbols +import org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm.JvmAtomicSymbols import org.jetbrains.kotlinx.atomicfu.compiler.backend.js.AtomicfuJsIrTransformer import org.jetbrains.kotlinx.atomicfu.compiler.backend.jvm.AtomicfuJvmIrTransformer @@ -27,7 +27,7 @@ public open class AtomicfuLoweringExtension : IrGenerationExtension { pluginContext: IrPluginContext ) { if (pluginContext.platform.isJvm()) { - val atomicSymbols = AtomicSymbols(pluginContext.irBuiltIns, moduleFragment) + val atomicSymbols = JvmAtomicSymbols(pluginContext, moduleFragment) AtomicfuJvmIrTransformer(pluginContext, atomicSymbols).transform(moduleFragment) } if (pluginContext.platform.isJs()) { @@ -62,4 +62,4 @@ fun FileLoweringPass.runOnFileInOrder(irFile: IrFile) { declaration.acceptChildrenVoid(this) } }) -} \ No newline at end of file +} diff --git a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AbstractAtomicfuJvmIrTest.kt b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AbstractAtomicfuJvmIrTest.kt index 96b1ccfd40c..3fb3f895d61 100644 --- a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AbstractAtomicfuJvmIrTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AbstractAtomicfuJvmIrTest.kt @@ -5,16 +5,9 @@ package org.jetbrains.kotlinx.atomicfu -import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.ObsoleteTestInfrastructure -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots -import org.jetbrains.kotlin.codegen.AbstractAsmLikeInstructionListingTest -import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar.ExtensionStorage import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.directives.CodegenTestDirectives import org.jetbrains.kotlin.test.model.TestModule @@ -27,13 +20,12 @@ import java.io.File private val coreLibraryPath = getLibraryJar("kotlinx.atomicfu.AtomicFU") private val kotlinTestPath = getLibraryJar("kotlin.test.AssertionsKt") -private val javaUtilConcurrentPath = getLibraryJar("java.util.concurrent.atomic.AtomicIntegerFieldUpdater") private val kotlinJvm = getLibraryJar("kotlin.jvm.JvmField") open class AbstractAtomicfuJvmIrTest : AbstractIrBlackBoxCodegenTest() { override fun configure(builder: TestConfigurationBuilder) { super.configure(builder) - val librariesPaths = listOf(coreLibraryPath!!, kotlinTestPath!!, javaUtilConcurrentPath!!, kotlinJvm!!) + val librariesPaths = listOf(coreLibraryPath!!, kotlinTestPath!!, kotlinJvm!!) builder.configureForKotlinxAtomicfu(librariesPaths) } } diff --git a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJsIrTestGenerated.java b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJsIrTestGenerated.java index de7bb3a0f07..1378830dfdf 100644 --- a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJsIrTestGenerated.java +++ b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJsIrTestGenerated.java @@ -25,171 +25,237 @@ public class AtomicfuJsIrTestGenerated extends AbstractAtomicfuJsIrTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } - @Test - @TestMetadata("ArithmeticTest.kt") - public void testArithmeticTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions") + @TestDataPath("$PROJECT_ROOT") + public class Atomic_extensions { + @Test + public void testAllFilesPresentInAtomic_extensions() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @Test + @TestMetadata("ArrayInlineExtensionTest.kt") + public void testArrayInlineExtensionTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.kt"); + } + + @Test + @TestMetadata("ArrayLoopTest.kt") + public void testArrayLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayLoopTest.kt"); + } + + @Test + @TestMetadata("ComplexLoopTest.kt") + public void testComplexLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.kt"); + } + + @Test + @TestMetadata("ExtensionLoopTest.kt") + public void testExtensionLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.kt"); + } + + @Test + @TestMetadata("ExtensionsTest.kt") + public void testExtensionsTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.kt"); + } + + @Test + @TestMetadata("InlineExtensionWithTypeParameterTest.kt") + public void testInlineExtensionWithTypeParameterTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.kt"); + } + + @Test + @TestMetadata("LambdaTest.kt") + public void testLambdaTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.kt"); + } + + @Test + @TestMetadata("LockFreeIntBitsTest.kt") + public void testLockFreeIntBitsTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockFreeIntBitsTest.kt"); + } + + @Test + @TestMetadata("LockTest.kt") + public void testLockTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockTest.kt"); + } + + @Test + @TestMetadata("ParameterizedInlineFunExtensionTest.kt") + public void testParameterizedInlineFunExtensionTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ParameterizedInlineFunExtensionTest.kt"); + } } - @Test - @TestMetadata("ArrayInlineExtensionTest.kt") - public void testArrayInlineExtensionTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic") + @TestDataPath("$PROJECT_ROOT") + public class Atomics_basic { + @Test + public void testAllFilesPresentInAtomics_basic() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @Test + @TestMetadata("ArithmeticTest.kt") + public void testArithmeticTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.kt"); + } + + @Test + @TestMetadata("AtomicArrayTest.kt") + public void testAtomicArrayTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.kt"); + } + + @Test + @TestMetadata("IndexArrayElementGetterTest.kt") + public void testIndexArrayElementGetterTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.kt"); + } + + @Test + @TestMetadata("InitializationOrderTest.kt") + public void testInitializationOrderTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.kt"); + } + + @Test + @TestMetadata("LateinitPropertiesTest.kt") + public void testLateinitPropertiesTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LateinitPropertiesTest.kt"); + } + + @Test + @TestMetadata("LockFreeLongCounterTest.kt") + public void testLockFreeLongCounterTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeLongCounterTest.kt"); + } + + @Test + @TestMetadata("LockFreeQueueTest.kt") + public void testLockFreeQueueTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.kt"); + } + + @Test + @TestMetadata("LockFreeStackTest.kt") + public void testLockFreeStackTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeStackTest.kt"); + } + + @Test + @TestMetadata("LoopTest.kt") + public void testLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.kt"); + } + + @Test + @TestMetadata("MultiInitTest.kt") + public void testMultiInitTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/MultiInitTest.kt"); + } + + @Test + @TestMetadata("ScopeTest.kt") + public void testScopeTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.kt"); + } + + @Test + @TestMetadata("SimpleLockTest.kt") + public void testSimpleLockTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/SimpleLockTest.kt"); + } + + @Test + @TestMetadata("UncheckedCastTest.kt") + public void testUncheckedCastTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/UncheckedCastTest.kt"); + } } - @Test - @TestMetadata("ArrayLoopTest.kt") - public void testArrayLoopTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/delegated") + @TestDataPath("$PROJECT_ROOT") + public class Delegated { + @Test + public void testAllFilesPresentInDelegated() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/delegated"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @Test + @TestMetadata("DelegatedPropertiesTest.kt") + public void testDelegatedPropertiesTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.kt"); + } } - @Test - @TestMetadata("AtomicArrayTest.kt") - public void testAtomicArrayTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/locks") + @TestDataPath("$PROJECT_ROOT") + public class Locks { + @Test + public void testAllFilesPresentInLocks() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/locks"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @Test + @TestMetadata("ReentrantLockTest.kt") + public void testReentrantLockTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/locks/ReentrantLockTest.kt"); + } + + @Test + @TestMetadata("SynchronizedObjectTest.kt") + public void testSynchronizedObjectTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/locks/SynchronizedObjectTest.kt"); + } } - @Test - @TestMetadata("ComplexLoopTest.kt") - public void testComplexLoopTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/top-level") + @TestDataPath("$PROJECT_ROOT") + public class Top_level { + @Test + public void testAllFilesPresentInTop_level() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/top-level"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @Test + @TestMetadata("FieldInObjectTest.kt") + public void testFieldInObjectTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.kt"); + } + + @Test + @TestMetadata("TopLevelTest.kt") + public void testTopLevelTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.kt"); + } } - @Test - @TestMetadata("DelegatedPropertiesTest.kt") - public void testDelegatedPropertiesTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.kt"); - } + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/trace") + @TestDataPath("$PROJECT_ROOT") + public class Trace { + @Test + public void testAllFilesPresentInTrace() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/trace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } - @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("FieldInObjectTest.kt") - public void testFieldInObjectTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.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"); + @Test + @TestMetadata("TraceTest.kt") + public void testTraceTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/trace/TraceTest.kt"); + } } } diff --git a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJvmIrTestGenerated.java b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJvmIrTestGenerated.java index 617d9a92441..9408053a29a 100644 --- a/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJvmIrTestGenerated.java +++ b/plugins/atomicfu/atomicfu-compiler/test/org/jetbrains/kotlinx/atomicfu/AtomicfuJvmIrTestGenerated.java @@ -25,171 +25,237 @@ public class AtomicfuJvmIrTestGenerated extends AbstractAtomicfuJvmIrTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } - @Test - @TestMetadata("ArithmeticTest.kt") - public void testArithmeticTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions") + @TestDataPath("$PROJECT_ROOT") + public class Atomic_extensions { + @Test + public void testAllFilesPresentInAtomic_extensions() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("ArrayInlineExtensionTest.kt") + public void testArrayInlineExtensionTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.kt"); + } + + @Test + @TestMetadata("ArrayLoopTest.kt") + public void testArrayLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayLoopTest.kt"); + } + + @Test + @TestMetadata("ComplexLoopTest.kt") + public void testComplexLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.kt"); + } + + @Test + @TestMetadata("ExtensionLoopTest.kt") + public void testExtensionLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.kt"); + } + + @Test + @TestMetadata("ExtensionsTest.kt") + public void testExtensionsTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.kt"); + } + + @Test + @TestMetadata("InlineExtensionWithTypeParameterTest.kt") + public void testInlineExtensionWithTypeParameterTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.kt"); + } + + @Test + @TestMetadata("LambdaTest.kt") + public void testLambdaTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.kt"); + } + + @Test + @TestMetadata("LockFreeIntBitsTest.kt") + public void testLockFreeIntBitsTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockFreeIntBitsTest.kt"); + } + + @Test + @TestMetadata("LockTest.kt") + public void testLockTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockTest.kt"); + } + + @Test + @TestMetadata("ParameterizedInlineFunExtensionTest.kt") + public void testParameterizedInlineFunExtensionTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ParameterizedInlineFunExtensionTest.kt"); + } } - @Test - @TestMetadata("ArrayInlineExtensionTest.kt") - public void testArrayInlineExtensionTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic") + @TestDataPath("$PROJECT_ROOT") + public class Atomics_basic { + @Test + public void testAllFilesPresentInAtomics_basic() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("ArithmeticTest.kt") + public void testArithmeticTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.kt"); + } + + @Test + @TestMetadata("AtomicArrayTest.kt") + public void testAtomicArrayTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.kt"); + } + + @Test + @TestMetadata("IndexArrayElementGetterTest.kt") + public void testIndexArrayElementGetterTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.kt"); + } + + @Test + @TestMetadata("InitializationOrderTest.kt") + public void testInitializationOrderTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.kt"); + } + + @Test + @TestMetadata("LateinitPropertiesTest.kt") + public void testLateinitPropertiesTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LateinitPropertiesTest.kt"); + } + + @Test + @TestMetadata("LockFreeLongCounterTest.kt") + public void testLockFreeLongCounterTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeLongCounterTest.kt"); + } + + @Test + @TestMetadata("LockFreeQueueTest.kt") + public void testLockFreeQueueTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.kt"); + } + + @Test + @TestMetadata("LockFreeStackTest.kt") + public void testLockFreeStackTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeStackTest.kt"); + } + + @Test + @TestMetadata("LoopTest.kt") + public void testLoopTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.kt"); + } + + @Test + @TestMetadata("MultiInitTest.kt") + public void testMultiInitTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/MultiInitTest.kt"); + } + + @Test + @TestMetadata("ScopeTest.kt") + public void testScopeTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.kt"); + } + + @Test + @TestMetadata("SimpleLockTest.kt") + public void testSimpleLockTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/SimpleLockTest.kt"); + } + + @Test + @TestMetadata("UncheckedCastTest.kt") + public void testUncheckedCastTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/UncheckedCastTest.kt"); + } } - @Test - @TestMetadata("ArrayLoopTest.kt") - public void testArrayLoopTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/delegated") + @TestDataPath("$PROJECT_ROOT") + public class Delegated { + @Test + public void testAllFilesPresentInDelegated() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/delegated"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("DelegatedPropertiesTest.kt") + public void testDelegatedPropertiesTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.kt"); + } } - @Test - @TestMetadata("AtomicArrayTest.kt") - public void testAtomicArrayTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/locks") + @TestDataPath("$PROJECT_ROOT") + public class Locks { + @Test + public void testAllFilesPresentInLocks() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/locks"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("ReentrantLockTest.kt") + public void testReentrantLockTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/locks/ReentrantLockTest.kt"); + } + + @Test + @TestMetadata("SynchronizedObjectTest.kt") + public void testSynchronizedObjectTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/locks/SynchronizedObjectTest.kt"); + } } - @Test - @TestMetadata("ComplexLoopTest.kt") - public void testComplexLoopTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.kt"); + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/top-level") + @TestDataPath("$PROJECT_ROOT") + public class Top_level { + @Test + public void testAllFilesPresentInTop_level() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/top-level"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("FieldInObjectTest.kt") + public void testFieldInObjectTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.kt"); + } + + @Test + @TestMetadata("TopLevelTest.kt") + public void testTopLevelTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.kt"); + } } - @Test - @TestMetadata("DelegatedPropertiesTest.kt") - public void testDelegatedPropertiesTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.kt"); - } + @Nested + @TestMetadata("plugins/atomicfu/atomicfu-compiler/testData/box/trace") + @TestDataPath("$PROJECT_ROOT") + public class Trace { + @Test + public void testAllFilesPresentInTrace() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/atomicfu/atomicfu-compiler/testData/box/trace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } - @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("FieldInObjectTest.kt") - public void testFieldInObjectTest() throws Exception { - runTest("plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.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"); + @Test + @TestMetadata("TraceTest.kt") + public void testTraceTest() throws Exception { + runTest("plugins/atomicfu/atomicfu-compiler/testData/box/trace/TraceTest.kt"); + } } } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.kt deleted file mode 100644 index e2e273a45ac..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.kt +++ /dev/null @@ -1,146 +0,0 @@ -import kotlinx.atomicfu.* -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(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) - } -} - -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) - } -} - -fun box(): String { - val testClass = ArithmeticTest() - - testClass.testGetValue() - if (!testClass.testAtomicCallPlaces()) return "testAtomicCallPlaces: FAILED" - - testClass.testInt() - testClass.testLong() - testClass.testBoolean() - testClass.testReference() - return "OK" -} \ No newline at end of file diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.txt deleted file mode 100644 index c0caa0ced1a..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ArithmeticTest.txt +++ /dev/null @@ -1,103 +0,0 @@ -@kotlin.Metadata -public final class ArithmeticTest { - // source: 'ArithmeticTest.kt' - private final static @org.jetbrains.annotations.NotNull field local$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field local: int - static method (): void - public method (): void - public final static @org.jetbrains.annotations.NotNull method getLocal$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getLocal(): int - public final method testAtomicCallPlaces(): boolean - public final method testBoolean(): void - public final method testGetValue(): void - public final method testInt(): void - public final method testLong(): void - public final method testReference(): void -} - -@kotlin.Metadata -public final class ArithmeticTestKt { - // source: 'ArithmeticTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} - -@kotlin.Metadata -public final class BooleanArithmetic { - // source: 'ArithmeticTest.kt' - private final static @org.jetbrains.annotations.NotNull field _x$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _x: int - static method (): void - public method (): void - public final method getX(): boolean - public final static @org.jetbrains.annotations.NotNull method get_x$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method get_x(): int -} - -@kotlin.Metadata -public final class IntArithmetic { - // source: 'ArithmeticTest.kt' - private final static @org.jetbrains.annotations.NotNull field _x$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _x: int - static method (): void - public method (): void - public final method getX(): int - public final static @org.jetbrains.annotations.NotNull method get_x$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method get_x(): int -} - -@kotlin.Metadata -public final class LongArithmetic { - // source: 'ArithmeticTest.kt' - private final static @org.jetbrains.annotations.NotNull field _x$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field _x: long - private final static @org.jetbrains.annotations.NotNull field max$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field max: long - private final static @org.jetbrains.annotations.NotNull field y$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field y: long - private final static @org.jetbrains.annotations.NotNull field z$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field z: long - static method (): void - public method (): void - public final static @org.jetbrains.annotations.NotNull method getMax$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater - public final method getMax(): long - public final method getX(): long - public final static @org.jetbrains.annotations.NotNull method getY$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater - public final method getY(): long - public final static @org.jetbrains.annotations.NotNull method getZ$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater - public final method getZ(): long - public final static @org.jetbrains.annotations.NotNull method get_x$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater - public final method get_x(): long -} - -@kotlin.Metadata -public final class ReferenceArithmetic { - // source: 'ArithmeticTest.kt' - private final static @org.jetbrains.annotations.NotNull field _x$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field _x: java.lang.Object - static method (): void - public method (): void - public final static @org.jetbrains.annotations.NotNull method get_x$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method get_x(): java.lang.Object -} - -@kotlin.Metadata -public final class VisibilitiesTest { - // source: 'ArithmeticTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field b$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field b: int - private final static @org.jetbrains.annotations.NotNull field c$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field c: int - private final static @org.jetbrains.annotations.NotNull field d$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field d: int - static method (): void - public method (): void - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA(): int - public final static @org.jetbrains.annotations.NotNull method getB$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getB(): int - public final static @org.jetbrains.annotations.NotNull method getD$FU$main(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getD$main(): int - public final method test(): void -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.txt deleted file mode 100644 index cc3a77acfc3..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.txt +++ /dev/null @@ -1,50 +0,0 @@ -@kotlin.Metadata -public final class ArrayInlineExtensionTest$A { - // source: 'ArrayInlineExtensionTest.kt' - private final @org.jetbrains.annotations.NotNull field s: java.lang.String - public method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void - public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String - public final inner class ArrayInlineExtensionTest$A -} - -@kotlin.Metadata -public final class ArrayInlineExtensionTest { - // source: 'ArrayInlineExtensionTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final @org.jetbrains.annotations.NotNull field intArr: java.util.concurrent.atomic.AtomicIntegerArray - private final @org.jetbrains.annotations.NotNull field longArr: java.util.concurrent.atomic.AtomicLongArray - private final @org.jetbrains.annotations.NotNull field refArr: java.util.concurrent.atomic.AtomicReferenceArray - static method (): void - public method (): void - private final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method casLoop(p0: int): int - private final method casLoopExpression(p0: long): long - private final method extensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method extensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method extensionLoopExpression$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method extensionLoopExpression$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method extensionLoopMixedReceivers$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int, p4: int, p5: int): int - private final method extensionLoopMixedReceivers$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int, p3: int, p4: int): int - private final method extensionLoopRecursive$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method extensionLoopRecursive$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA(): int - public final @org.jetbrains.annotations.NotNull method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray - public final @org.jetbrains.annotations.NotNull method getLongArr(): java.util.concurrent.atomic.AtomicLongArray - public final @org.jetbrains.annotations.NotNull method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray - private final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void - private final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicLongArray, p1: int, p2: kotlin.jvm.functions.Function1): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - public final method testIntExtensionLoops(): void - public final inner class ArrayInlineExtensionTest$A -} - -@kotlin.Metadata -public final class ArrayInlineExtensionTestKt { - // source: 'ArrayInlineExtensionTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.txt deleted file mode 100644 index 8714e859e03..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.txt +++ /dev/null @@ -1,51 +0,0 @@ -@kotlin.Metadata -public final class ARef { - // source: 'AtomicArrayTest.kt' - private final field n: int - public method (p0: int): void - public final method component1(): int - public synthetic static method copy$default(p0: ARef, p1: int, p2: int, p3: java.lang.Object): ARef - public final @org.jetbrains.annotations.NotNull method copy(p0: int): ARef - public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean - public final method getN(): int - public method hashCode(): int - public @org.jetbrains.annotations.NotNull method toString(): java.lang.String -} - -@kotlin.Metadata -public final class AtomicArrayClass { - // source: 'AtomicArrayTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field a: java.lang.Object - private final @org.jetbrains.annotations.NotNull field anyArr: java.util.concurrent.atomic.AtomicReferenceArray - private final @org.jetbrains.annotations.NotNull field booleanArr: java.util.concurrent.atomic.AtomicIntegerArray - private final @org.jetbrains.annotations.NotNull field intArr: java.util.concurrent.atomic.AtomicIntegerArray - private final @org.jetbrains.annotations.NotNull field longArr: java.util.concurrent.atomic.AtomicLongArray - private final @org.jetbrains.annotations.NotNull field refArr: java.util.concurrent.atomic.AtomicReferenceArray - static method (): void - public method (): void - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getA(): java.lang.Object - public final @org.jetbrains.annotations.NotNull method getAnyArr(): java.util.concurrent.atomic.AtomicReferenceArray - public final @org.jetbrains.annotations.NotNull method getBooleanArr(): java.util.concurrent.atomic.AtomicIntegerArray - public final @org.jetbrains.annotations.NotNull method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray - public final @org.jetbrains.annotations.NotNull method getLongArr(): java.util.concurrent.atomic.AtomicLongArray - public final @org.jetbrains.annotations.NotNull method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray -} - -@kotlin.Metadata -public final class AtomicArrayTest { - // source: 'AtomicArrayTest.kt' - public method (): void - public final method testAnyArray(): void - public final method testBooleanArray(): void - public final method testIntArray(): void - public final method testLongArray(): void - public final method testRefArray(): void -} - -@kotlin.Metadata -public final class AtomicArrayTestKt { - // source: 'AtomicArrayTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.txt deleted file mode 100644 index 747aaf75e3e..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.txt +++ /dev/null @@ -1,44 +0,0 @@ -@kotlin.Metadata -public final class ComplexLoopTestKt { - // source: 'ComplexLoopTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} - -@kotlin.Metadata -public final class LoopTest { - // source: 'ComplexLoopTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field b$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field b: int - private final static @org.jetbrains.annotations.NotNull field c$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field c: int - private final @org.jetbrains.annotations.NotNull field intArr: java.util.concurrent.atomic.AtomicIntegerArray - private final static @org.jetbrains.annotations.NotNull field r$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field r: java.lang.Object - static method (): void - public method (): void - private final method embeddedLoops(p0: int): int - private final method embeddedUpdate(p0: int): int - private final method extensionEmbeddedLoops$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method extensionEmbeddedLoops$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method extesntionEmbeddedRefUpdate$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.String): java.lang.String - private final method extesntionEmbeddedRefUpdate$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.String): java.lang.String - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA(): int - public final static @org.jetbrains.annotations.NotNull method getB$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getB(): int - public final static @org.jetbrains.annotations.NotNull method getC$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getC(): int - public final @org.jetbrains.annotations.NotNull method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray - public final static @org.jetbrains.annotations.NotNull method getR$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getR(): java.lang.Object - private final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void - private final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - public final method test(): void - private final method updateAndGet$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object - private final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): int - private final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionLoopTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionLoopTest.txt deleted file mode 100644 index fe4d735be87..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionLoopTest.txt +++ /dev/null @@ -1,81 +0,0 @@ -@kotlin.Metadata -public final class ExtensionLoopTestKt { - // source: 'ExtensionLoopTest.kt' - private final static @org.jetbrains.annotations.NotNull field ref$ExtensionLoopTest$VolatileWrapper: Ref$ExtensionLoopTest$VolatileWrapper - static method (): void - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String - private final static method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void - private final static method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - public final static method testTopLevelExtensionLoop(): void - private final static method topLevelExtensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.String): java.lang.String - private final static method topLevelExtensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.String): java.lang.String -} - -@kotlin.Metadata -public final class LoopTest$A { - // source: 'ExtensionLoopTest.kt' - private final @org.jetbrains.annotations.NotNull field s: java.lang.String - public method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void - public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String - public final inner class LoopTest$A -} - -@kotlin.Metadata -public final class LoopTest { - // source: 'ExtensionLoopTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private final static @org.jetbrains.annotations.NotNull field a1$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a1: int - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field b$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field b: int - private final static @org.jetbrains.annotations.NotNull field l$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field l: long - private final static @org.jetbrains.annotations.NotNull field r$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field r: java.lang.Object - private final static @org.jetbrains.annotations.NotNull field rs$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field rs: java.lang.Object - static method (): void - public method (): void - private final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method casLoop(p0: int): int - private final method casLoopExpression(p0: int): int - private final method extensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method extensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method extensionLoopExpression$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method extensionLoopExpression$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method extensionLoopMixedReceivers$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int, p4: int): int - private final method extensionLoopMixedReceivers$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int, p3: int): int - private final method extensionLoopRecursive$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method extensionLoopRecursive$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - private final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int - private final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA(): int - public final static @org.jetbrains.annotations.NotNull method getA1$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA1(): int - public final static @org.jetbrains.annotations.NotNull method getB$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getB(): int - public final static @org.jetbrains.annotations.NotNull method getL$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater - public final method getL(): long - public final static @org.jetbrains.annotations.NotNull method getR$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getR(): java.lang.Object - public final static @org.jetbrains.annotations.NotNull method getRs$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getRs(): java.lang.Object - private final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - public final method testIntExtensionLoops(): void - public final inner class LoopTest$A -} - -@kotlin.Metadata -final class Ref$ExtensionLoopTest$VolatileWrapper { - // source: 'ExtensionLoopTest.kt' - private final static @org.jetbrains.annotations.NotNull field ref$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field ref: java.lang.Object - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getRef$FU$p(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionsTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionsTest.txt deleted file mode 100644 index b866de48529..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionsTest.txt +++ /dev/null @@ -1,38 +0,0 @@ -@kotlin.Metadata -public final class ExtensionsTest { - // source: 'ExtensionsTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field b$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field b: int - private final static @org.jetbrains.annotations.NotNull field l$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field l: long - private final static @org.jetbrains.annotations.NotNull field s$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field s: java.lang.Object - static method (): void - public method (): void - public final method booleanExtensionArithmetic$atomicfu$array(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): void - public final method booleanExtensionArithmetic$atomicfu(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): void - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA(): int - public final static @org.jetbrains.annotations.NotNull method getB$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getB(): int - public final static @org.jetbrains.annotations.NotNull method getL$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater - public final method getL(): long - public final static @org.jetbrains.annotations.NotNull method getS$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getS(): java.lang.Object - public final method intExtensionArithmetic$atomicfu$array(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): void - public final method intExtensionArithmetic$atomicfu(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): void - public final method longExtensionArithmetic$atomicfu$array(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicLongArray, p2: int): void - public final method longExtensionArithmetic$atomicfu(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicLongFieldUpdater): void - public final method refExtension$atomicfu$array(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int): void - public final method refExtension$atomicfu(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater): void - public final method testExtension(): void - public final method testScopedFieldGetters(): void -} - -@kotlin.Metadata -public final class ExtensionsTestKt { - // source: 'ExtensionsTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.txt deleted file mode 100644 index 5b4cfd3736b..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.txt +++ /dev/null @@ -1,118 +0,0 @@ -@kotlin.Metadata -public final class DelegatedProvider$_a$DelegatedProvider$VolatileWrapper { - // source: 'FieldInObjectTest.kt' - private final static @org.jetbrains.annotations.NotNull field _a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _a: int - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$get_a$p(p0: DelegatedProvider$_a$DelegatedProvider$VolatileWrapper): int - public synthetic final static method access$set_a$p(p0: DelegatedProvider$_a$DelegatedProvider$VolatileWrapper, p1: int): void - public final static @org.jetbrains.annotations.NotNull method get_a$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method get_a(): int - public final inner class DelegatedProvider$_a$DelegatedProvider$VolatileWrapper -} - -@kotlin.Metadata -public final class DelegatedProvider { - // source: 'FieldInObjectTest.kt' - public final static @org.jetbrains.annotations.NotNull field INSTANCE: DelegatedProvider - private final static @org.jetbrains.annotations.NotNull field _a$DelegatedProvider$VolatileWrapper: DelegatedProvider$_a$DelegatedProvider$VolatileWrapper - private volatile @kotlin.jvm.Volatile field vInt: int - static method (): void - private method (): void - public final method getA(): int - public final method getVInt(): int - public final static @org.jetbrains.annotations.NotNull method get_a$DelegatedProvider$VolatileWrapper(): DelegatedProvider$_a$DelegatedProvider$VolatileWrapper - public final method setA(p0: int): void - public final method setVInt(p0: int): void - public final inner class DelegatedProvider$_a$DelegatedProvider$VolatileWrapper -} - -@kotlin.Metadata -public final class FieldInObjectTestKt { - // source: 'FieldInObjectTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String - private final static method testDelegatedPropertiesInObject(): void - private final static method testFieldInObject(): void - public final inner class DelegatedProvider$_a$DelegatedProvider$VolatileWrapper - public final inner class Provider$_ref$Provider$VolatileWrapper - public final inner class Provider$_x$Provider$VolatileWrapper -} - -@kotlin.Metadata -final class Provider$Port$Provider$VolatileWrapper { - // source: 'FieldInObjectTest.kt' - private final static @org.jetbrains.annotations.NotNull field port$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field port: int - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getPort$FU$p(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private final inner class Provider$Port$Provider$VolatileWrapper - public final inner class kotlin/random/Random$Default -} - -@kotlin.Metadata -final class Provider$_l$Provider$VolatileWrapper { - // source: 'FieldInObjectTest.kt' - private final static @org.jetbrains.annotations.NotNull field _l$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field _l: long - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$get_l$FU$p(): java.util.concurrent.atomic.AtomicLongFieldUpdater - private final inner class Provider$_l$Provider$VolatileWrapper -} - -@kotlin.Metadata -public final class Provider$_ref$Provider$VolatileWrapper { - // source: 'FieldInObjectTest.kt' - private final static @org.jetbrains.annotations.NotNull field _ref$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field _ref: java.lang.Object - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public final static @org.jetbrains.annotations.NotNull method get_ref$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method get_ref(): java.lang.Object - public final inner class Provider$_ref$Provider$VolatileWrapper -} - -@kotlin.Metadata -public final class Provider$_x$Provider$VolatileWrapper { - // source: 'FieldInObjectTest.kt' - private final static @org.jetbrains.annotations.NotNull field _x$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _x: int - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public final static @org.jetbrains.annotations.NotNull method get_x$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method get_x(): int - public final inner class Provider$_x$Provider$VolatileWrapper -} - -@kotlin.Metadata -public final class Provider { - // source: 'FieldInObjectTest.kt' - public final static @org.jetbrains.annotations.NotNull field INSTANCE: Provider - private final static @org.jetbrains.annotations.NotNull field _l$Provider$VolatileWrapper: Provider$_l$Provider$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field _ref$Provider$VolatileWrapper: Provider$_ref$Provider$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field _x$Provider$VolatileWrapper: Provider$_x$Provider$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field intArr: java.util.concurrent.atomic.AtomicIntegerArray - private final static @org.jetbrains.annotations.NotNull field longArr: java.util.concurrent.atomic.AtomicLongArray - private final static @org.jetbrains.annotations.NotNull field port$Provider$VolatileWrapper: Provider$Port$Provider$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field refArr: java.util.concurrent.atomic.AtomicReferenceArray - static method (): void - private method (): void - public final static @org.jetbrains.annotations.NotNull method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray - public final method getL(): long - public final static @org.jetbrains.annotations.NotNull method getLongArr(): java.util.concurrent.atomic.AtomicLongArray - public final static @org.jetbrains.annotations.NotNull method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray - public final static @org.jetbrains.annotations.NotNull method get_ref$Provider$VolatileWrapper(): Provider$_ref$Provider$VolatileWrapper - public final static @org.jetbrains.annotations.NotNull method get_x$Provider$VolatileWrapper(): Provider$_x$Provider$VolatileWrapper - public final method next(): int - private final inner class Provider$Port$Provider$VolatileWrapper - private final inner class Provider$_l$Provider$VolatileWrapper - public final inner class Provider$_ref$Provider$VolatileWrapper - public final inner class Provider$_x$Provider$VolatileWrapper -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/IndexArrayElementGetterTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/IndexArrayElementGetterTest.txt deleted file mode 100644 index 70ab6517779..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/IndexArrayElementGetterTest.txt +++ /dev/null @@ -1,26 +0,0 @@ -@kotlin.Metadata -public final class IndexArrayElementGetterTest$AtomicArrayClass { - // source: 'IndexArrayElementGetterTest.kt' - private final @org.jetbrains.annotations.NotNull field intArr: java.util.concurrent.atomic.AtomicIntegerArray - private final @org.jetbrains.annotations.NotNull field longArr: java.util.concurrent.atomic.AtomicLongArray - public method (): void - public final @org.jetbrains.annotations.NotNull method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray - public final @org.jetbrains.annotations.NotNull method getLongArr(): java.util.concurrent.atomic.AtomicLongArray - public final inner class IndexArrayElementGetterTest$AtomicArrayClass -} - -@kotlin.Metadata -public final class IndexArrayElementGetterTest { - // source: 'IndexArrayElementGetterTest.kt' - private final @org.jetbrains.annotations.NotNull field clazz: IndexArrayElementGetterTest$AtomicArrayClass - public method (): void - public final method fib(p0: int): int - public final method testIndexArrayElementGetting(): void - public final inner class IndexArrayElementGetterTest$AtomicArrayClass -} - -@kotlin.Metadata -public final class IndexArrayElementGetterTestKt { - // source: 'IndexArrayElementGetterTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LambdaTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/LambdaTest.kt deleted file mode 100644 index e90fc8ba7a7..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LambdaTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -import kotlinx.atomicfu.* -import kotlin.test.* - -class LambdaTest { - val a = atomic(0) - val rs = atomic("bbbb") - - private inline fun inlineLambda( - arg: Int, - crossinline block: (Int) -> Unit - ) = block(arg) - - fun loopInLambda1(to: Int) = inlineLambda(to) sc@ { arg -> - a.loop { value -> - a.compareAndSet(value, arg) - return@sc - } - } - - fun loopInLambda2(to: Int) = inlineLambda(to) { arg1 -> - inlineLambda(arg1) sc@ { arg2 -> - a.loop { value -> - a.compareAndSet(value, arg2) - return@sc - } - } - } -} - -fun box(): String { - val testClass = LambdaTest() - testClass.loopInLambda1(34) - assertEquals(34, testClass.a.value) - testClass.loopInLambda1(77) - assertEquals(77, testClass.a.value) - return "OK" -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LambdaTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/LambdaTest.txt deleted file mode 100644 index fb7b648dc64..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LambdaTest.txt +++ /dev/null @@ -1,24 +0,0 @@ -@kotlin.Metadata -public final class LambdaTest { - // source: 'LambdaTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field rs$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field rs: java.lang.Object - static method (): void - public method (): void - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA(): int - public final static @org.jetbrains.annotations.NotNull method getRs$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getRs(): java.lang.Object - private final method inlineLambda(p0: int, p1: kotlin.jvm.functions.Function1): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - public final method loopInLambda1(p0: int): void - public final method loopInLambda2(p0: int): void -} - -@kotlin.Metadata -public final class LambdaTestKt { - // source: 'LambdaTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LateinitPropertiesTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/LateinitPropertiesTest.txt deleted file mode 100644 index c13986805b0..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LateinitPropertiesTest.txt +++ /dev/null @@ -1,31 +0,0 @@ -@kotlin.Metadata -final class LateinitPropertiesTest$Data { - // source: 'LateinitPropertiesTest.kt' - private final field n: int - public method (p0: int): void - public final method getN(): int - private final inner class LateinitPropertiesTest$Data -} - -@kotlin.Metadata -public final class LateinitPropertiesTest { - // source: 'LateinitPropertiesTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field dataRef$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field dataRef: java.lang.Object - private final static @org.jetbrains.annotations.NotNull field head$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field head: java.lang.Object - private final @org.jetbrains.annotations.NotNull field lateIntArr: java.util.concurrent.atomic.AtomicIntegerArray - private final @org.jetbrains.annotations.NotNull field lateRefArr: java.util.concurrent.atomic.AtomicReferenceArray - static method (): void - public method (): void - public final method test(): void - private final inner class LateinitPropertiesTest$Data -} - -@kotlin.Metadata -public final class LateinitPropertiesTestKt { - // source: 'LateinitPropertiesTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeQueueTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeQueueTest.txt deleted file mode 100644 index af4fddb8a6e..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeQueueTest.txt +++ /dev/null @@ -1,41 +0,0 @@ -@kotlin.Metadata -final class LockFreeQueue$Node { - // source: 'LockFreeQueueTest.kt' - private final static @org.jetbrains.annotations.NotNull field next$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field next: java.lang.Object - private final field value: int - static method (): void - public method (p0: int): void - public final static @org.jetbrains.annotations.NotNull method getNext$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getNext(): java.lang.Object - public final method getValue(): int - private final inner class LockFreeQueue$Node -} - -@kotlin.Metadata -public final class LockFreeQueue { - // source: 'LockFreeQueueTest.kt' - private final static @org.jetbrains.annotations.NotNull field head$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field head: java.lang.Object - private final static @org.jetbrains.annotations.NotNull field tail$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field tail: java.lang.Object - static method (): void - public method (): void - public final method dequeue(): int - public final method enqueue(p0: int): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final inner class LockFreeQueue$Node -} - -@kotlin.Metadata -public final class LockFreeQueueTest { - // source: 'LockFreeQueueTest.kt' - public method (): void - public final method testBasic(): void -} - -@kotlin.Metadata -public final class LockFreeQueueTestKt { - // source: 'LockFreeQueueTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/LockTest.txt deleted file mode 100644 index f249df2ce79..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LockTest.txt +++ /dev/null @@ -1,18 +0,0 @@ -@kotlin.Metadata -public final class LockTest { - // source: 'LockTest.kt' - private final static @org.jetbrains.annotations.NotNull field inProgressLock$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field inProgressLock: int - static method (): void - public method (): void - public final method testLock(): void -} - -@kotlin.Metadata -public final class LockTestKt { - // source: 'LockTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String - public final static @org.jetbrains.annotations.NotNull method reflectionTest(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.util.Map): java.util.List - private final static method tryAcquire$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): boolean - private final static method tryAcquire$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): boolean -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LoopTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/LoopTest.txt deleted file mode 100644 index b23d837c294..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LoopTest.txt +++ /dev/null @@ -1,66 +0,0 @@ -@kotlin.Metadata -public final class LoopTest$A { - // source: 'LoopTest.kt' - private final @org.jetbrains.annotations.NotNull field s: java.lang.String - public method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void - public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String - public final inner class LoopTest$A -} - -@kotlin.Metadata -public final class LoopTest { - // source: 'LoopTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private final static @org.jetbrains.annotations.NotNull field a1$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a1: int - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field b$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field b: int - private final static @org.jetbrains.annotations.NotNull field l$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field l: long - private final static @org.jetbrains.annotations.NotNull field r$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field r: java.lang.Object - private final static @org.jetbrains.annotations.NotNull field rs$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field rs: java.lang.Object - static method (): void - public method (): void - public final method atomicfuBooleanLoopTest(): void - public final method atomicfuGetAndUpdateTest(): void - public final method atomicfuIntLoopTest(): void - public final method atomicfuLongLoopTest(): void - public final method atomicfuLoopTest(): void - public final method atomicfuRefLoopTest(): void - public final method atomicfuUpdateAndGetTest(): void - public final method atomicfuUpdateTest(): void - public final static @org.jetbrains.annotations.NotNull method getA$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA(): int - public final static @org.jetbrains.annotations.NotNull method getA1$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getA1(): int - private final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): int - private final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): long - private final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object - public final static @org.jetbrains.annotations.NotNull method getB$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public final method getB(): int - public final static @org.jetbrains.annotations.NotNull method getL$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater - public final method getL(): long - public final static @org.jetbrains.annotations.NotNull method getR$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getR(): java.lang.Object - public final static @org.jetbrains.annotations.NotNull method getRs$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getRs(): java.lang.Object - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void - private final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): int - private final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): long - private final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object - public final inner class LoopTest$A -} - -@kotlin.Metadata -public final class LoopTestKt { - // source: 'LoopTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ParameterizedInlineFunExtensionTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/ParameterizedInlineFunExtensionTest.txt deleted file mode 100644 index 588167a0fe3..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ParameterizedInlineFunExtensionTest.txt +++ /dev/null @@ -1,19 +0,0 @@ -@kotlin.Metadata -public final class ParameterizedInlineFunExtensionTest { - // source: 'ParameterizedInlineFunExtensionTest.kt' - private final static @org.jetbrains.annotations.NotNull field tail$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field tail: java.lang.Object - static method (): void - public method (): void - private final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.Object, p4: java.lang.Object): java.lang.Object - private final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.Object, p3: java.lang.Object): java.lang.Object - private final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.Object, p4: java.lang.Object, p5: kotlin.jvm.functions.Function1): java.lang.Object - private final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.Object, p3: java.lang.Object, p4: kotlin.jvm.functions.Function1): java.lang.Object - public final method testClose(): void -} - -@kotlin.Metadata -public final class ParameterizedInlineFunExtensionTestKt { - // source: 'ParameterizedInlineFunExtensionTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/PropertyDeclarationTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/PropertyDeclarationTest.txt deleted file mode 100644 index 756bd516c71..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/PropertyDeclarationTest.txt +++ /dev/null @@ -1,19 +0,0 @@ -@kotlin.Metadata -public final class PropertyDeclarationTest { - // source: 'PropertyDeclarationTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field head$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field head: java.lang.Object - private final @org.jetbrains.annotations.NotNull field lateIntArr: java.util.concurrent.atomic.AtomicIntegerArray - private final @org.jetbrains.annotations.NotNull field lateRefArr: java.util.concurrent.atomic.AtomicReferenceArray - static method (): void - public method (): void - public final method test(): void -} - -@kotlin.Metadata -public final class PropertyDeclarationTestKt { - // source: 'PropertyDeclarationTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/TopLevelTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/TopLevelTest.txt deleted file mode 100644 index 9ecb4924289..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/TopLevelTest.txt +++ /dev/null @@ -1,145 +0,0 @@ -@kotlin.Metadata -final class A$TopLevelTest$VolatileWrapper { - // source: 'TopLevelTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getA$FU$p(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater -} - -@kotlin.Metadata -public final class ANode { - // source: 'TopLevelTest.kt' - private final field b: java.lang.Object - public method (p0: java.lang.Object): void - public final method component1(): java.lang.Object - public synthetic static method copy$default(p0: ANode, p1: java.lang.Object, p2: int, p3: java.lang.Object): ANode - public final @org.jetbrains.annotations.NotNull method copy(p0: java.lang.Object): ANode - public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean - public final method getB(): java.lang.Object - public method hashCode(): int - public @org.jetbrains.annotations.NotNull method toString(): java.lang.String -} - -@kotlin.Metadata -final class AbcNode$TopLevelTest$VolatileWrapper { - // source: 'TopLevelTest.kt' - private final static @org.jetbrains.annotations.NotNull field abcNode$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field abcNode: java.lang.Object - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getAbcNode$FU$p(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater -} - -@kotlin.Metadata -final class Any$TopLevelTest$VolatileWrapper { - // source: 'TopLevelTest.kt' - private final static @org.jetbrains.annotations.NotNull field any$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field any: java.lang.Object - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getAny$FU$p(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater -} - -@kotlin.Metadata -final class B$TopLevelTest$VolatileWrapper { - // source: 'TopLevelTest.kt' - private final static @org.jetbrains.annotations.NotNull field b$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field b: long - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getB$FU$p(): java.util.concurrent.atomic.AtomicLongFieldUpdater -} - -@kotlin.Metadata -public final class BNode { - // source: 'TopLevelTest.kt' - private final field c: java.lang.Object - public method (p0: java.lang.Object): void - public final method component1(): java.lang.Object - public synthetic static method copy$default(p0: BNode, p1: java.lang.Object, p2: int, p3: java.lang.Object): BNode - public final @org.jetbrains.annotations.NotNull method copy(p0: java.lang.Object): BNode - public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean - public final method getC(): java.lang.Object - public method hashCode(): int - public @org.jetbrains.annotations.NotNull method toString(): java.lang.String -} - -@kotlin.Metadata -final class C$TopLevelTest$VolatileWrapper { - // source: 'TopLevelTest.kt' - private final static @org.jetbrains.annotations.NotNull field c$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field c: int - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getC$FU$p(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater -} - -@kotlin.Metadata -public final class CNode { - // source: 'TopLevelTest.kt' - private final field d: int - public method (p0: int): void - public final method component1(): int - public synthetic static method copy$default(p0: CNode, p1: int, p2: int, p3: java.lang.Object): CNode - public final @org.jetbrains.annotations.NotNull method copy(p0: int): CNode - public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean - public final method getD(): int - public method hashCode(): int - public @org.jetbrains.annotations.NotNull method toString(): java.lang.String -} - -@kotlin.Metadata -public final class TopLevelArrayTest { - // source: 'TopLevelTest.kt' - public method (): void - public final method testBooleanArray(): void - public final method testIntArray(): void - public final method testLongArray(): void - public final method testRefArray(): void -} - -@kotlin.Metadata -public final class TopLevelPrimitiveTest { - // source: 'TopLevelTest.kt' - public method (): void - public final method testTopLevelArrayOfNulls(): void - public final method testTopLevelBoolean(): void - public final method testTopLevelInt(): void - public final method testTopLevelLong(): void - public final method testTopLevelRef(): void -} - -@kotlin.Metadata -public final class TopLevelTestKt { - // source: 'TopLevelTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$TopLevelTest$VolatileWrapper: A$TopLevelTest$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field abcNode$TopLevelTest$VolatileWrapper: AbcNode$TopLevelTest$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field any$TopLevelTest$VolatileWrapper: Any$TopLevelTest$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field anyRefArr: java.util.concurrent.atomic.AtomicReferenceArray - private final static @org.jetbrains.annotations.NotNull field b$TopLevelTest$VolatileWrapper: B$TopLevelTest$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field booleanArr: java.util.concurrent.atomic.AtomicIntegerArray - private final static @org.jetbrains.annotations.NotNull field c$TopLevelTest$VolatileWrapper: C$TopLevelTest$VolatileWrapper - private final static @org.jetbrains.annotations.NotNull field intArr: java.util.concurrent.atomic.AtomicIntegerArray - private final static @org.jetbrains.annotations.NotNull field longArr: java.util.concurrent.atomic.AtomicLongArray - private final static @org.jetbrains.annotations.NotNull field refArr: java.util.concurrent.atomic.AtomicReferenceArray - private final static @org.jetbrains.annotations.NotNull field stringAtomicNullArr: java.util.concurrent.atomic.AtomicReferenceArray - static method (): void - public synthetic final static method access$getA$TopLevelTest$VolatileWrapper$p(): A$TopLevelTest$VolatileWrapper - public synthetic final static method access$getAbcNode$TopLevelTest$VolatileWrapper$p(): AbcNode$TopLevelTest$VolatileWrapper - public synthetic final static method access$getAny$TopLevelTest$VolatileWrapper$p(): Any$TopLevelTest$VolatileWrapper - public synthetic final static method access$getB$TopLevelTest$VolatileWrapper$p(): B$TopLevelTest$VolatileWrapper - public synthetic final static method access$getBooleanArr$p(): java.util.concurrent.atomic.AtomicIntegerArray - public synthetic final static method access$getC$TopLevelTest$VolatileWrapper$p(): C$TopLevelTest$VolatileWrapper - public synthetic final static method access$getIntArr$p(): java.util.concurrent.atomic.AtomicIntegerArray - public synthetic final static method access$getLongArr$p(): java.util.concurrent.atomic.AtomicLongArray - public synthetic final static method access$getRefArr$p(): java.util.concurrent.atomic.AtomicReferenceArray - public synthetic final static method access$getStringAtomicNullArr$p(): java.util.concurrent.atomic.AtomicReferenceArray - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/TraceTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/TraceTest.txt deleted file mode 100644 index c3c1ecf2050..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/TraceTest.txt +++ /dev/null @@ -1,46 +0,0 @@ -@kotlin.Metadata -final enum class TraceTest$Status { - // source: 'TraceTest.kt' - private synthetic final static field $ENTRIES: kotlin.enums.EnumEntries - private synthetic final static field $VALUES: TraceTest$Status[] - public final enum static field END: TraceTest$Status - public final enum static field START: TraceTest$Status - private synthetic final static method $values(): TraceTest$Status[] - static method (): void - private method (p0: java.lang.String, p1: int): void - public static @org.jetbrains.annotations.NotNull method getEntries(): kotlin.enums.EnumEntries - public static method valueOf(p0: java.lang.String): TraceTest$Status - public static method values(): TraceTest$Status[] - private final inner class TraceTest$Status -} - -@kotlin.Metadata -public final class TraceTest { - // source: 'TraceTest.kt' - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private final static @org.jetbrains.annotations.NotNull field a1$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a1: int - private final static @org.jetbrains.annotations.NotNull field a2$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a2: int - private final static @org.jetbrains.annotations.NotNull field a3$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a3: int - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field s$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field s: int - static method (): void - public method (): void - public final method test(): void - public final method testDefaultTrace(): void - public final method testMultipleAppend(): void - public final method testNamedTrace(): void - public final method testTraceInBlock(): void - public final method testTraceWithFormat(): void - public final method testTraceWithSize(): void - private final inner class TraceTest$Status -} - -@kotlin.Metadata -public final class TraceTestKt { - // source: 'TraceTest.kt' - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/UncheckedCastTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/UncheckedCastTest.txt deleted file mode 100644 index d8cad8d3b50..00000000000 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/UncheckedCastTest.txt +++ /dev/null @@ -1,54 +0,0 @@ -@kotlin.Metadata -final class TopLevelS$UncheckedCastTest$VolatileWrapper { - // source: 'UncheckedCastTest.kt' - private final static @org.jetbrains.annotations.NotNull field topLevelS$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field topLevelS: java.lang.Object - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$getTopLevelS$FU$p(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater -} - -@kotlin.Metadata -final class UncheckedCastTest$Box { - // source: 'UncheckedCastTest.kt' - private final field b: int - public method (p0: int): void - public final method component1(): int - public synthetic static method copy$default(p0: UncheckedCastTest$Box, p1: int, p2: int, p3: java.lang.Object): UncheckedCastTest$Box - public final @org.jetbrains.annotations.NotNull method copy(p0: int): UncheckedCastTest$Box - public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean - public final method getB(): int - public method hashCode(): int - public @org.jetbrains.annotations.NotNull method toString(): java.lang.String - private final inner class UncheckedCastTest$Box -} - -@kotlin.Metadata -public final class UncheckedCastTest { - // source: 'UncheckedCastTest.kt' - private final @org.jetbrains.annotations.NotNull field a: java.util.concurrent.atomic.AtomicReferenceArray - private final static @org.jetbrains.annotations.NotNull field bs$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field bs: java.lang.Object - private final static @org.jetbrains.annotations.NotNull field s$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field s: java.lang.Object - static method (): void - public method (): void - private final method getString$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int): java.lang.String - private final method getString$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater): java.lang.String - public final method testArrayValueUncheckedCast(): void - public final method testArrayValueUncheckedCastInlineFunc(): void - public final method testAtomicValUncheckedCast(): void - public final method testInlineFunc(): void - public final method testTopLevelValUnchekedCast(): void - private final inner class UncheckedCastTest$Box -} - -@kotlin.Metadata -public final class UncheckedCastTestKt { - // source: 'UncheckedCastTest.kt' - private final static @org.jetbrains.annotations.NotNull field topLevelS$UncheckedCastTest$VolatileWrapper: TopLevelS$UncheckedCastTest$VolatileWrapper - static method (): void - public synthetic final static method access$getTopLevelS$UncheckedCastTest$VolatileWrapper$p(): TopLevelS$UncheckedCastTest$VolatileWrapper - public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.kt similarity index 92% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.kt index d8c04b62542..098ea73f7a1 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayInlineExtensionTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.kt @@ -2,10 +2,10 @@ import kotlinx.atomicfu.* import kotlin.test.* class ArrayInlineExtensionTest { - val intArr = AtomicIntArray(10) - val a = atomic(100) - val longArr = AtomicLongArray(10) - val refArr = atomicArrayOfNulls(5) + private val intArr = AtomicIntArray(10) + private val a = atomic(100) + private val longArr = AtomicLongArray(10) + private val refArr = atomicArrayOfNulls(5) class A(val s: String) diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.txt new file mode 100644 index 00000000000..f581317b733 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayInlineExtensionTest.txt @@ -0,0 +1,51 @@ +@kotlin.Metadata +public final class ArrayInlineExtensionTest$A { + // source: 'ArrayInlineExtensionTest.kt' + private final @org.jetbrains.annotations.NotNull field s: java.lang.String + public method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String + public final inner class ArrayInlineExtensionTest$A +} + +@kotlin.Metadata +public final class ArrayInlineExtensionTest { + // source: 'ArrayInlineExtensionTest.kt' + private synthetic final static field a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field a$volatile: int + private synthetic final field intArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final field longArr: java.util.concurrent.atomic.AtomicLongArray + private synthetic final field refArr: java.util.concurrent.atomic.AtomicReferenceArray + static method (): void + public method (): void + private synthetic final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private final method casLoop(p0: int): int + private final method casLoopExpression(p0: long): long + private synthetic final method extensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method extensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final method extensionLoopExpression$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method extensionLoopExpression$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final method extensionLoopMixedReceivers$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int, p4: int, p5: int): int + private synthetic final method extensionLoopMixedReceivers$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int, p3: int, p4: int): int + private synthetic final method extensionLoopRecursive$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method extensionLoopRecursive$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final method getLongArr(): java.util.concurrent.atomic.AtomicLongArray + private synthetic final method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicLongArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method setA$volatile(p0: int): void + public final method testIntExtensionLoops(): void + public final inner class ArrayInlineExtensionTest$A +} + +@kotlin.Metadata +public final class ArrayInlineExtensionTestKt { + // source: 'ArrayInlineExtensionTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayLoopTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayLoopTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayLoopTest.txt similarity index 58% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayLoopTest.txt index eb70ee53b41..5207316ef39 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ArrayLoopTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ArrayLoopTest.txt @@ -16,18 +16,20 @@ final class ArrayInlineFunctionTest$Box { @kotlin.Metadata public final class ArrayInlineFunctionTest { // source: 'ArrayLoopTest.kt' - private final @org.jetbrains.annotations.NotNull field anyArr: java.util.concurrent.atomic.AtomicReferenceArray - private final @org.jetbrains.annotations.NotNull field refArr: java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final field anyArr: java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final field refArr: java.util.concurrent.atomic.AtomicReferenceArray public method (): void private final method action(p0: ArrayInlineFunctionTest$Box): ArrayInlineFunctionTest$Box - private final method getAndUpdate$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object - private final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final method getAndUpdate$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object + private synthetic final method getAnyArr(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void public final method testArrayElementGetAndUpdate(): void public final method testArrayElementUpdate(): void public final method testArrayElementUpdateAndGet(): void public final method testSetArrayElementValueInLoop(): void - private final method update$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void - private final method updateAndGet$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object + private synthetic final method update$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final method updateAndGet$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object private final inner class ArrayInlineFunctionTest$Box } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.kt similarity index 87% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.kt index 98c356b5a4f..b9483138505 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ComplexLoopTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.kt @@ -2,11 +2,11 @@ import kotlinx.atomicfu.* import kotlin.test.* class LoopTest { - val a = atomic(10) - val b = atomic(11) - val c = atomic(12) - val r = atomic("aaa") - val intArr = AtomicIntArray(10) + private val a = atomic(10) + private val b = atomic(11) + private val c = atomic(12) + private val r = atomic("aaa") + private val intArr = AtomicIntArray(10) private inline fun AtomicInt.extensionEmbeddedLoops(to: Int): Int = loop { cur1 -> diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.txt new file mode 100644 index 00000000000..0690a5ab88f --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ComplexLoopTest.txt @@ -0,0 +1,48 @@ +@kotlin.Metadata +public final class ComplexLoopTestKt { + // source: 'ComplexLoopTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} + +@kotlin.Metadata +public final class LoopTest { + // source: 'ComplexLoopTest.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 c$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field c$volatile: int + private synthetic final field intArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static field r$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field r$volatile: java.lang.Object + static method (): void + public method (): void + private final method embeddedLoops(p0: int): int + private final method embeddedUpdate(p0: int): int + private synthetic final method extensionEmbeddedLoops$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method extensionEmbeddedLoops$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final method extesntionEmbeddedRefUpdate$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.String): java.lang.String + private synthetic final method extesntionEmbeddedRefUpdate$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.String): java.lang.String + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getB$volatile(): int + private synthetic final static method getC$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getC$volatile(): int + private synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static method getR$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getR$volatile(): java.lang.Object + private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setB$volatile(p0: int): void + private synthetic final method setC$volatile(p0: int): void + private synthetic final method setR$volatile(p0: java.lang.Object): void + public final method test(): void + private synthetic final method updateAndGet$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): java.lang.Object + private synthetic final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): int + private synthetic final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionLoopTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.kt similarity index 91% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionLoopTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.kt index ec5acaa494d..a173e1af192 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionLoopTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.kt @@ -2,12 +2,12 @@ import kotlinx.atomicfu.* import kotlin.test.* class LoopTest { - val a = atomic(0) - val a1 = atomic(1) - val b = atomic(true) - val l = atomic(5000000000) - val r = atomic(A("aaaa")) - val rs = atomic("bbbb") + private val a = atomic(0) + private val a1 = atomic(1) + private val b = atomic(true) + private val l = atomic(5000000000) + private val r = atomic(A("aaaa")) + private val rs = atomic("bbbb") class A(val s: String) diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.txt new file mode 100644 index 00000000000..fa31979f898 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionLoopTest.txt @@ -0,0 +1,91 @@ +@kotlin.Metadata +synthetic final class ExtensionLoopTest$VolatileWrapper$atomicfu$private { + // source: 'ExtensionLoopTest.kt' + private synthetic final static field ref$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field ref$volatile: java.lang.Object + static method (): void + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$getRef$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final static method getRef$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getRef$volatile(): java.lang.Object + private synthetic final method setRef$volatile(p0: java.lang.Object): void +} + +@kotlin.Metadata +public final class ExtensionLoopTestKt { + // source: 'ExtensionLoopTest.kt' + private synthetic final static field extensionLoopTest$VolatileWrapper$atomicfu$private: ExtensionLoopTest$VolatileWrapper$atomicfu$private + static method (): void + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + private synthetic final static method getExtensionLoopTest$VolatileWrapper$atomicfu$private(): ExtensionLoopTest$VolatileWrapper$atomicfu$private + private synthetic final static method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicReferenceArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final static method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + public final static method testTopLevelExtensionLoop(): void + private synthetic final static method topLevelExtensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.String): java.lang.String + private synthetic final static method topLevelExtensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.String): java.lang.String +} + +@kotlin.Metadata +public final class LoopTest$A { + // source: 'ExtensionLoopTest.kt' + private final @org.jetbrains.annotations.NotNull field s: java.lang.String + public method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String + public final inner class LoopTest$A +} + +@kotlin.Metadata +public final class LoopTest { + // source: 'ExtensionLoopTest.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 a1$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field a1$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 r$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field r$volatile: java.lang.Object + private synthetic final static field rs$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field rs$volatile: java.lang.Object + static method (): void + public method (): void + private synthetic final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private final method casLoop(p0: int): int + private final method casLoopExpression(p0: int): int + private synthetic final method extensionLoop$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method extensionLoop$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final method extensionLoopExpression$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method extensionLoopExpression$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final method extensionLoopMixedReceivers$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int, p4: int): int + private synthetic final method extensionLoopMixedReceivers$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int, p3: int): int + private synthetic final method extensionLoopRecursive$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method extensionLoopRecursive$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int, p3: int): int + private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p2: int): int + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getA1$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA1$volatile(): int + private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getB$volatile(): int + private synthetic final static method getL$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getL$volatile(): long + private synthetic final static method getR$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getR$volatile(): java.lang.Object + private synthetic final static method getRs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getRs$volatile(): java.lang.Object + private synthetic final method loop$atomicfu$array(p0: java.util.concurrent.atomic.AtomicIntegerArray, p1: int, p2: kotlin.jvm.functions.Function1): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setA1$volatile(p0: int): void + private synthetic final method setB$volatile(p0: int): void + private synthetic final method setL$volatile(p0: long): void + private synthetic final method setR$volatile(p0: java.lang.Object): void + private synthetic final method setRs$volatile(p0: java.lang.Object): void + public final method testIntExtensionLoops(): void + public final inner class LoopTest$A +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionsTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.kt similarity index 88% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionsTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.kt index 510f90de785..eba2ff76901 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ExtensionsTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.kt @@ -2,10 +2,10 @@ import kotlinx.atomicfu.* import kotlin.test.* class ExtensionsTest { - val a = atomic(0) - val l = atomic(0L) - val s = atomic(null) - val b = atomic(true) + private val a = atomic(0) + private val l = atomic(0L) + private val s = atomic(null) + private val b = atomic(true) fun testScopedFieldGetters() { check(a.value == 0) @@ -31,7 +31,7 @@ class ExtensionsTest { check(a.compareAndSet(7, 10)) } - inline fun AtomicInt.intExtensionArithmetic() { + private inline fun AtomicInt.intExtensionArithmetic() { value = 0 check(value == 0) val update = 3 @@ -58,7 +58,7 @@ class ExtensionsTest { check(value == 55) } - inline fun AtomicLong.longExtensionArithmetic() { + private inline fun AtomicLong.longExtensionArithmetic() { value = 2424920024888888848 check(value == 2424920024888888848) lazySet(8424920024888888848) @@ -79,7 +79,7 @@ class ExtensionsTest { check(value == -198452011965886959) } - inline fun AtomicRef.refExtension() { + private inline fun AtomicRef.refExtension() { value = "aaa" check(value == "aaa") lazySet("bb") @@ -88,7 +88,7 @@ class ExtensionsTest { check(value == "ccc") } - inline fun AtomicBoolean.booleanExtensionArithmetic() { + private inline fun AtomicBoolean.booleanExtensionArithmetic() { value = false check(!value) lazySet(true) @@ -112,4 +112,4 @@ fun box(): String { testClass.testScopedFieldGetters() testClass.testExtension() return "OK" -} \ No newline at end of file +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.txt new file mode 100644 index 00000000000..d2648cd715a --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ExtensionsTest.txt @@ -0,0 +1,42 @@ +@kotlin.Metadata +public final class ExtensionsTest { + // source: 'ExtensionsTest.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 s$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field s$volatile: java.lang.Object + static method (): void + public method (): void + private synthetic final method booleanExtensionArithmetic$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): void + private synthetic final method booleanExtensionArithmetic$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): void + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getB$volatile(): int + private synthetic final static method getL$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getL$volatile(): long + private synthetic final static method getS$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getS$volatile(): java.lang.Object + private synthetic final method intExtensionArithmetic$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): void + private synthetic final method intExtensionArithmetic$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): void + private synthetic final method longExtensionArithmetic$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicLongArray, p2: int): void + private synthetic final method longExtensionArithmetic$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicLongFieldUpdater): void + private synthetic final method refExtension$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int): void + private synthetic final method refExtension$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater): void + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setB$volatile(p0: int): void + private synthetic final method setL$volatile(p0: long): void + private synthetic final method setS$volatile(p0: java.lang.Object): void + public final method testExtension(): void + public final method testScopedFieldGetters(): void +} + +@kotlin.Metadata +public final class ExtensionsTestKt { + // source: 'ExtensionsTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/InlineExtensionWithTypeParameterTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.kt similarity index 93% rename from plugins/atomicfu/atomicfu-compiler/testData/box/InlineExtensionWithTypeParameterTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.kt index ea58420875e..0c7f0108398 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/InlineExtensionWithTypeParameterTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.kt @@ -18,7 +18,7 @@ class InlineExtensionWithTypeParameterTest { return cur.id } - val sref = atomic(SemaphoreSegment(0)) + private val sref = atomic(SemaphoreSegment(0)) fun testInlineExtensionWithTypeParameter() { val s = SemaphoreSegment(77) @@ -30,4 +30,4 @@ fun box(): String { val testClass = InlineExtensionWithTypeParameterTest() testClass.testInlineExtensionWithTypeParameter() return "OK" -} \ No newline at end of file +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/InlineExtensionWithTypeParameterTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.txt similarity index 62% rename from plugins/atomicfu/atomicfu-compiler/testData/box/InlineExtensionWithTypeParameterTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.txt index 1489d3e2367..94a82de93a4 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/InlineExtensionWithTypeParameterTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/InlineExtensionWithTypeParameterTest.txt @@ -18,15 +18,16 @@ public final class InlineExtensionWithTypeParameterTest$SemaphoreSegment { @kotlin.Metadata public final class InlineExtensionWithTypeParameterTest { // source: 'InlineExtensionWithTypeParameterTest.kt' - private final static @org.jetbrains.annotations.NotNull field sref$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field sref: java.lang.Object + private synthetic final static field sref$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field sref$volatile: java.lang.Object static method (): void public method (): void - private final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: int, p4: InlineExtensionWithTypeParameterTest$Segment): int - private final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: int, p3: InlineExtensionWithTypeParameterTest$Segment): int + private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: int, p4: InlineExtensionWithTypeParameterTest$Segment): int + private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: int, p3: InlineExtensionWithTypeParameterTest$Segment): int private final method getSegmentId(p0: InlineExtensionWithTypeParameterTest$Segment): int - public final static @org.jetbrains.annotations.NotNull method getSref$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getSref(): java.lang.Object + private synthetic final static method getSref$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getSref$volatile(): java.lang.Object + private synthetic final method setSref$volatile(p0: java.lang.Object): void public final method testInlineExtensionWithTypeParameter(): void public abstract inner class InlineExtensionWithTypeParameterTest$Segment public final inner class InlineExtensionWithTypeParameterTest$SemaphoreSegment diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.kt new file mode 100644 index 00000000000..fef5c847a01 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.kt @@ -0,0 +1,52 @@ +import kotlinx.atomicfu.* +import kotlin.test.* + +class LambdaTest { + private val a = atomic(0) + private val rs = atomic("bbbb") + + private inline fun inlineLambda( + arg: T, + crossinline block: (T) -> Unit + ) = block(arg) + + fun loopInLambda1(to: Int) = inlineLambda(to) sc@ { arg -> + a.loop { value -> + a.compareAndSet(value, arg) + return@sc + } + } + + fun loopInLambda2(to: Int) = inlineLambda(to) { arg1 -> + inlineLambda(arg1) sc@ { arg2 -> + a.loop { value -> + a.compareAndSet(value, arg2) + return@sc + } + } + } + + fun loopInLambda2Ref(to: String) = inlineLambda(to) { arg1 -> + inlineLambda(arg1) sc@ { arg2 -> + rs.loop { value -> + rs.compareAndSet(value, arg2) + return@sc + } + } + } + + fun test() { + loopInLambda1(34) + assertEquals(34, a.value) + loopInLambda1(77) + assertEquals(77, a.value) + loopInLambda2Ref("bbb") + assertEquals("bbb", rs.value) + } +} + +fun box(): String { + val testClass = LambdaTest() + testClass.test() + return "OK" +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.txt new file mode 100644 index 00000000000..b61e4dc0540 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LambdaTest.txt @@ -0,0 +1,31 @@ +@kotlin.Metadata +public final class LambdaTest { + // source: 'LambdaTest.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 rs$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field rs$volatile: java.lang.Object + static method (): void + public method (): void + public synthetic final static method access$getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + public synthetic final static method access$getRs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getRs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getRs$volatile(): java.lang.Object + private final method inlineLambda(p0: java.lang.Object, p1: kotlin.jvm.functions.Function1): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + public final method loopInLambda1(p0: int): void + public final method loopInLambda2(p0: int): void + public final method loopInLambda2Ref(@org.jetbrains.annotations.NotNull p0: java.lang.String): void + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setRs$volatile(p0: java.lang.Object): void + public final method test(): void +} + +@kotlin.Metadata +public final class LambdaTestKt { + // source: 'LambdaTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeIntBitsTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockFreeIntBitsTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeIntBitsTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockFreeIntBitsTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeIntBitsTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockFreeIntBitsTest.txt similarity index 58% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeIntBitsTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockFreeIntBitsTest.txt index e3bcbb142ac..09965886ab4 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeIntBitsTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockFreeIntBitsTest.txt @@ -1,16 +1,19 @@ @kotlin.Metadata public final class LockFreeIntBits { // source: 'LockFreeIntBitsTest.kt' - private final static @org.jetbrains.annotations.NotNull field bits$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field bits: int + private synthetic final static field bits$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field bits$volatile: int static method (): void public method (): void public final method bitClear(p0: int): boolean public final method bitSet(p0: int): boolean private final method bitUpdate(p0: kotlin.jvm.functions.Function1, p1: kotlin.jvm.functions.Function1): boolean public final method get(p0: int): boolean + private synthetic final static method getBits$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getBits$volatile(): int private final method mask(p0: int): int - private final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method setBits$volatile(p0: int): void + private synthetic final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void } @kotlin.Metadata diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockTest.txt new file mode 100644 index 00000000000..f8bbbe09d17 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/LockTest.txt @@ -0,0 +1,21 @@ +@kotlin.Metadata +public final class LockTest { + // source: 'LockTest.kt' + private synthetic final static field inProgressLock$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field inProgressLock$volatile: int + static method (): void + public method (): void + private synthetic final static method getInProgressLock$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getInProgressLock$volatile(): int + private synthetic final method setInProgressLock$volatile(p0: int): void + public final method testLock(): void +} + +@kotlin.Metadata +public final class LockTestKt { + // source: 'LockTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static @org.jetbrains.annotations.NotNull method reflectionTest(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.util.Map): java.util.List + private synthetic final static method tryAcquire$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerArray, p2: int): boolean + private synthetic final static method tryAcquire$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicIntegerFieldUpdater): boolean +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ParameterizedInlineFunExtensionTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ParameterizedInlineFunExtensionTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ParameterizedInlineFunExtensionTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ParameterizedInlineFunExtensionTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ParameterizedInlineFunExtensionTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ParameterizedInlineFunExtensionTest.txt new file mode 100644 index 00000000000..21a6583aa3e --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomic_extensions/ParameterizedInlineFunExtensionTest.txt @@ -0,0 +1,22 @@ +@kotlin.Metadata +public final class ParameterizedInlineFunExtensionTest { + // source: 'ParameterizedInlineFunExtensionTest.kt' + private synthetic final static field tail$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field tail$volatile: java.lang.Object + static method (): void + public method (): void + private synthetic final method bar$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.Object, p4: java.lang.Object): java.lang.Object + private synthetic final method bar$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.Object, p3: java.lang.Object): java.lang.Object + private synthetic final method foo$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int, p3: java.lang.Object, p4: java.lang.Object, p5: kotlin.jvm.functions.Function1): java.lang.Object + private synthetic final method foo$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p2: java.lang.Object, p3: java.lang.Object, p4: kotlin.jvm.functions.Function1): java.lang.Object + private synthetic final static method getTail$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getTail$volatile(): java.lang.Object + private synthetic final method setTail$volatile(p0: java.lang.Object): void + public final method testClose(): void +} + +@kotlin.Metadata +public final class ParameterizedInlineFunExtensionTestKt { + // source: 'ParameterizedInlineFunExtensionTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.kt new file mode 100644 index 00000000000..8bc59d0bd26 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.kt @@ -0,0 +1,130 @@ +import kotlinx.atomicfu.* +import kotlin.test.* + +class IntArithmetic { + private val _x = atomic(0) + val x get() = _x.value + + private val local = atomic(0) + + private fun testGetValue() { + _x.value = 5 + assertEquals(5, _x.value) + var aValue = _x.value + assertEquals(5, aValue) + assertEquals(5, x) + + local.value = 555 + aValue = local.value + assertEquals(aValue, local.value) + } + + private fun testAtomicCallPlaces() { + _x.value = 5 + _x.compareAndSet(5, 42) + val res = _x.compareAndSet(42, 45) + assertTrue(res) + assertTrue(_x.compareAndSet(45, 77)) + assertFalse(_x.compareAndSet(95, 77)) + assertTrue(_x.compareAndSet(77, 88)) + } + + private fun testInt() { + _x.value = 0 + assertEquals(0, x) + val update = 3 + assertEquals(0, _x.getAndSet(update)) + assertTrue(_x.compareAndSet(update, 8)) + _x.lazySet(1) + assertEquals(1, x) + assertEquals(1, _x.getAndSet(2)) + assertEquals(2, x) + assertEquals(2, _x.getAndIncrement()) + assertEquals(3, x) + assertEquals(3, _x.getAndDecrement()) + assertEquals(2, x) + assertEquals(2, _x.getAndAdd(2)) + assertEquals(4, x) + assertEquals(7, _x.addAndGet(3)) + assertEquals(7, x) + assertEquals(8, _x.incrementAndGet()) + assertEquals(8, x) + assertEquals(7, _x.decrementAndGet()) + assertEquals(7, x) + assertTrue(_x.compareAndSet(7, 10)) + } + + fun test() { + testGetValue() + testAtomicCallPlaces() + testInt() + } +} + +class LongArithmetic { + private val _x = atomic(4294967296) + val x get() = _x.value + private val y = atomic(5000000000) + private val z = atomic(2424920024888888848) + private val max = atomic(9223372036854775807) + + fun testLong() { + assertEquals(2424920024888888848, z.value) + z.lazySet(8424920024888888848) + assertEquals(8424920024888888848, z.value) + assertEquals(8424920024888888848, z.getAndSet(8924920024888888848)) + assertEquals(8924920024888888848, z.value) + assertEquals(8924920024888888849, z.incrementAndGet()) + assertEquals(8924920024888888849, z.value) + assertEquals(8924920024888888849, z.getAndDecrement()) + assertEquals(8924920024888888848, z.value) + assertEquals(8924920024888888848, z.getAndAdd(100000000000000000)) + assertEquals(9024920024888888848, z.value) + assertEquals(-198452011965886959, z.addAndGet(-9223372036854775807)) + assertEquals(-198452011965886959, z.value) + assertEquals(-198452011965886958, z.incrementAndGet()) + assertEquals(-198452011965886958, z.value) + assertEquals(-198452011965886959, z.decrementAndGet()) + assertEquals(-198452011965886959, z.value) + } +} + +class BooleanArithmetic { + private val _x = atomic(false) + val x get() = _x.value + + fun testBoolean() { + assertEquals(false, _x.value) + assertFalse(x) + _x.lazySet(true) + assertTrue(x) + assertTrue(_x.getAndSet(true)) + assertTrue(_x.compareAndSet(true, false)) + assertFalse(x) + } +} + +class ReferenceArithmetic { + private val _x = atomic(null) + + fun testReference() { + _x.value = "aaa" + assertEquals("aaa", _x.value) + _x.lazySet("bb") + assertEquals("bb", _x.value) + assertEquals("bb", _x.getAndSet("ccc")) + assertEquals("ccc", _x.value) + } +} + +fun box(): String { + val intClass = IntArithmetic() + intClass.test() + val longClass = LongArithmetic() + longClass.testLong() + val booleanClass = BooleanArithmetic() + booleanClass.testBoolean() + val refClass = ReferenceArithmetic() + refClass.testReference() + return "OK" +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.txt new file mode 100644 index 00000000000..865928dcc27 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ArithmeticTest.txt @@ -0,0 +1,83 @@ +@kotlin.Metadata +public final class ArithmeticTestKt { + // source: 'ArithmeticTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} + +@kotlin.Metadata +public final class BooleanArithmetic { + // source: 'ArithmeticTest.kt' + private synthetic final static field _x$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field _x$volatile: int + static method (): void + public method (): void + public final method getX(): boolean + private synthetic final static method get_x$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method get_x$volatile(): int + private synthetic final method set_x$volatile(p0: int): void + public final method testBoolean(): void +} + +@kotlin.Metadata +public final class IntArithmetic { + // source: 'ArithmeticTest.kt' + private synthetic final static field _x$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field _x$volatile: int + private synthetic final static field local$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field local$volatile: int + static method (): void + public method (): void + private synthetic final static method getLocal$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getLocal$volatile(): int + public final method getX(): int + private synthetic final static method get_x$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method get_x$volatile(): int + private synthetic final method setLocal$volatile(p0: int): void + private synthetic final method set_x$volatile(p0: int): void + public final method test(): void + private final method testAtomicCallPlaces(): void + private final method testGetValue(): void + private final method testInt(): void +} + +@kotlin.Metadata +public final class LongArithmetic { + // source: 'ArithmeticTest.kt' + private synthetic final static field _x$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field _x$volatile: long + private synthetic final static field max$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field max$volatile: long + private synthetic final static field y$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field y$volatile: long + private synthetic final static field z$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field z$volatile: long + static method (): void + public method (): void + private synthetic final static method getMax$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getMax$volatile(): long + public final method getX(): long + private synthetic final static method getY$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getY$volatile(): long + private synthetic final static method getZ$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getZ$volatile(): long + private synthetic final static method get_x$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method get_x$volatile(): long + private synthetic final method setMax$volatile(p0: long): void + private synthetic final method setY$volatile(p0: long): void + private synthetic final method setZ$volatile(p0: long): void + private synthetic final method set_x$volatile(p0: long): void + public final method testLong(): void +} + +@kotlin.Metadata +public final class ReferenceArithmetic { + // source: 'ArithmeticTest.kt' + private synthetic final static field _x$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field _x$volatile: java.lang.Object + static method (): void + public method (): void + private synthetic final static method get_x$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method get_x$volatile(): java.lang.Object + private synthetic final method set_x$volatile(p0: java.lang.Object): void + public final method testReference(): void +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.kt similarity index 98% rename from plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.kt index c330596016d..1a0678719e0 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/AtomicArrayTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.kt @@ -87,13 +87,13 @@ class AtomicArrayTest { } } -class AtomicArrayClass { +private class AtomicArrayClass { val intArr = AtomicIntArray(10) val longArr = AtomicLongArray(10) val booleanArr = AtomicBooleanArray(10) val refArr = atomicArrayOfNulls(10) val anyArr = atomicArrayOfNulls(10) - val a = atomic(ARef(8)) + internal val a = atomic(ARef(8)) } data class ARef(val n: Int) @@ -106,4 +106,4 @@ fun box(): String { testClass.testRefArray() testClass.testAnyArray() return "OK" -} \ No newline at end of file +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.txt new file mode 100644 index 00000000000..cc1c933569e --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/AtomicArrayTest.txt @@ -0,0 +1,53 @@ +@kotlin.Metadata +public final class ARef { + // source: 'AtomicArrayTest.kt' + private final field n: int + public method (p0: int): void + public final method component1(): int + public synthetic static method copy$default(p0: ARef, p1: int, p2: int, p3: java.lang.Object): ARef + public final @org.jetbrains.annotations.NotNull method copy(p0: int): ARef + public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public final method getN(): int + public method hashCode(): int + public @org.jetbrains.annotations.NotNull method toString(): java.lang.String +} + +@kotlin.Metadata +final class AtomicArrayClass { + // source: 'AtomicArrayTest.kt' + private synthetic final static field a$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field a$volatile: java.lang.Object + private synthetic final field anyArr: java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final field booleanArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final field intArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final field longArr: java.util.concurrent.atomic.AtomicLongArray + private synthetic final field refArr: java.util.concurrent.atomic.AtomicReferenceArray + static method (): void + public method (): void + public synthetic final static method access$getA$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getA$volatile(): java.lang.Object + public synthetic final method getAnyArr(): java.util.concurrent.atomic.AtomicReferenceArray + public synthetic final method getBooleanArr(): java.util.concurrent.atomic.AtomicIntegerArray + public synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + public synthetic final method getLongArr(): java.util.concurrent.atomic.AtomicLongArray + public synthetic final method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final method setA$volatile(p0: java.lang.Object): void +} + +@kotlin.Metadata +public final class AtomicArrayTest { + // source: 'AtomicArrayTest.kt' + public method (): void + public final method testAnyArray(): void + public final method testBooleanArray(): void + public final method testIntArray(): void + public final method testLongArray(): void + public final method testRefArray(): void +} + +@kotlin.Metadata +public final class AtomicArrayTestKt { + // source: 'AtomicArrayTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/IndexArrayElementGetterTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.kt similarity index 96% rename from plugins/atomicfu/atomicfu-compiler/testData/box/IndexArrayElementGetterTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.kt index e2bc18b8518..24b8e400f41 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/IndexArrayElementGetterTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.kt @@ -19,7 +19,7 @@ class IndexArrayElementGetterTest { assertEquals(100, clazz.longArr[(fib(4) + fib(5)) % fib(5)].value) } - class AtomicArrayClass { + private class AtomicArrayClass { val intArr = AtomicIntArray(10) val longArr = AtomicLongArray(10) } @@ -29,4 +29,4 @@ fun box(): String { val testClass = IndexArrayElementGetterTest() testClass.testIndexArrayElementGetting() return "OK" -} \ No newline at end of file +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.txt new file mode 100644 index 00000000000..84d70532157 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/IndexArrayElementGetterTest.txt @@ -0,0 +1,26 @@ +@kotlin.Metadata +final class IndexArrayElementGetterTest$AtomicArrayClass { + // source: 'IndexArrayElementGetterTest.kt' + private synthetic final field intArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final field longArr: java.util.concurrent.atomic.AtomicLongArray + public method (): void + public synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + public synthetic final method getLongArr(): java.util.concurrent.atomic.AtomicLongArray + private final inner class IndexArrayElementGetterTest$AtomicArrayClass +} + +@kotlin.Metadata +public final class IndexArrayElementGetterTest { + // source: 'IndexArrayElementGetterTest.kt' + private final @org.jetbrains.annotations.NotNull field clazz: IndexArrayElementGetterTest$AtomicArrayClass + public method (): void + public final method fib(p0: int): int + public final method testIndexArrayElementGetting(): void + private final inner class IndexArrayElementGetterTest$AtomicArrayClass +} + +@kotlin.Metadata +public final class IndexArrayElementGetterTestKt { + // source: 'IndexArrayElementGetterTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.kt new file mode 100644 index 00000000000..24d208630fb --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.kt @@ -0,0 +1,33 @@ +import kotlinx.atomicfu.* +import kotlin.test.* + +private class AAA { + private val _counter = atomic(5L) + val counterValue: Long get() = _counter.value + val delegateCounterValue by _counter + val lateInitInt: AtomicInt + val intArr: AtomicIntArray + + // test ensures that transformation does not change the order of initialization + init { + lateInitInt = atomic(10) + assertTrue(lateInitInt.compareAndSet(10, 100)) + assertEquals(100, lateInitInt.value) + intArr = AtomicIntArray(10) + intArr[0].value = 10 + assertTrue(intArr[0].compareAndSet(10, 100)) + intArr[1].value = 20 + } + + init { + assertEquals(5L, _counter.value) + assertEquals(5L,counterValue) + assertEquals(5L, delegateCounterValue) + assertEquals(120, intArr[0].value + intArr[1].value) + } +} + +fun box(): String { + val intClass = AAA() + return "OK" +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.txt new file mode 100644 index 00000000000..62b8ab43eca --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/InitializationOrderTest.txt @@ -0,0 +1,26 @@ +@kotlin.Metadata +final class AAA { + // source: 'InitializationOrderTest.kt' + private synthetic final static field _counter$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field _counter$volatile: long + private synthetic final field intArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static field lateInitInt$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field lateInitInt$volatile: int + static method (): void + public method (): void + public final method getCounterValue(): long + public final method getDelegateCounterValue(): long + public synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static method getLateInitInt$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getLateInitInt$volatile(): int + private synthetic final static method get_counter$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method get_counter$volatile(): long + private synthetic final method setLateInitInt$volatile(p0: int): void + private synthetic final method set_counter$volatile(p0: long): void +} + +@kotlin.Metadata +public final class InitializationOrderTestKt { + // source: 'InitializationOrderTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LateinitPropertiesTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LateinitPropertiesTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LateinitPropertiesTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LateinitPropertiesTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LateinitPropertiesTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LateinitPropertiesTest.txt new file mode 100644 index 00000000000..eced37a0fec --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LateinitPropertiesTest.txt @@ -0,0 +1,42 @@ +@kotlin.Metadata +final class LateinitPropertiesTest$Data { + // source: 'LateinitPropertiesTest.kt' + private final field n: int + public method (p0: int): void + public final method getN(): int + private final inner class LateinitPropertiesTest$Data +} + +@kotlin.Metadata +public final class LateinitPropertiesTest { + // source: 'LateinitPropertiesTest.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 dataRef$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field dataRef$volatile: java.lang.Object + private synthetic final static field head$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field head$volatile: java.lang.Object + private synthetic final field lateIntArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final field lateRefArr: java.util.concurrent.atomic.AtomicReferenceArray + static method (): void + public method (): void + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getDataRef$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getDataRef$volatile(): java.lang.Object + private synthetic final static method getHead$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getHead$volatile(): java.lang.Object + private synthetic final method getLateIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final method getLateRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setDataRef$volatile(p0: java.lang.Object): void + private synthetic final method setHead$volatile(p0: java.lang.Object): void + public final method test(): void + private final inner class LateinitPropertiesTest$Data +} + +@kotlin.Metadata +public final class LateinitPropertiesTestKt { + // source: 'LateinitPropertiesTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeLongCounterTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeLongCounterTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeLongCounterTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeLongCounterTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeLongCounterTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeLongCounterTest.txt similarity index 70% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeLongCounterTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeLongCounterTest.txt index 03b022fc381..39a8b4847ea 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeLongCounterTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeLongCounterTest.txt @@ -10,15 +10,18 @@ final class LockFreeLongCounter$Inner { @kotlin.Metadata public final class LockFreeLongCounter { // source: 'LockFreeLongCounterTest.kt' - private final static @org.jetbrains.annotations.NotNull field counter$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field counter: long + private synthetic final static field counter$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field counter$volatile: long static method (): void public method (): void - public synthetic final static method access$getCounter$FU$p(): java.util.concurrent.atomic.AtomicLongFieldUpdater + public synthetic final static method access$getCounter$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater public final method add2(): long public final method get(): long + private synthetic final static method getCounter$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getCounter$volatile(): long public final method getInner(): long public final method increment(): long + private synthetic final method setCounter$volatile(p0: long): void public final method setM2(): void private final inner class LockFreeLongCounter$Inner } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeQueueTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.kt similarity index 99% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeQueueTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.kt index 9d5a8c8df9f..e6dee982547 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeQueueTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.kt @@ -52,4 +52,4 @@ fun box(): String { val testClass = LockFreeQueueTest() testClass.testBasic() return "OK" -} \ No newline at end of file +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.txt new file mode 100644 index 00000000000..3d2004f5de7 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeQueueTest.txt @@ -0,0 +1,49 @@ +@kotlin.Metadata +final class LockFreeQueue$Node { + // source: 'LockFreeQueueTest.kt' + private synthetic final static field next$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field next$volatile: java.lang.Object + private final field value: int + static method (): void + public method (p0: int): void + public synthetic final static method access$getNext$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final static method getNext$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getNext$volatile(): java.lang.Object + public final method getValue(): int + private synthetic final method setNext$volatile(p0: java.lang.Object): void + private final inner class LockFreeQueue$Node +} + +@kotlin.Metadata +public final class LockFreeQueue { + // source: 'LockFreeQueueTest.kt' + private synthetic final static field head$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field head$volatile: java.lang.Object + private synthetic final static field tail$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field tail$volatile: java.lang.Object + static method (): void + public method (): void + public final method dequeue(): int + public final method enqueue(p0: int): void + private synthetic final static method getHead$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getHead$volatile(): java.lang.Object + private synthetic final static method getTail$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getTail$volatile(): java.lang.Object + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method setHead$volatile(p0: java.lang.Object): void + private synthetic final method setTail$volatile(p0: java.lang.Object): void + private final inner class LockFreeQueue$Node +} + +@kotlin.Metadata +public final class LockFreeQueueTest { + // source: 'LockFreeQueueTest.kt' + public method (): void + public final method testBasic(): void +} + +@kotlin.Metadata +public final class LockFreeQueueTestKt { + // source: 'LockFreeQueueTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeStackTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeStackTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeStackTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeStackTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeStackTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeStackTest.txt similarity index 61% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeStackTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeStackTest.txt index 34067762923..bb8914f2b39 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LockFreeStackTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LockFreeStackTest.txt @@ -12,19 +12,22 @@ final class LockFreeStack$Node { @kotlin.Metadata public final class LockFreeStack { // source: 'LockFreeStackTest.kt' - private final static @org.jetbrains.annotations.NotNull field top$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field top: java.lang.Object + private synthetic final static field top$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field top$volatile: java.lang.Object static method (): void public method (): void public final method clear(): void - private final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object + private synthetic final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object + private synthetic final static method getTop$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getTop$volatile(): java.lang.Object public final method isEmpty(): boolean - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void public final @org.jetbrains.annotations.Nullable method popLoop(): java.lang.Object public final @org.jetbrains.annotations.Nullable method popUpdate(): java.lang.Object public final method pushLoop(p0: java.lang.Object): void public final method pushUpdate(p0: java.lang.Object): void - private final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method setTop$volatile(p0: java.lang.Object): void + private synthetic final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void private final inner class LockFreeStack$Node } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/LoopTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.kt similarity index 92% rename from plugins/atomicfu/atomicfu-compiler/testData/box/LoopTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.kt index c0a9b447053..a6a0e0b3dea 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/LoopTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.kt @@ -2,12 +2,12 @@ import kotlinx.atomicfu.* import kotlin.test.* class LoopTest { - val a = atomic(0) - val a1 = atomic(1) - val b = atomic(true) - val l = atomic(5000000000) - val r = atomic(A("aaaa")) - val rs = atomic("bbbb") + private val a = atomic(0) + private val a1 = atomic(1) + private val b = atomic(true) + private val l = atomic(5000000000) + private val r = atomic(A("aaaa")) + private val rs = atomic("bbbb") class A(val s: String) @@ -49,7 +49,7 @@ class LoopTest { } } - inline fun atomicfuLoopTest() { + fun atomicfuLoopTest() { atomicfuIntLoopTest() assertEquals(777, a.value) atomicfuBooleanLoopTest() diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.txt new file mode 100644 index 00000000000..7e5a09a3f54 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/LoopTest.txt @@ -0,0 +1,72 @@ +@kotlin.Metadata +public final class LoopTest$A { + // source: 'LoopTest.kt' + private final @org.jetbrains.annotations.NotNull field s: java.lang.String + public method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String + public final inner class LoopTest$A +} + +@kotlin.Metadata +public final class LoopTest { + // source: 'LoopTest.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 a1$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field a1$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 r$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field r$volatile: java.lang.Object + private synthetic final static field rs$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field rs$volatile: java.lang.Object + static method (): void + public method (): void + public final method atomicfuBooleanLoopTest(): void + public final method atomicfuGetAndUpdateTest(): void + public final method atomicfuIntLoopTest(): void + public final method atomicfuLongLoopTest(): void + public final method atomicfuLoopTest(): void + public final method atomicfuRefLoopTest(): void + public final method atomicfuUpdateAndGetTest(): void + public final method atomicfuUpdateTest(): void + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getA1$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA1$volatile(): int + private synthetic final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): int + private synthetic final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): long + private synthetic final method getAndUpdate$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object + private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getB$volatile(): int + private synthetic final static method getL$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getL$volatile(): long + private synthetic final static method getR$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getR$volatile(): java.lang.Object + private synthetic final static method getRs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getRs$volatile(): java.lang.Object + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setA1$volatile(p0: int): void + private synthetic final method setB$volatile(p0: int): void + private synthetic final method setL$volatile(p0: long): void + private synthetic final method setR$volatile(p0: java.lang.Object): void + private synthetic final method setRs$volatile(p0: java.lang.Object): void + private synthetic final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method update$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): int + private synthetic final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicLongFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): long + private synthetic final method updateAndGet$atomicfu(p0: java.util.concurrent.atomic.AtomicReferenceFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): java.lang.Object + public final inner class LoopTest$A +} + +@kotlin.Metadata +public final class LoopTestKt { + // source: 'LoopTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/MultiInitTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/MultiInitTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/MultiInitTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/MultiInitTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/MultiInitTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/MultiInitTest.txt similarity index 56% rename from plugins/atomicfu/atomicfu-compiler/testData/box/MultiInitTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/MultiInitTest.txt index 544dbac7e40..6ff371547f3 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/MultiInitTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/MultiInitTest.txt @@ -11,14 +11,20 @@ public final class MultiInit$Companion { public final class MultiInit { // source: 'MultiInitTest.kt' public final static @org.jetbrains.annotations.NotNull field Companion: MultiInit$Companion - private final static @org.jetbrains.annotations.NotNull field a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field a: int - private final static @org.jetbrains.annotations.NotNull field b$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field b: int + 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 static method (): void public method (): void + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getB$volatile(): int public final method incA(): int public final method incB(): int + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setB$volatile(p0: int): void public final inner class MultiInit$Companion } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ScopeTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.kt similarity index 96% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ScopeTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.kt index 3ffe02887de..f861829337d 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ScopeTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.kt @@ -23,7 +23,7 @@ class D (val e: E) class E (val x: Int) -class AtomicState(value: Any) { +private class AtomicState(value: Any) { val state = atomic(value) } @@ -42,4 +42,4 @@ fun box(): String { val testClass = ScopeTest() testClass.scopeTest() return "OK" -} \ No newline at end of file +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ScopeTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.txt similarity index 77% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ScopeTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.txt index 73738e2641e..86da734aa5a 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/ScopeTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/ScopeTest.txt @@ -13,14 +13,16 @@ public final class AA { } @kotlin.Metadata -public final class AtomicState { +final class AtomicState { // source: 'ScopeTest.kt' - private final static @org.jetbrains.annotations.NotNull field state$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field state: java.lang.Object + private synthetic final static field state$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field state$volatile: java.lang.Object static method (): void public method (@org.jetbrains.annotations.NotNull p0: java.lang.Object): void - public final static @org.jetbrains.annotations.NotNull method getState$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater - public final @org.jetbrains.annotations.Nullable method getState(): java.lang.Object + public synthetic final static method access$getState$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final static method getState$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getState$volatile(): java.lang.Object + private synthetic final method setState$volatile(p0: java.lang.Object): void } @kotlin.Metadata diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/SimpleLockTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/SimpleLockTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/SimpleLockTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/SimpleLockTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/SimpleLockTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/SimpleLockTest.txt similarity index 66% rename from plugins/atomicfu/atomicfu-compiler/testData/box/SimpleLockTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/SimpleLockTest.txt index e99062d07a1..be529ab8f1f 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/SimpleLockTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/SimpleLockTest.txt @@ -1,11 +1,14 @@ @kotlin.Metadata public final class SimpleLock { // source: 'SimpleLockTest.kt' - private final static @org.jetbrains.annotations.NotNull field _locked$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _locked: int + private synthetic final static field _locked$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field _locked$volatile: int static method (): void public method (): void - private final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final static method get_locked$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method get_locked$volatile(): int + private synthetic final method loop$atomicfu(p0: java.util.concurrent.atomic.AtomicIntegerFieldUpdater, p1: kotlin.jvm.functions.Function1, p2: java.lang.Object): void + private synthetic final method set_locked$volatile(p0: int): void public final method withLock(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): java.lang.Object } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/UncheckedCastTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/UncheckedCastTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/UncheckedCastTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/UncheckedCastTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/UncheckedCastTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/UncheckedCastTest.txt new file mode 100644 index 00000000000..55d4b5499c6 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/atomics_basic/UncheckedCastTest.txt @@ -0,0 +1,65 @@ +@kotlin.Metadata +final class UncheckedCastTest$Box { + // source: 'UncheckedCastTest.kt' + private final field b: int + public method (p0: int): void + public final method component1(): int + public synthetic static method copy$default(p0: UncheckedCastTest$Box, p1: int, p2: int, p3: java.lang.Object): UncheckedCastTest$Box + public final @org.jetbrains.annotations.NotNull method copy(p0: int): UncheckedCastTest$Box + public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public final method getB(): int + public method hashCode(): int + public @org.jetbrains.annotations.NotNull method toString(): java.lang.String + private final inner class UncheckedCastTest$Box +} + +@kotlin.Metadata +synthetic final class UncheckedCastTest$VolatileWrapper$atomicfu$private { + // source: 'UncheckedCastTest.kt' + private synthetic final static field topLevelS$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field topLevelS$volatile: java.lang.Object + static method (): void + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$getTopLevelS$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final static method getTopLevelS$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getTopLevelS$volatile(): java.lang.Object + private synthetic final method setTopLevelS$volatile(p0: java.lang.Object): void +} + +@kotlin.Metadata +public final class UncheckedCastTest { + // source: 'UncheckedCastTest.kt' + private synthetic final field a: java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final static field bs$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field bs$volatile: java.lang.Object + private synthetic final static field s$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field s$volatile: java.lang.Object + static method (): void + public method (): void + private synthetic final method getA(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final static method getBs$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getBs$volatile(): java.lang.Object + private synthetic final static method getS$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getS$volatile(): java.lang.Object + private synthetic final method getString$atomicfu$array(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceArray, p2: int): java.lang.String + private synthetic final method getString$atomicfu(p0: java.lang.Object, p1: java.util.concurrent.atomic.AtomicReferenceFieldUpdater): java.lang.String + private synthetic final method setBs$volatile(p0: java.lang.Object): void + private synthetic final method setS$volatile(p0: java.lang.Object): void + public final method testArrayValueUncheckedCast(): void + public final method testArrayValueUncheckedCastInlineFunc(): void + public final method testAtomicValUncheckedCast(): void + public final method testInlineFunc(): void + public final method testTopLevelValUnchekedCast(): void + private final inner class UncheckedCastTest$Box +} + +@kotlin.Metadata +public final class UncheckedCastTestKt { + // source: 'UncheckedCastTest.kt' + private synthetic final static field uncheckedCastTest$VolatileWrapper$atomicfu$private: UncheckedCastTest$VolatileWrapper$atomicfu$private + static method (): void + public synthetic final static method access$getUncheckedCastTest$VolatileWrapper$atomicfu$private(): UncheckedCastTest$VolatileWrapper$atomicfu$private + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + private synthetic final static method getUncheckedCastTest$VolatileWrapper$atomicfu$private(): UncheckedCastTest$VolatileWrapper$atomicfu$private +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.kt similarity index 93% rename from plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.kt index 10d72ca08ee..f9ac0750af6 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.kt @@ -104,22 +104,12 @@ class DelegatedProperties { assertEquals(99, vRef.b.n) } - inner class D { - var c by atomic("aaa") - } - - fun testScopedVolatileProperties() { - val clazz = D() - assertEquals("aaa", clazz.c) - clazz.c = "bbb" - assertEquals("bbb", clazz.c) - } - fun testDelegatedVariablesFlow() { _a.lazySet(55) assertEquals(55, _a.value) assertEquals(55, a) var aValue = a + assertEquals(55, aValue) } fun test() { @@ -131,7 +121,6 @@ class DelegatedProperties { testVolatileBoolean() testVolatileLong() testVolatileRef() - testScopedVolatileProperties() testDelegatedVariablesFlow() } } diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.txt similarity index 53% rename from plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.txt index 5d68be41e56..c419a609e79 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/DelegatedPropertiesTest.txt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/delegated/DelegatedPropertiesTest.txt @@ -17,32 +17,21 @@ public final class DelegatedProperties$B { public final inner class DelegatedProperties$B } -@kotlin.Metadata -public final class DelegatedProperties$D { - // source: 'DelegatedPropertiesTest.kt' - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field c: java.lang.Object - synthetic final field this$0: DelegatedProperties - public method (p0: DelegatedProperties): void - public final @org.jetbrains.annotations.NotNull method getC(): java.lang.String - public final method setC(@org.jetbrains.annotations.NotNull p0: java.lang.String): void - public final inner class DelegatedProperties$D -} - @kotlin.Metadata public final class DelegatedProperties { // source: 'DelegatedPropertiesTest.kt' - private final static @org.jetbrains.annotations.NotNull field _a$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _a: int - private final static @org.jetbrains.annotations.NotNull field _b$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _b: int - private final static @org.jetbrains.annotations.NotNull field _l$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater - private volatile @kotlin.jvm.Volatile field _l: long - private final static @org.jetbrains.annotations.NotNull field _ref$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field _ref: java.lang.Object - private volatile @kotlin.jvm.Volatile field vBoolean: int - private volatile @kotlin.jvm.Volatile field vInt: int - private volatile @kotlin.jvm.Volatile field vLong: int - private volatile @kotlin.jvm.Volatile @org.jetbrains.annotations.Nullable field vRef: java.lang.Object + 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 (): void public method (): void public final method getA(): int @@ -54,6 +43,14 @@ public final class DelegatedProperties { 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 @@ -63,29 +60,48 @@ public final class DelegatedProperties { 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 testScopedVolatileProperties(): 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 - public final inner class DelegatedProperties$D +} + +@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 (): void + private method (): void + public synthetic method (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 final static @org.jetbrains.annotations.NotNull field _topLevelInt$DelegatedPropertiesTest$VolatileWrapper: _topLevelInt$DelegatedPropertiesTest$VolatileWrapper - private volatile static @kotlin.jvm.Volatile field topLevelVolatile: int + private synthetic final static field delegatedPropertiesTest$VolatileWrapper$atomicfu$private: DelegatedPropertiesTest$VolatileWrapper$atomicfu$private + private synthetic volatile static field topLevelVolatile$volatile: int static method (): 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 @@ -93,16 +109,3 @@ public final class DelegatedPropertiesTestKt { public final static method testTopLevelDelegatedProperties(): void public final static method testTopLevelVolatileProperties(): void } - -@kotlin.Metadata -final class _topLevelInt$DelegatedPropertiesTest$VolatileWrapper { - // source: 'DelegatedPropertiesTest.kt' - private final static @org.jetbrains.annotations.NotNull field _topLevelInt$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater - private volatile @kotlin.jvm.Volatile field _topLevelInt: int - static method (): void - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void - public synthetic final static method access$get_topLevelInt$FU$p(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater - public synthetic final static method access$get_topLevelInt$p(p0: _topLevelInt$DelegatedPropertiesTest$VolatileWrapper): int - public synthetic final static method access$set_topLevelInt$p(p0: _topLevelInt$DelegatedPropertiesTest$VolatileWrapper, p1: int): void -} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ReentrantLockTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/locks/ReentrantLockTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ReentrantLockTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/locks/ReentrantLockTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/ReentrantLockTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/locks/ReentrantLockTest.txt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/ReentrantLockTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/locks/ReentrantLockTest.txt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/SynchronizedObjectTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/locks/SynchronizedObjectTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/SynchronizedObjectTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/locks/SynchronizedObjectTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/SynchronizedObjectTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/locks/SynchronizedObjectTest.txt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/SynchronizedObjectTest.txt rename to plugins/atomicfu/atomicfu-compiler/testData/box/locks/SynchronizedObjectTest.txt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.kt similarity index 94% rename from plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.kt index 1a2bb017ef6..2d095869b57 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/FieldInObjectTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.kt @@ -2,7 +2,7 @@ import kotlinx.atomicfu.* import kotlin.test.* import kotlin.random.* -object Provider { +private object Provider { private val port = atomic(Random.nextInt(20, 90) * 100) fun next(): Int = port.incrementAndGet() @@ -18,8 +18,8 @@ object Provider { val refArr = atomicArrayOfNulls(5) } -object DelegatedProvider { - val _a = atomic(42) +private object DelegatedProvider { + internal val _a = atomic(42) var a: Int by _a var vInt by atomic(77) diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.txt new file mode 100644 index 00000000000..66597d36c62 --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/FieldInObjectTest.txt @@ -0,0 +1,97 @@ +@kotlin.Metadata +synthetic final class DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private { + // source: 'FieldInObjectTest.kt' + private synthetic final static field _a$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field _a$volatile: int + static method (): void + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$get_a$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + public synthetic final static method access$get_a$volatile$p(p0: DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private): int + public synthetic final static method access$set_a$volatile$p(p0: DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private, p1: int): void + 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 method set_a$volatile(p0: int): void + private synthetic inner class DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private +} + +@kotlin.Metadata +final class DelegatedProvider { + // source: 'FieldInObjectTest.kt' + public final static @org.jetbrains.annotations.NotNull field INSTANCE: DelegatedProvider + private synthetic final static field delegatedProvider$VolatileWrapper$atomicfu$private: DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private + private synthetic volatile field vInt$volatile: int + static method (): void + private method (): void + public synthetic final static method access$getDelegatedProvider$VolatileWrapper$atomicfu$private(): DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private + public final method getA(): int + private synthetic final static method getDelegatedProvider$VolatileWrapper$atomicfu$private(): DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private + public final method getVInt(): int + public final method setA(p0: int): void + public final method setVInt(p0: int): void + private synthetic inner class DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private +} + +@kotlin.Metadata +public final class FieldInObjectTestKt { + // source: 'FieldInObjectTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + private final static method testDelegatedPropertiesInObject(): void + private final static method testFieldInObject(): void + private synthetic inner class DelegatedProvider$DelegatedProvider$VolatileWrapper$atomicfu$private + private synthetic inner class Provider$Provider$VolatileWrapper$atomicfu$private +} + +@kotlin.Metadata +synthetic final class Provider$Provider$VolatileWrapper$atomicfu$private { + // source: 'FieldInObjectTest.kt' + 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 final static field _x$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field _x$volatile: int + private synthetic final static field port$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field port$volatile: int + static method (): void + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$getPort$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + public synthetic final static method access$get_l$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + public synthetic final static method access$get_ref$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + public synthetic final static method access$get_x$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final static method getPort$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getPort$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 + private synthetic final static method get_x$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method get_x$volatile(): int + private synthetic final method setPort$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 + private synthetic final method set_x$volatile(p0: int): void + private synthetic inner class Provider$Provider$VolatileWrapper$atomicfu$private + public final inner class kotlin/random/Random$Default +} + +@kotlin.Metadata +final class Provider { + // source: 'FieldInObjectTest.kt' + public final static @org.jetbrains.annotations.NotNull field INSTANCE: Provider + private synthetic final static field intArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static field longArr: java.util.concurrent.atomic.AtomicLongArray + private synthetic final static field provider$VolatileWrapper$atomicfu$private: Provider$Provider$VolatileWrapper$atomicfu$private + private synthetic final static field refArr: java.util.concurrent.atomic.AtomicReferenceArray + static method (): void + private method (): void + public synthetic final static method access$getProvider$VolatileWrapper$atomicfu$private(): Provider$Provider$VolatileWrapper$atomicfu$private + public synthetic final method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + public final method getL(): long + public synthetic final method getLongArr(): java.util.concurrent.atomic.AtomicLongArray + private synthetic final static method getProvider$VolatileWrapper$atomicfu$private(): Provider$Provider$VolatileWrapper$atomicfu$private + public synthetic final method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + public final method next(): int + private synthetic inner class Provider$Provider$VolatileWrapper$atomicfu$private +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/TopLevelTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.kt similarity index 96% rename from plugins/atomicfu/atomicfu-compiler/testData/box/TopLevelTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.kt index c1dfcb7777f..80663fda7b7 100644 --- a/plugins/atomicfu/atomicfu-compiler/testData/box/TopLevelTest.kt +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.kt @@ -7,6 +7,12 @@ private val c = atomic(true) private val abcNode = atomic(ANode(BNode(CNode(8)))) private val any = atomic(null) +internal val a_internal = atomic(0) +internal val b_internal = atomic(2424920024888888848) +internal val c_internal = atomic(true) +internal val abcNode_internal = atomic(ANode(BNode(CNode(8)))) +internal val any_internal = atomic(null) + private val intArr = AtomicIntArray(3) private val longArr = AtomicLongArray(5) private val booleanArr = AtomicBooleanArray(4) diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.txt new file mode 100644 index 00000000000..404779efe6c --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/top-level/TopLevelTest.txt @@ -0,0 +1,162 @@ +@kotlin.Metadata +public final class ANode { + // source: 'TopLevelTest.kt' + private final field b: java.lang.Object + public method (p0: java.lang.Object): void + public final method component1(): java.lang.Object + public synthetic static method copy$default(p0: ANode, p1: java.lang.Object, p2: int, p3: java.lang.Object): ANode + public final @org.jetbrains.annotations.NotNull method copy(p0: java.lang.Object): ANode + public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public final method getB(): java.lang.Object + public method hashCode(): int + public @org.jetbrains.annotations.NotNull method toString(): java.lang.String +} + +@kotlin.Metadata +public final class BNode { + // source: 'TopLevelTest.kt' + private final field c: java.lang.Object + public method (p0: java.lang.Object): void + public final method component1(): java.lang.Object + public synthetic static method copy$default(p0: BNode, p1: java.lang.Object, p2: int, p3: java.lang.Object): BNode + public final @org.jetbrains.annotations.NotNull method copy(p0: java.lang.Object): BNode + public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public final method getC(): java.lang.Object + public method hashCode(): int + public @org.jetbrains.annotations.NotNull method toString(): java.lang.String +} + +@kotlin.Metadata +public final class CNode { + // source: 'TopLevelTest.kt' + private final field d: int + public method (p0: int): void + public final method component1(): int + public synthetic static method copy$default(p0: CNode, p1: int, p2: int, p3: java.lang.Object): CNode + public final @org.jetbrains.annotations.NotNull method copy(p0: int): CNode + public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public final method getD(): int + public method hashCode(): int + public @org.jetbrains.annotations.NotNull method toString(): java.lang.String +} + +@kotlin.Metadata +public final class TopLevelArrayTest { + // source: 'TopLevelTest.kt' + public method (): void + public final method testBooleanArray(): void + public final method testIntArray(): void + public final method testLongArray(): void + public final method testRefArray(): void +} + +@kotlin.Metadata +public final class TopLevelPrimitiveTest { + // source: 'TopLevelTest.kt' + public method (): void + public final method testTopLevelArrayOfNulls(): void + public final method testTopLevelBoolean(): void + public final method testTopLevelInt(): void + public final method testTopLevelLong(): void + public final method testTopLevelRef(): void +} + +@kotlin.Metadata +public synthetic final class TopLevelTest$VolatileWrapper$atomicfu$internal { + // source: 'TopLevelTest.kt' + private synthetic final static field a_internal$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field a_internal$volatile: int + private synthetic final static field abcNode_internal$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field abcNode_internal$volatile: java.lang.Object + private synthetic final static field any_internal$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field any_internal$volatile: java.lang.Object + private synthetic final static field b_internal$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field b_internal$volatile: long + private synthetic final static field c_internal$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field c_internal$volatile: int + static method (): void + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method getA_internal$volatile$FU$main(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA_internal$volatile(): int + public synthetic final static method getAbcNode_internal$volatile$FU$main(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getAbcNode_internal$volatile(): java.lang.Object + public synthetic final static method getAny_internal$volatile$FU$main(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getAny_internal$volatile(): java.lang.Object + public synthetic final static method getB_internal$volatile$FU$main(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getB_internal$volatile(): long + public synthetic final static method getC_internal$volatile$FU$main(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getC_internal$volatile(): int + private synthetic final method setA_internal$volatile(p0: int): void + private synthetic final method setAbcNode_internal$volatile(p0: java.lang.Object): void + private synthetic final method setAny_internal$volatile(p0: java.lang.Object): void + private synthetic final method setB_internal$volatile(p0: long): void + private synthetic final method setC_internal$volatile(p0: int): void +} + +@kotlin.Metadata +synthetic final class TopLevelTest$VolatileWrapper$atomicfu$private { + // source: 'TopLevelTest.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 abcNode$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field abcNode$volatile: java.lang.Object + private synthetic final static field any$volatile$FU: java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic volatile field any$volatile: java.lang.Object + private synthetic final static field b$volatile$FU: java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic volatile field b$volatile: long + private synthetic final static field c$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field c$volatile: int + static method (): void + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + public synthetic final static method access$getAbcNode$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + public synthetic final static method access$getAny$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + public synthetic final static method access$getB$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + public synthetic final static method access$getC$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getAbcNode$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getAbcNode$volatile(): java.lang.Object + private synthetic final static method getAny$volatile$FU(): java.util.concurrent.atomic.AtomicReferenceFieldUpdater + private synthetic final method getAny$volatile(): java.lang.Object + private synthetic final static method getB$volatile$FU(): java.util.concurrent.atomic.AtomicLongFieldUpdater + private synthetic final method getB$volatile(): long + private synthetic final static method getC$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getC$volatile(): int + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setAbcNode$volatile(p0: java.lang.Object): void + private synthetic final method setAny$volatile(p0: java.lang.Object): void + private synthetic final method setB$volatile(p0: long): void + private synthetic final method setC$volatile(p0: int): void +} + +@kotlin.Metadata +public final class TopLevelTestKt { + // source: 'TopLevelTest.kt' + private synthetic final static field anyRefArr: java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final static field booleanArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static field intArr: java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static field longArr: java.util.concurrent.atomic.AtomicLongArray + private synthetic final static field refArr: java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final static field stringAtomicNullArr: java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final static field topLevelTest$VolatileWrapper$atomicfu$internal: TopLevelTest$VolatileWrapper$atomicfu$internal + private synthetic final static field topLevelTest$VolatileWrapper$atomicfu$private: TopLevelTest$VolatileWrapper$atomicfu$private + static method (): void + public synthetic final static method access$getBooleanArr(): java.util.concurrent.atomic.AtomicIntegerArray + public synthetic final static method access$getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + public synthetic final static method access$getLongArr(): java.util.concurrent.atomic.AtomicLongArray + public synthetic final static method access$getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + public synthetic final static method access$getStringAtomicNullArr(): java.util.concurrent.atomic.AtomicReferenceArray + public synthetic final static method access$getTopLevelTest$VolatileWrapper$atomicfu$private(): TopLevelTest$VolatileWrapper$atomicfu$private + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + private synthetic final static method getAnyRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final static method getBooleanArr(): java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static method getIntArr(): java.util.concurrent.atomic.AtomicIntegerArray + private synthetic final static method getLongArr(): java.util.concurrent.atomic.AtomicLongArray + private synthetic final static method getRefArr(): java.util.concurrent.atomic.AtomicReferenceArray + private synthetic final static method getStringAtomicNullArr(): java.util.concurrent.atomic.AtomicReferenceArray + public synthetic final static method getTopLevelTest$VolatileWrapper$atomicfu$internal(): TopLevelTest$VolatileWrapper$atomicfu$internal + private synthetic final static method getTopLevelTest$VolatileWrapper$atomicfu$private(): TopLevelTest$VolatileWrapper$atomicfu$private +} diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/TraceTest.kt b/plugins/atomicfu/atomicfu-compiler/testData/box/trace/TraceTest.kt similarity index 100% rename from plugins/atomicfu/atomicfu-compiler/testData/box/TraceTest.kt rename to plugins/atomicfu/atomicfu-compiler/testData/box/trace/TraceTest.kt diff --git a/plugins/atomicfu/atomicfu-compiler/testData/box/trace/TraceTest.txt b/plugins/atomicfu/atomicfu-compiler/testData/box/trace/TraceTest.txt new file mode 100644 index 00000000000..03522118d4a --- /dev/null +++ b/plugins/atomicfu/atomicfu-compiler/testData/box/trace/TraceTest.txt @@ -0,0 +1,61 @@ +@kotlin.Metadata +final enum class TraceTest$Status { + // source: 'TraceTest.kt' + private synthetic final static field $ENTRIES: kotlin.enums.EnumEntries + private synthetic final static field $VALUES: TraceTest$Status[] + public final enum static field END: TraceTest$Status + public final enum static field START: TraceTest$Status + private synthetic final static method $values(): TraceTest$Status[] + static method (): void + private method (p0: java.lang.String, p1: int): void + public static @org.jetbrains.annotations.NotNull method getEntries(): kotlin.enums.EnumEntries + public static method valueOf(p0: java.lang.String): TraceTest$Status + public static method values(): TraceTest$Status[] + private final inner class TraceTest$Status +} + +@kotlin.Metadata +public final class TraceTest { + // source: 'TraceTest.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 a1$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field a1$volatile: int + private synthetic final static field a2$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field a2$volatile: int + private synthetic final static field a3$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field a3$volatile: int + private synthetic final static field s$volatile$FU: java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic volatile field s$volatile: int + static method (): void + public method (): void + private synthetic final static method getA$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA$volatile(): int + private synthetic final static method getA1$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA1$volatile(): int + private synthetic final static method getA2$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA2$volatile(): int + private synthetic final static method getA3$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getA3$volatile(): int + private synthetic final static method getS$volatile$FU(): java.util.concurrent.atomic.AtomicIntegerFieldUpdater + private synthetic final method getS$volatile(): int + private synthetic final method setA$volatile(p0: int): void + private synthetic final method setA1$volatile(p0: int): void + private synthetic final method setA2$volatile(p0: int): void + private synthetic final method setA3$volatile(p0: int): void + private synthetic final method setS$volatile(p0: int): void + public final method test(): void + public final method testDefaultTrace(): void + public final method testMultipleAppend(): void + public final method testNamedTrace(): void + public final method testTraceInBlock(): void + public final method testTraceWithFormat(): void + public final method testTraceWithSize(): void + private final inner class TraceTest$Status +} + +@kotlin.Metadata +public final class TraceTestKt { + // source: 'TraceTest.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +}