[IR] Prepare MFVC-lowering for the new MFVC classes

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2022-07-07 03:14:44 +02:00
committed by teamcity
parent eb0aa55571
commit 8ba20bee5b
15 changed files with 844 additions and 115 deletions
@@ -50230,6 +50230,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
public void testThrowingMFVCReassignments() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("visibility.kt")
public void testVisibility() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/visibility.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
}
@Nested
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.MultiFieldValueClassMapping
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.RegularMapping
import org.jetbrains.kotlin.backend.jvm.SpecialBridge
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.codegen.AsmUtil
@@ -342,14 +344,12 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
for (override in irFunction.allOverridden()) {
if (override.isFakeOverride) continue
val target = override.mangleFunctionIfNeeded()
val signature = target.jvmMethod
val signature = override.jvmMethod
if (targetMethod != signature && signature !in blacklist) {
val bridge = generated.getOrPut(signature) {
Bridge(target, signature)
Bridge(override, signature)
}
bridge.overriddenSymbols += target.symbol
bridge.overriddenSymbols += override.symbol
}
}
@@ -361,18 +361,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
.forEach { irClass.addBridge(it, bridgeTarget) }
}
private fun IrSimpleFunction.mangleFunctionIfNeeded(): IrSimpleFunction {
if (!hasMangledReturnType && !hasMangledParameters()) return this
val replacement = context.multiFieldValueClassReplacements.getReplacementFunction(this)
?: context.inlineClassReplacements.getReplacementFunction(this)
?: return this
if (name.asString().substringAfterLast('-') == replacement.name.asString().substringAfterLast('-')) {
// function is already mangled
return this
}
return replacement
}
private fun IrSimpleFunction.isClashingWithPotentialBridge(name: Name, signature: Method): Boolean =
(!this.isFakeOverride || this.modality == Modality.FINAL) && this.name == name && this.jvmMethod == signature
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.backend.jvm.MultiFieldValueClassTree.InternalNode
import org.jetbrains.kotlin.backend.jvm.MultiFieldValueClassTree.Leaf
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.isMultiFieldValueClassType
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -151,7 +152,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
name = Name.guessByFirstCharacter("${oldField.name.asString()}$${sourceField.name.asString()}")
type = sourceField.type
origin = IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER
visibility = sourceField.visibility
visibility = DescriptorVisibilities.PRIVATE
}.apply {
parent = declaration
initializer = null
@@ -205,11 +206,12 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
accessor.body?.transform(object : IrElementTransformerVoid() {
override fun visitGetField(expression: IrGetField): IrExpression {
if (expression.symbol.owner == oldField) {
require(expression.receiver.let { it is IrGetValue && it.symbol.owner == accessor.dispatchReceiverParameter!! }) {
"Unexpected receiver for IrGetField: ${expression.receiver}"
}
require(expression.receiver.let {
it is IrGetValue && it.symbol.owner == accessor.dispatchReceiverParameter ||
it == null && oldField.origin == JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD
}) { "Unexpected receiver for IrGetField: ${expression.receiver}" }
val gettersAndSetters =
newFields.toGettersAndSetters(accessor.dispatchReceiverParameter!!, transformReceiver = true)
newFields.toGettersAndSetters(accessor.dispatchReceiverParameter, transformReceiver = true)
val representation = newFields.zip(gettersAndSetters) { newField, (getter, setter) ->
VirtualProperty(newField.type, getter, setter, null)
}
@@ -232,7 +234,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
parent = declaration
body = context.createIrBuilder(this.symbol).irBlockBody {
+irBlock {
flattenExpressionTo(initializer.expression, newFields.toGettersAndSetters(declaration.thisReceiver!!))
flattenExpressionTo(initializer.expression, newFields.toGettersAndSetters(declaration.thisReceiver))
}
}
oldFieldToInitializers[oldField] = this
@@ -785,10 +787,10 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD &&
parent is IrClass &&
parent.multiFieldValueClassRepresentation?.containsPropertyWithName(field.name) == true -> {
val receiver = expression.receiver!!.transform(this, null)
val receiver = expression.receiver?.transform(this, null)
with(valueDeclarationsRemapper) {
with(context.createIrBuilder(expression.symbol)) {
subfield(receiver, field.name) ?: run {
receiver?.let { subfield(it, field.name) } ?: run {
expression.receiver = receiver
expression
}
@@ -813,7 +815,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
val field = expression.symbol.owner
val replacementFields = regularClassMFVCPropertyFieldsMapping[field] ?: return super.visitSetField(expression)
return context.createIrBuilder(expression.symbol).irBlock {
val thisVar = irTemporary(expression.receiver!!.transform(this@JvmMultiFieldValueClassLowering, null))
val thisVar = expression.receiver?.let { irTemporary(it.transform(this@JvmMultiFieldValueClassLowering, null)) }
// We flatten to temp variables because code can throw an exception otherwise and partially update variables
val subValues = flattenExpressionToGetters(
expression = expression.value, // not modified
@@ -821,7 +823,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
additionalConditionForValue = { (_, value) -> value is IrGetValue }
)
for ((replacementField, subValue) in replacementFields zip subValues) {
+irSetField(irGet(thisVar), replacementField, subValue)
+irSetField(thisVar?.let { irGet(it) }, replacementField, subValue)
}
}
}
@@ -882,19 +884,19 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
)
}
private fun List<IrField>.toGettersAndSetters(receiver: IrValueParameter, transformReceiver: Boolean = false) = map { field ->
private fun List<IrField>.toGettersAndSetters(receiver: IrValueParameter?, transformReceiver: Boolean = false) = map { field ->
Pair<ExpressionGenerator, ExpressionSupplier>(
{
val initialGetReceiver = irGet(receiver)
val initialGetReceiver = receiver?.let { irGet(it) }
val resultReceiver =
if (transformReceiver) initialGetReceiver.transform(this@JvmMultiFieldValueClassLowering, null)
if (transformReceiver) initialGetReceiver?.transform(this@JvmMultiFieldValueClassLowering, null)
else initialGetReceiver
irGetField(resultReceiver, field)
},
{ value: IrExpression ->
val initialGetReceiver = irGet(receiver)
val initialGetReceiver = receiver?.let { irGet(it) }
val resultReceiver =
if (transformReceiver) initialGetReceiver.transform(this@JvmMultiFieldValueClassLowering, null)
if (transformReceiver) initialGetReceiver?.transform(this@JvmMultiFieldValueClassLowering, null)
else initialGetReceiver
irSetField(resultReceiver, field, value)
},
@@ -0,0 +1,202 @@
/*
* 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.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.jvm.MultiFieldValueClassSpecificDeclarations
import org.jetbrains.kotlin.backend.jvm.MultiFieldValueClassTree
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.typeOrNull
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.util.substitute
import org.jetbrains.kotlin.name.Name
typealias TypeArguments = Map<IrTypeParameterSymbol, IrType>
sealed interface MFVCRepresentation<Leaf : MFVCLeafRepresentation> {
operator fun get(name: Name): MFVCRepresentation<Leaf>?
fun IrBuilderWithScope.makeGetter(): IrExpression
val type: IrSimpleType
val children: List<Pair<Name, MFVCRepresentation<Leaf>>>
val leaves: List<Leaf>
}
sealed interface MutableMFVCRepresentation<Leaf : MFVCLeafRepresentation> : MFVCRepresentation<Leaf>
sealed interface RecursivelyMutableMFVCRepresentation<Leaf : MFVCLeafRepresentation> : MutableMFVCRepresentation<Leaf>
interface MFVCLeafRepresentation : MFVCRepresentation<Nothing> {
override fun get(name: Name): Nothing? = null
override val children: List<Pair<Name, MFVCRepresentation<Nothing>>>
get() = emptyList()
override val leaves: List<Nothing>
get() = emptyList()
}
interface MutableMFVCLeafRepresentation : MFVCLeafRepresentation, RecursivelyMutableMFVCRepresentation<Nothing> {
fun IrBuilderWithScope.makeSetter(value: IrExpression): IrExpression
}
sealed class ValueDeclarationLeafRepresentation(open val valueDeclaration: IrValueDeclaration) : MFVCLeafRepresentation {
override fun IrBuilderWithScope.makeGetter(): IrExpression = irGet(valueDeclaration)
override val type: IrSimpleType
get() = valueDeclaration.type as IrSimpleType
}
data class VariableLeafRepresentation(override val valueDeclaration: IrVariable) : ValueDeclarationLeafRepresentation(valueDeclaration),
MutableMFVCLeafRepresentation {
override fun IrBuilderWithScope.makeSetter(value: IrExpression): IrExpression = irSet(valueDeclaration, value)
}
data class ValueParameterLeafRepresentation(override val valueDeclaration: IrValueParameter) :
ValueDeclarationLeafRepresentation(valueDeclaration)
sealed class ReceiverBasedLeafRepresentation(open val receiver: IrValueDeclaration) : MFVCLeafRepresentation {
protected fun makeTypeParametersMapping(): Map<IrTypeParameterSymbol, IrType> {
val type = receiver.type as IrSimpleType
return (type.erasedUpperBound.typeParameters zip type.arguments)
.mapNotNull { (parameter, argument) -> argument.typeOrNull?.let { parameter.symbol to it } }.toMap()
}
}
data class FieldAccessLeafRepresentation(override val receiver: IrValueDeclaration, val field: IrField) :
ReceiverBasedLeafRepresentation(receiver), MutableMFVCLeafRepresentation {
override fun IrBuilderWithScope.makeGetter(): IrExpression = irGetField(irGet(receiver), field)
override fun IrBuilderWithScope.makeSetter(value: IrExpression): IrExpression = irSetField(irGet(receiver), field, value)
override val type: IrSimpleType = field.type.substitute(makeTypeParametersMapping()) as IrSimpleType
}
data class GetterLeafRepresentation(override val receiver: IrValueDeclaration, val getter: IrFunction) :
ReceiverBasedLeafRepresentation(receiver) {
init {
require(getter.typeParameters.isEmpty()) { "Getter ${getter.render()} must have no type parameters" }
}
override fun IrBuilderWithScope.makeGetter(): IrExpression = irCall(getter).apply {
dispatchReceiver = irGet(receiver)
}
override val type: IrSimpleType = getter.returnType.substitute(makeTypeParametersMapping()) as IrSimpleType
}
private fun getChildType(
declarations: MultiFieldValueClassSpecificDeclarations,
typeMapping: Map<IrTypeParameterSymbol, IrSimpleType>,
name: Name,
): IrSimpleType? = declarations.loweringRepresentation[name]?.type?.substitute(typeMapping) as IrSimpleType?
private fun <T : MFVCRepresentation<Leaf>, Leaf : T, InternalNode : T> makeTree(
node: MultiFieldValueClassTree,
typeArguments: TypeArguments,
createInternalNode: (type: IrSimpleType, typeArguments: TypeArguments, node: MultiFieldValueClassTree, children: List<Pair<Name, T>>) -> InternalNode,
createLeaf: (type: IrType, node: MultiFieldValueClassTree) -> Leaf,
): T = when (node) {
is MultiFieldValueClassTree.InternalNode -> {
val type = node.type.substitute(typeArguments) as IrSimpleType
val children = node.fields.map { it.name to makeTree(it.node, typeArguments, createInternalNode, createLeaf) }
createInternalNode(type, typeArguments, node, children)
}
is MultiFieldValueClassTree.Leaf -> createLeaf(node.type.substitute(typeArguments), node)
}
sealed interface InternalNodeRepresentation<Leaf : MFVCLeafRepresentation> : MFVCRepresentation<Leaf>
abstract class InternalNodeRepresentationImpl<Leaf : MFVCLeafRepresentation>(
val declarations: MultiFieldValueClassSpecificDeclarations,
val typeArguments: TypeArguments,
final override val children: List<Pair<Name, MFVCRepresentation<Leaf>>>,
) : InternalNodeRepresentation<Leaf> {
final override val type: IrSimpleType = declarations.valueClass.defaultType.substitute(typeArguments) as IrSimpleType
final override val leaves: List<Leaf> = children.flatMap { (_, node) -> node.leaves }
private val childrenMap = children.toMap()
final override fun get(name: Name): MFVCRepresentation<Leaf>? = childrenMap[name]
final override fun IrBuilderWithScope.makeGetter(): IrExpression = irCall(declarations.boxMethod).apply {
declarations.valueClass.typeParameters.forEachIndexed { index, typeParameter ->
typeArguments[typeParameter.symbol]?.let { putTypeArgument(index, it) }
}
leaves.forEachIndexed { index, leaf -> putValueArgument(index, leaf.run { makeGetter() }) }
}
}
abstract class MutableInternalNodeRepresentation<Leaf : MFVCLeafRepresentation>(
declarations: MultiFieldValueClassSpecificDeclarations,
typeArguments: TypeArguments,
children: List<Pair<Name, MFVCRepresentation<Leaf>>>
) : InternalNodeRepresentationImpl<Leaf>(declarations, typeArguments, children), MutableMFVCRepresentation<Leaf> {
abstract fun IrBuilderWithScope.makeSetter(values: List<IrExpression>): IrExpression
}
abstract class RecursivelyMutableInternalNodeRepresentation<Leaf : MutableMFVCLeafRepresentation>(
declarations: MultiFieldValueClassSpecificDeclarations,
typeArguments: TypeArguments,
children: List<Pair<Name, MFVCRepresentation<Leaf>>>,
) : MutableInternalNodeRepresentation<Leaf>(declarations, typeArguments, children), RecursivelyMutableMFVCRepresentation<Leaf> {
final override fun IrBuilderWithScope.makeSetter(values: List<IrExpression>): IrExpression {
require(values.size == leaves.size) { "Expected ${leaves.size} expressions but found ${values.size} of them" }
return irComposite {
for ((leaf, value) in leaves zip values) {
+leaf.run { makeSetter(value) }
}
}
}
}
sealed interface ValueDeclarationInternalNodeRepresentation<Leaf : ValueDeclarationLeafRepresentation> : InternalNodeRepresentation<Leaf>
class MutableValueDeclarationInternalNodeRepresentation(
declarations: MultiFieldValueClassSpecificDeclarations,
typeArguments: TypeArguments,
children: List<Pair<Name, RecursivelyMutableMFVCRepresentation<VariableLeafRepresentation>>>,
) : ValueDeclarationInternalNodeRepresentation<VariableLeafRepresentation>,
RecursivelyMutableInternalNodeRepresentation<VariableLeafRepresentation>(declarations, typeArguments, children)
class FieldAccessInternalNodeRepresentation(
declarations: MultiFieldValueClassSpecificDeclarations,
typeArguments: TypeArguments,
children: List<Pair<Name, RecursivelyMutableMFVCRepresentation<FieldAccessLeafRepresentation>>>,
) : RecursivelyMutableInternalNodeRepresentation<FieldAccessLeafRepresentation>(declarations, typeArguments, children)
class RegularClassMFVCInternalNodeRepresentation(
declarations: MultiFieldValueClassSpecificDeclarations,
typeArguments: TypeArguments,
children: List<Pair<Name, MFVCRepresentation<ReceiverBasedLeafRepresentation>>>,
) : InternalNodeRepresentationImpl<ReceiverBasedLeafRepresentation>(declarations, typeArguments, children) {
init {
leaves.verifyEqualReceivers()
}
}
private fun List<ReceiverBasedLeafRepresentation>.verifyEqualReceivers() {
val receiver = this[0].receiver
require(all { it.receiver == receiver }) { "Different receivers found in leaves" }
}
class MutableRegularClassMFVCInternalNodeRepresentation(
declarations: MultiFieldValueClassSpecificDeclarations,
val setter: IrFunction,
typeArguments: TypeArguments,
children: List<Pair<Name, MFVCRepresentation<ReceiverBasedLeafRepresentation>>>,
) : MutableInternalNodeRepresentation<ReceiverBasedLeafRepresentation>(declarations, typeArguments, children) {
init {
leaves.verifyEqualReceivers()
require(setter.typeParameters.isEmpty()) { "No type parameters are expected for ${setter.render()}" }
}
override fun IrBuilderWithScope.makeSetter(values: List<IrExpression>): IrExpression = irCall(setter).apply {
dispatchReceiver = irGet(leaves[0].receiver)
values.forEachIndexed { index, value -> putValueArgument(index, value) }
}
}
@@ -5,11 +5,10 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyTypeParameters
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.ir.classFileContainsMethod
import org.jetbrains.kotlin.backend.jvm.ir.extensionReceiverName
import org.jetbrains.kotlin.backend.jvm.ir.isStaticValueClassReplacement
import org.jetbrains.kotlin.backend.jvm.ir.parentClassId
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
@@ -17,7 +16,6 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
@@ -52,6 +50,7 @@ class MemoizedInlineClassReplacements(
(it.isLocal && it is IrSimpleFunction && it.overriddenSymbols.isEmpty()) ||
(it.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR && it.visibility == DescriptorVisibilities.LOCAL) ||
it.isStaticValueClassReplacement ||
it in context.multiFieldValueClassReplacements.bindingNewFunctionToParameterTemplateStructure ||
it.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD ||
it.origin.isSynthetic && it.origin != IrDeclarationOrigin.SYNTHETIC_GENERATED_SAM_IMPLEMENTATION ->
null
@@ -261,9 +260,4 @@ class MemoizedInlineClassReplacements(
computeOverrideReplacement(it.owner).symbol
}
}
private fun computeOverrideReplacement(function: IrSimpleFunction): IrSimpleFunction =
getReplacementFunction(function) ?: function.also {
function.overriddenSymbols = replaceOverriddenSymbols(function)
}
}
@@ -5,16 +5,14 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.MultiFieldValueClassMapping
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
@@ -295,8 +293,12 @@ class MemoizedMultiFieldValueClassReplacements(
}
}
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> = storageManager.createMemoizedFunction {
TODO()
}
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> =
storageManager.createMemoizedFunction { irSimpleFunction ->
irSimpleFunction.overriddenSymbols.map {
computeOverrideReplacement(it.owner).symbol
}
}
}
@@ -5,9 +5,6 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.backend.common.ir.copyTypeParameters
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.descriptors.Modality
@@ -16,13 +13,14 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.isInt
import org.jetbrains.kotlin.ir.util.*
import java.util.concurrent.ConcurrentHashMap
abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: IrFactory, protected val context: JvmBackendContext) {
protected val propertyMap = ConcurrentHashMap<IrPropertySymbol, IrProperty>()
private val propertyMap = ConcurrentHashMap<IrPropertySymbol, IrProperty>()
/**
* Get a replacement for a function or a constructor.
*/
@@ -102,9 +100,7 @@ abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: I
}
}
overriddenSymbols = function.overriddenSymbols.map {
getReplacementFunction(it.owner)?.symbol ?: it
}
overriddenSymbols = replaceOverriddenSymbols(function)
}
body()
@@ -113,4 +109,9 @@ abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: I
abstract val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol>
abstract val getReplacementRegularClassConstructor: (IrConstructor) -> IrConstructor?
protected fun computeOverrideReplacement(function: IrSimpleFunction): IrSimpleFunction =
getReplacementFunction(function) ?: function.also {
function.overriddenSymbols = replaceOverriddenSymbols(function)
}
}
@@ -5,8 +5,6 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.common.pop
@@ -43,8 +41,8 @@ sealed class MultiFieldValueClassTree {
companion object {
@JvmStatic
fun create(type: IrSimpleType, replacements: MemoizedMultiFieldValueClassReplacements) =
if (!type.isNullable() && type.isMultiFieldValueClassType()) InternalNode(type, DescriptorVisibilities.PUBLIC, replacements)
fun create(type: IrSimpleType, replacements: MemoizedMultiFieldValueClassReplacements, descriptorVisibility: DescriptorVisibility) =
if (!type.isNullable() && type.isMultiFieldValueClassType()) InternalNode(type, descriptorVisibility, replacements)
else Leaf(type)
}
@@ -71,9 +69,7 @@ sealed class MultiFieldValueClassTree {
valueClassRepresentation.underlyingPropertyNamesToTypes.map { (name, representationType) ->
val property = propertiesByName[name]!!
val innerVisibility = property.visibility
val comparison = visibility.compareTo(innerVisibility)
?: error("Expected comparable visibilities but got $visibility and $innerVisibility")
val newVisibility = if (comparison < 0) visibility else innerVisibility
val newVisibility = minVisibility(visibility, innerVisibility)
TreeField(
name,
representationType.substitute(substitutionMap) as IrSimpleType,
@@ -94,12 +90,9 @@ sealed class MultiFieldValueClassTree {
visibility: DescriptorVisibility,
annotations: List<IrConstructorCall>,
replacements: MemoizedMultiFieldValueClassReplacements
) : this(name, type, visibility, annotations, create(type, replacements))
) : this(name, type, visibility, annotations, create(type, replacements, visibility))
}
// todo store real fields, cannot restore them
// todo or store fields not pairs
init {
require(!type.isNullable() && type.isMultiFieldValueClassType())
}
@@ -110,6 +103,15 @@ sealed class MultiFieldValueClassTree {
}
}
fun minVisibility(
visibility1: DescriptorVisibility,
visibility2: DescriptorVisibility
): DescriptorVisibility {
val comparison = visibility1.compareTo(visibility2)
?: error("Expected comparable visibilities but got $visibility1 and $visibility2")
return if (comparison < 0) visibility1 else visibility2
}
fun MultiFieldValueClassTree.render(): String = type.render() + when (this) {
is InternalNode -> "\n" + fields.joinToString("\n") { "${it.name.render()}: ${it.node.render().prependIndent(" ")}" }
is Leaf -> ""
@@ -126,7 +128,8 @@ class MultiFieldValueClassSpecificDeclarations(
require(valueClass.isMultiFieldValueClass) { "Cannot build ${this::class.simpleName} for not multi-field value class: $valueClass" }
}
val loweringRepresentation = MultiFieldValueClassTree.create(valueClass.defaultType, replacements) as InternalNode
val loweringRepresentation =
MultiFieldValueClassTree.create(valueClass.defaultType, replacements, DescriptorVisibilities.PUBLIC) as InternalNode
val leaves: List<Leaf> = ArrayList<Leaf>().apply {
fun proceed(node: MultiFieldValueClassTree) {
@@ -167,8 +170,8 @@ class MultiFieldValueClassSpecificDeclarations(
require(nodeFullNames.size == nodeFullNames.values.distinct().size) { "Ambiguous names found: ${nodeFullNames.values}" }
}
private val indexByLeaf = leaves.withIndex().associate { it.value to it.index }
private val indexesByInternalNode = mutableMapOf<InternalNode, IntRange>().apply {
val indexByLeaf = leaves.withIndex().associate { it.value to it.index }
val indexesByInternalNode = mutableMapOf<InternalNode, IntRange>().apply {
var index = 0
fun proceed(node: MultiFieldValueClassTree) {
when (node) {
@@ -202,7 +205,7 @@ class MultiFieldValueClassSpecificDeclarations(
}
}
private val gettersVisibilities = mutableMapOf<MultiFieldValueClassTree, DescriptorVisibility>().apply {
val gettersVisibilities = mutableMapOf<MultiFieldValueClassTree, DescriptorVisibility>().apply {
val stack = mutableListOf<DescriptorVisibility>()
fun proceed(node: MultiFieldValueClassTree) {
when (node) {
@@ -368,10 +371,11 @@ class MultiFieldValueClassSpecificDeclarations(
makeNodes2FieldExpressions(fields)
nodeFullNames.mapValues { (node, propertyName) ->
val overrideable = oldProperties[propertyName]
val descriptorVisibility = gettersVisibilities[node]!!
irFactory.buildProperty {
name = propertyName
origin = IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER
visibility = gettersVisibilities[node]!!
visibility = descriptorVisibility
}.apply {
annotations = gettersAnnotations[node]!!
overrideable?.overriddenSymbols?.let { overriddenSymbols = it }
@@ -379,6 +383,7 @@ class MultiFieldValueClassSpecificDeclarations(
addGetter {
returnType = node.type
origin = IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER
visibility = descriptorVisibility
}.apply {
val function = this
overrideable?.getter?.overriddenSymbols?.let { overriddenSymbols = it }
@@ -513,6 +518,8 @@ class MultiFieldValueClassSpecificDeclarations(
// todo default parameters
// todo annotations etc.
// todo visibilities etc.
// todo regenerate tests for not only jvm
}
}
+2
View File
@@ -155,6 +155,8 @@ fun reuseBoxed(list: MutableList<R<List<Int>>>) {
}
fun supply(x: Boolean) {}
fun equalsChecks1(x: A<List<Int>>) {}
fun equalsChecks(left: R<List<Int>>, right: R<List<Int>>) {
supply(left == right)
supply(left as Any == right)
+9 -8
View File
@@ -56,7 +56,7 @@ public interface Base1 {
public interface Base2 {
// source: 'complex.kt'
public abstract @org.jetbrains.annotations.NotNull method getL(): R
public abstract method setL-Y_3tvh0(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public abstract method setL-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
}
@kotlin.Metadata
@@ -101,10 +101,11 @@ public final class C {
public final class ComplexKt {
// source: 'complex.kt'
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method equalsChecks-GPBa7dw-yJnZWq8(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List, p6: int, p7: int, p8: int, p9: int, @org.jetbrains.annotations.NotNull p10: java.lang.String, @org.jetbrains.annotations.NotNull p11: java.util.List): void
public final static method f-sUp7gFk-Y_3tvh0(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final static method g-sUp7gFk-ZTiL54U(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): void
public final static method h-sUp7gFk-Y_3tvh0(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final static method equalsChecks-GPBa7dw(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List, p6: int, p7: int, p8: int, p9: int, @org.jetbrains.annotations.NotNull p10: java.lang.String, @org.jetbrains.annotations.NotNull p11: java.util.List): void
public final static method equalsChecks1-iUtXLc0(@org.jetbrains.annotations.NotNull p0: java.util.List): void
public final static method f-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final static method g-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): void
public final static method h-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final static method h1(): void
public final static @org.jetbrains.annotations.NotNull method inlined-OsBMiQA(p0: int, p1: int, p2: int): D
public final static @org.jetbrains.annotations.NotNull method notInlined-OsBMiQA(p0: int, p1: int, p2: int): D
@@ -211,9 +212,9 @@ public final class NotInlined {
public final @org.jetbrains.annotations.NotNull method getWithNonTrivialSettersWithBF(): R
public final method getY(): int
public synthetic bridge method setL(p0: java.lang.Object): void
public method setL-Y_3tvh0(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final method setWithNonTrivialSetters-Y_3tvh0(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final method setWithNonTrivialSettersWithBF-Y_3tvh0(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public method setL-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final method setWithNonTrivialSetters-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final method setWithNonTrivialSettersWithBF-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
public final method setY(p0: int): void
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public final method trySetter(): void
@@ -60,12 +60,10 @@ public final class DPointWithInterface {
public method hashCode(): int
public static method hashCode-impl(p0: double, p1: double): int
public synthetic bridge method setSomethingGeneric(p0: java.lang.Object): void
public synthetic bridge method setSomethingGeneric-f_6zJnY(p0: double, p1: double): void
public method setSomethingGeneric-sUp7gFk(p0: double, p1: double): void
public static method setSomethingGeneric-sUp7gFk(p0: double, p1: double, p2: double, p3: double): void
public method setSomethingGeneric-sUp7gFk-f_6zJnY(p0: double, p1: double): void
public synthetic bridge method setSomethingMFVC-f_6zJnY(p0: double, p1: double): void
public method setSomethingMFVC-sUp7gFk(p0: double, p1: double): void
public static method setSomethingMFVC-sUp7gFk(p0: double, p1: double, p2: double, p3: double): void
public method setSomethingMFVC-sUp7gFk-f_6zJnY(p0: double, p1: double): void
public method setSomethingRegular(p0: int): void
public static method setSomethingRegular-impl(p0: double, p1: double, p2: int): void
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
@@ -188,12 +186,10 @@ public final class GenericFakeOverrideMFVCWithMFVCUpperBound {
public static @org.jetbrains.annotations.NotNull method getP1-impl(p0: double, p1: double): DPoint
public method hashCode(): int
public static method hashCode-impl(p0: double, p1: double): int
public synthetic bridge method setP-f_6zJnY(p0: double, p1: double): void
public method setP-sUp7gFk(p0: double, p1: double): void
public static method setP-sUp7gFk(p0: double, p1: double, p2: double, p3: double): void
public method setP-sUp7gFk-f_6zJnY(p0: double, p1: double): void
public synthetic bridge method setP1-f_6zJnY(p0: double, p1: double): void
public method setP1-sUp7gFk(p0: double, p1: double): void
public static method setP1-sUp7gFk(p0: double, p1: double, p2: double, p3: double): void
public method setP1-sUp7gFk-f_6zJnY(p0: double, p1: double): void
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: double, p1: double): java.lang.String
public synthetic final method unbox-impl0(): double
@@ -206,8 +202,8 @@ public final class GenericFakeOverrideWithMFVCUpperBound {
public method <init>(): void
public @org.jetbrains.annotations.NotNull method getP(): DPoint
public @org.jetbrains.annotations.NotNull method getP1(): DPoint
public method setP-f_6zJnY(p0: double, p1: double): void
public method setP1-f_6zJnY(p0: double, p1: double): void
public method setP-sUp7gFk(p0: double, p1: double): void
public method setP1-sUp7gFk(p0: double, p1: double): void
}
@kotlin.Metadata
@@ -244,8 +240,8 @@ public interface GenericMFVCHolderWithMFVCUpperBound {
// source: 'overrides_inlineClass.kt'
public abstract @org.jetbrains.annotations.NotNull method getP(): DPoint
public abstract @org.jetbrains.annotations.NotNull method getP1(): DPoint
public abstract method setP-f_6zJnY(p0: double, p1: double): void
public abstract method setP1-f_6zJnY(p0: double, p1: double): void
public abstract method setP-sUp7gFk(p0: double, p1: double): void
public abstract method setP1-sUp7gFk(p0: double, p1: double): void
}
@kotlin.Metadata
@@ -253,8 +249,8 @@ public final class GenericMFVCHolderWithMFVCUpperBoundWithImpls$DefaultImpls {
// source: 'overrides_inlineClass.kt'
public static @org.jetbrains.annotations.NotNull method getP(@org.jetbrains.annotations.NotNull p0: GenericMFVCHolderWithMFVCUpperBoundWithImpls): DPoint
public static @org.jetbrains.annotations.NotNull method getP1(@org.jetbrains.annotations.NotNull p0: GenericMFVCHolderWithMFVCUpperBoundWithImpls): DPoint
public static method setP-f_6zJnY(@org.jetbrains.annotations.NotNull p0: GenericMFVCHolderWithMFVCUpperBoundWithImpls, p1: double, p2: double): void
public static method setP1-f_6zJnY(@org.jetbrains.annotations.NotNull p0: GenericMFVCHolderWithMFVCUpperBoundWithImpls, p1: double, p2: double): void
public static method setP-sUp7gFk(@org.jetbrains.annotations.NotNull p0: GenericMFVCHolderWithMFVCUpperBoundWithImpls, p1: double, p2: double): void
public static method setP1-sUp7gFk(@org.jetbrains.annotations.NotNull p0: GenericMFVCHolderWithMFVCUpperBoundWithImpls, p1: double, p2: double): void
public final inner class GenericMFVCHolderWithMFVCUpperBoundWithImpls$DefaultImpls
}
@@ -263,8 +259,8 @@ public interface GenericMFVCHolderWithMFVCUpperBoundWithImpls {
// source: 'overrides_inlineClass.kt'
public abstract @org.jetbrains.annotations.NotNull method getP(): DPoint
public abstract @org.jetbrains.annotations.NotNull method getP1(): DPoint
public abstract method setP-f_6zJnY(p0: double, p1: double): void
public abstract method setP1-f_6zJnY(p0: double, p1: double): void
public abstract method setP-sUp7gFk(p0: double, p1: double): void
public abstract method setP1-sUp7gFk(p0: double, p1: double): void
public final inner class GenericMFVCHolderWithMFVCUpperBoundWithImpls$DefaultImpls
}
@@ -2482,9 +2478,9 @@ public final class RealOverride {
public @org.jetbrains.annotations.NotNull method getP1(): DPoint
public synthetic bridge method getP1(): java.lang.Object
public synthetic bridge method setP(p0: java.lang.Object): void
public method setP-f_6zJnY(p0: double, p1: double): void
public method setP-sUp7gFk(p0: double, p1: double): void
public synthetic bridge method setP1(p0: java.lang.Object): void
public method setP1-f_6zJnY(p0: double, p1: double): void
public method setP1-sUp7gFk(p0: double, p1: double): void
}
@kotlin.Metadata
@@ -2493,8 +2489,8 @@ public final class ReifiedFakeOverride {
public method <init>(): void
public @org.jetbrains.annotations.NotNull method getP(): DPoint
public @org.jetbrains.annotations.NotNull method getP1(): DPoint
public method setP-f_6zJnY(p0: double, p1: double): void
public method setP1-f_6zJnY(p0: double, p1: double): void
public method setP-sUp7gFk(p0: double, p1: double): void
public method setP1-sUp7gFk(p0: double, p1: double): void
}
@kotlin.jvm.JvmInline
@@ -2517,12 +2513,10 @@ public final class ReifiedFakeOverrideMFVC {
public static @org.jetbrains.annotations.NotNull method getP1-impl(p0: double, p1: double): DPoint
public method hashCode(): int
public static method hashCode-impl(p0: double, p1: double): int
public synthetic bridge method setP-f_6zJnY(p0: double, p1: double): void
public method setP-sUp7gFk(p0: double, p1: double): void
public static method setP-sUp7gFk(p0: double, p1: double, p2: double, p3: double): void
public method setP-sUp7gFk-f_6zJnY(p0: double, p1: double): void
public synthetic bridge method setP1-f_6zJnY(p0: double, p1: double): void
public method setP1-sUp7gFk(p0: double, p1: double): void
public static method setP1-sUp7gFk(p0: double, p1: double, p2: double, p3: double): void
public method setP1-sUp7gFk-f_6zJnY(p0: double, p1: double): void
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: double, p1: double): java.lang.String
public synthetic final method unbox-impl0(): double
@@ -2534,8 +2528,8 @@ public interface ReifiedMFVCHolder {
// source: 'overrides_inlineClass.kt'
public abstract @org.jetbrains.annotations.NotNull method getP(): DPoint
public abstract @org.jetbrains.annotations.NotNull method getP1(): DPoint
public abstract method setP-f_6zJnY(p0: double, p1: double): void
public abstract method setP1-f_6zJnY(p0: double, p1: double): void
public abstract method setP-sUp7gFk(p0: double, p1: double): void
public abstract method setP1-sUp7gFk(p0: double, p1: double): void
}
@kotlin.Metadata
@@ -2543,8 +2537,8 @@ public final class ReifiedMFVCHolderWithImpls$DefaultImpls {
// source: 'overrides_inlineClass.kt'
public static @org.jetbrains.annotations.NotNull method getP(@org.jetbrains.annotations.NotNull p0: ReifiedMFVCHolderWithImpls): DPoint
public static @org.jetbrains.annotations.NotNull method getP1(@org.jetbrains.annotations.NotNull p0: ReifiedMFVCHolderWithImpls): DPoint
public static method setP-f_6zJnY(@org.jetbrains.annotations.NotNull p0: ReifiedMFVCHolderWithImpls, p1: double, p2: double): void
public static method setP1-f_6zJnY(@org.jetbrains.annotations.NotNull p0: ReifiedMFVCHolderWithImpls, p1: double, p2: double): void
public static method setP-sUp7gFk(@org.jetbrains.annotations.NotNull p0: ReifiedMFVCHolderWithImpls, p1: double, p2: double): void
public static method setP1-sUp7gFk(@org.jetbrains.annotations.NotNull p0: ReifiedMFVCHolderWithImpls, p1: double, p2: double): void
public final inner class ReifiedMFVCHolderWithImpls$DefaultImpls
}
@@ -2553,8 +2547,8 @@ public interface ReifiedMFVCHolderWithImpls {
// source: 'overrides_inlineClass.kt'
public abstract @org.jetbrains.annotations.NotNull method getP(): DPoint
public abstract @org.jetbrains.annotations.NotNull method getP1(): DPoint
public abstract method setP-f_6zJnY(p0: double, p1: double): void
public abstract method setP1-f_6zJnY(p0: double, p1: double): void
public abstract method setP-sUp7gFk(p0: double, p1: double): void
public abstract method setP1-sUp7gFk(p0: double, p1: double): void
public final inner class ReifiedMFVCHolderWithImpls$DefaultImpls
}
@@ -2565,7 +2559,7 @@ public interface SomePointInterface {
public abstract @org.jetbrains.annotations.NotNull method getSomethingMFVC(): DPoint
public abstract method getSomethingRegular(): int
public abstract method setSomethingGeneric(p0: java.lang.Object): void
public abstract method setSomethingMFVC-f_6zJnY(p0: double, p1: double): void
public abstract method setSomethingMFVC-sUp7gFk(p0: double, p1: double): void
public abstract method setSomethingRegular(p0: int): void
}
@@ -2575,7 +2569,7 @@ public interface SomePointInterfaceWithMFVCBound {
public abstract @org.jetbrains.annotations.NotNull method getSomethingGeneric(): DPoint
public abstract @org.jetbrains.annotations.NotNull method getSomethingMFVC(): DPoint
public abstract method getSomethingRegular(): int
public abstract method setSomethingGeneric-f_6zJnY(p0: double, p1: double): void
public abstract method setSomethingMFVC-f_6zJnY(p0: double, p1: double): void
public abstract method setSomethingGeneric-sUp7gFk(p0: double, p1: double): void
public abstract method setSomethingMFVC-sUp7gFk(p0: double, p1: double): void
public abstract method setSomethingRegular(p0: int): void
}
+147
View File
@@ -0,0 +1,147 @@
// IGNORE_BACKEND_FIR: JVM_IR
// https://youtrack.jetbrains.com/issue/KT-52236/Different-modality-in-psi-and-fir
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class Public(val x: Int, val y: Int) {
companion object {
// TODO
}
}
@JvmInline
value class Internal(internal val x: Int, internal val y: Int) {
companion object {
// @JvmStatic
// TODO
}
}
@JvmInline
value class Private(private val x: Int, private val y: Int)
@JvmInline
value class PublicPublic(val value: Public)
@JvmInline
value class InternalPublic(internal val value: Public)
@JvmInline
value class PrivatePublic(private val value: Public)
@JvmInline
value class PublicInternal(val value: Internal)
@JvmInline
value class InternalInternal(internal val value: Internal)
@JvmInline
value class PrivateInternal(private val value: Internal)
@JvmInline
value class PublicPrivate(val value: Private)
@JvmInline
value class InternalPrivate(internal val value: Private)
@JvmInline
value class PrivatePrivate(private val value: Private)
class Regular {
var x1: Public = Public(1, 2)
internal var x2: Public = Public(3, 4)
private var x3: Public = Public(5, 6)
var x4: Public = Public(7, 8)
private set
internal var x5: Public = Public(9, 10)
private set
var x6: Public = Public(11, 12)
internal set
var y1: Internal = Internal(13, 14)
internal var y2: Internal = Internal(15, 16)
private var y3: Internal = Internal(17, 18)
var y4: Internal = Internal(19, 20)
private set
internal var y5: Internal = Internal(21, 22)
private set
var y6: Internal = Internal(23, 24)
internal set
var z1: Private = Private(25, 26)
internal var z2: Private = Private(27, 28)
private var z3: Private = Private(29, 30)
var z4: Private = Private(31, 32)
private set
internal var z5: Private = Private(33, 34)
private set
var z6: Private = Private(35, 36)
internal set
companion object {
// TODO @JvmStatic
var staticX1: Public = Public(-1, -2)
internal var staticX2: Public = Public(-3, -4)
private var staticX3: Public = Public(-5, -6)
var staticX4: Public = Public(-7, -8)
private set
internal var staticX5: Public = Public(-9, -10)
private set
var staticX6: Public = Public(-11, -12)
internal set
var staticY1: Internal = Internal(-13, -14)
internal var staticY2: Internal = Internal(-15, -16)
private var staticY3: Internal = Internal(-17, -18)
var staticY4: Internal = Internal(-19, -20)
private set
internal var staticY5: Internal = Internal(-21, -22)
private set
var staticY6: Internal = Internal(-23, -24)
internal set
var staticZ1: Private = Private(-25, -26)
internal var staticZ2: Private = Private(-27, -28)
private var staticZ3: Private = Private(-29, -30)
var staticZ4: Private = Private(-31, -32)
private set
internal var staticZ5: Private = Private(-33, -34)
private set
var staticZ6: Private = Private(-35, -36)
internal set
}
// TODO statics
fun callAll() {
z6
x3
x3.x
x3.y
}
}
fun box(): String {
Regular().callAll()
return "OK"
}
@@ -0,0 +1,377 @@
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class Internal {
// source: 'visibility.kt'
private field x: int
private field y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): Internal
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
public final method getX$main(): int
public final method getY$main(): int
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class InternalInternal {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): InternalInternal
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
public final @org.jetbrains.annotations.NotNull method getValue$main(): Internal
public final method getValue$x$main(): int
public final method getValue$y$main(): int
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class InternalPrivate {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): InternalPrivate
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
public final @org.jetbrains.annotations.NotNull method getValue$main(): Private
private final method getValue$x(): int
private final method getValue$y(): int
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class InternalPublic {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): InternalPublic
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
public final @org.jetbrains.annotations.NotNull method getValue$main(): Public
public final method getValue$x$main(): int
public final method getValue$y$main(): int
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class Private {
// source: 'visibility.kt'
private field x: int
private field y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): Private
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
private final method getX(): int
private final method getY(): int
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class PrivateInternal {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): PrivateInternal
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
private final method getValue$x(): int
private final method getValue$y(): int
private final method getValue(): Internal
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class PrivatePrivate {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): PrivatePrivate
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
private final method getValue$x(): int
private final method getValue$y(): int
private final method getValue(): Private
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class PrivatePublic {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): PrivatePublic
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
private final method getValue$x(): int
private final method getValue$y(): int
private final method getValue(): Public
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class Public {
// source: 'visibility.kt'
private field x: int
private field y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): Public
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
public final method getX(): int
public final method getY(): int
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class PublicInternal {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): PublicInternal
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
public final method getValue$x$main(): int
public final method getValue$y$main(): int
public final @org.jetbrains.annotations.NotNull method getValue(): Internal
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class PublicPrivate {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): PublicPrivate
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
private final method getValue$x(): int
private final method getValue$y(): int
public final @org.jetbrains.annotations.NotNull method getValue(): Private
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class PublicPublic {
// source: 'visibility.kt'
private field value$x: int
private field value$y: int
private synthetic method <init>(p0: int, p1: int): void
public synthetic final static method box-impl(p0: int, p1: int): PublicPublic
public final static method constructor-impl(p0: int, p1: int): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
public final method getValue$x(): int
public final method getValue$y(): int
public final @org.jetbrains.annotations.NotNull method getValue(): Public
public method hashCode(): int
public static method hashCode-impl(p0: int, p1: int): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: int, p1: int): java.lang.String
public synthetic final method unbox-impl0(): int
public synthetic final method unbox-impl1(): int
}
@kotlin.Metadata
public final class Regular {
// source: 'visibility.kt'
private field x1$x: int
private field x1$y: int
private field x2$x: int
private field x2$y: int
private field x3$x: int
private field x3$y: int
private field x4$x: int
private field x4$y: int
private field x5$x: int
private field x5$y: int
private field x6$x: int
private field x6$y: int
private field y1$x: int
private field y1$y: int
private field y2$x: int
private field y2$y: int
private field y3$x: int
private field y3$y: int
private field y4$x: int
private field y4$y: int
private field y5$x: int
private field y5$y: int
private field y6$x: int
private field y6$y: int
private field z1$x: int
private field z1$y: int
private field z2$x: int
private field z2$y: int
private field z3$x: int
private field z3$y: int
private field z4$x: int
private field z4$y: int
private field z5$x: int
private field z5$y: int
private field z6$x: int
private field z6$y: int
public method <init>(): void
public final method callAll(): void
public final method getX1$x(): int
public final method getX1$y(): int
public final @org.jetbrains.annotations.NotNull method getX1(): Public
public final @org.jetbrains.annotations.NotNull method getX2$main(): Public
public final method getX2$x$main(): int
public final method getX2$y$main(): int
private final method getX3(): Public
public final method getX4$x(): int
public final method getX4$y(): int
public final @org.jetbrains.annotations.NotNull method getX4(): Public
public final @org.jetbrains.annotations.NotNull method getX5$main(): Public
public final method getX5$x$main(): int
public final method getX5$y$main(): int
public final method getX6$x(): int
public final method getX6$y(): int
public final @org.jetbrains.annotations.NotNull method getX6(): Public
public final method getY1$x$main(): int
public final method getY1$y$main(): int
public final @org.jetbrains.annotations.NotNull method getY1(): Internal
public final @org.jetbrains.annotations.NotNull method getY2$main(): Internal
public final method getY2$x$main(): int
public final method getY2$y$main(): int
private final method getY3(): Internal
public final method getY4$x$main(): int
public final method getY4$y$main(): int
public final @org.jetbrains.annotations.NotNull method getY4(): Internal
public final @org.jetbrains.annotations.NotNull method getY5$main(): Internal
public final method getY5$x$main(): int
public final method getY5$y$main(): int
public final method getY6$x$main(): int
public final method getY6$y$main(): int
public final @org.jetbrains.annotations.NotNull method getY6(): Internal
public final @org.jetbrains.annotations.NotNull method getZ1(): Private
public final @org.jetbrains.annotations.NotNull method getZ2$main(): Private
private final method getZ3(): Private
public final @org.jetbrains.annotations.NotNull method getZ4(): Private
public final @org.jetbrains.annotations.NotNull method getZ5$main(): Private
public final @org.jetbrains.annotations.NotNull method getZ6(): Private
public final method setX1-sUp7gFk(p0: int, p1: int): void
public final method setX2-sUp7gFk$main(p0: int, p1: int): void
private final method setX3-sUp7gFk(p0: int, p1: int): void
private final method setX4-sUp7gFk(p0: int, p1: int): void
private final method setX5-sUp7gFk(p0: int, p1: int): void
public final method setX6-sUp7gFk$main(p0: int, p1: int): void
public final method setY1-sUp7gFk(p0: int, p1: int): void
public final method setY2-sUp7gFk$main(p0: int, p1: int): void
private final method setY3-sUp7gFk(p0: int, p1: int): void
private final method setY4-sUp7gFk(p0: int, p1: int): void
private final method setY5-sUp7gFk(p0: int, p1: int): void
public final method setY6-sUp7gFk$main(p0: int, p1: int): void
public final method setZ1-sUp7gFk(p0: int, p1: int): void
public final method setZ2-sUp7gFk$main(p0: int, p1: int): void
private final method setZ3-sUp7gFk(p0: int, p1: int): void
private final method setZ4-sUp7gFk(p0: int, p1: int): void
private final method setZ5-sUp7gFk(p0: int, p1: int): void
public final method setZ6-sUp7gFk$main(p0: int, p1: int): void
}
@kotlin.Metadata
public final class VisibilityKt {
// source: 'visibility.kt'
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
}
@@ -64,5 +64,5 @@ fun functionWithoutBoxes(x: D, y: D) {
// 1 INVOKESTATIC D.box-impl \(IILjava/lang/String;\)LD;\n ARETURN
// 1 INVOKESTATIC C.box-impl \(IILjava/lang/String;\)LC;
// 1 INVOKESTATIC C.box-impl \(IILjava/lang/String;\)LC;\n ARETURN
// 1 public final static functionWithoutBoxes-GPBa7dw-AYZo7_8\(IILjava/lang/String;IILjava/lang/String;\)V
// 1 public final static functionWithoutBoxes-GPBa7dw\(IILjava/lang/String;IILjava/lang/String;\)V
// 0 functionWithoutBoxes.*(\n {3}.*)*(\n {4}(NEW [ABCD]|.*(box|[ABCD]\.<init>|LA;|LB;|LC;|LD;)))
@@ -50230,6 +50230,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testThrowingMFVCReassignments() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("visibility.kt")
public void testVisibility() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/visibility.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
}
@Nested