[IR] Rename MFVC tests + Add test for get-field optimization
#KT-1179
This commit is contained in:
committed by
teamcity
parent
2c50fef251
commit
e76041bb3b
+2
-2
@@ -50202,9 +50202,9 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("MfvcFieldInitializationOrder.kt")
|
@TestMetadata("mfvcFieldInitializationOrder.kt")
|
||||||
public void testMfvcFieldInitializationOrder() throws Exception {
|
public void testMfvcFieldInitializationOrder() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/valueClasses/MfvcFieldInitializationOrder.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
runTest("compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+6
-6
@@ -5796,15 +5796,15 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("MFVCDeclaration.kt")
|
@TestMetadata("mfvcDeclaration.kt")
|
||||||
public void testMFVCDeclaration() throws Exception {
|
public void testMfvcDeclaration() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/MFVCDeclaration.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("MFVCReassignments.kt")
|
@TestMetadata("mfvcReassignments.kt")
|
||||||
public void testMFVCReassignments() throws Exception {
|
public void testMfvcReassignments() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/MFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+1
-1
@@ -692,7 +692,7 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
val instance = targetRemappedParameter.rootMfvcNode.createInstanceFromBox(
|
val instance = targetRemappedParameter.rootMfvcNode.createInstanceFromBox(
|
||||||
this@irBlock,
|
this@irBlock,
|
||||||
irCastIfNeeded(irGet(bridgeParameter), targetParameterType),
|
irCastIfNeeded(irGet(bridgeParameter), targetParameterType),
|
||||||
hasAccessToPrivateMembersOf(target, targetRemappedParameter.rootMfvcNode.mfvc)
|
getOptimizedPublicAccess(target, targetRemappedParameter.rootMfvcNode.mfvc)
|
||||||
) { error("Not applicable") }
|
) { error("Not applicable") }
|
||||||
val newArguments = instance.makeFlattenedGetterExpressions()
|
val newArguments = instance.makeFlattenedGetterExpressions()
|
||||||
for (newArgument in newArguments) {
|
for (newArgument in newArguments) {
|
||||||
|
|||||||
+16
-12
@@ -131,7 +131,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
val typeArguments = makeTypeArgumentsFromField(expression)
|
val typeArguments = makeTypeArgumentsFromField(expression)
|
||||||
var instance: ReceiverBasedMfvcNodeInstance? = null
|
var instance: ReceiverBasedMfvcNodeInstance? = null
|
||||||
return scope.irBlock {
|
return scope.irBlock {
|
||||||
instance = node.createInstanceFromBox(this, typeArguments, expression.receiver, true, ::variablesSaver)
|
instance = node.createInstanceFromBox(this, typeArguments, expression.receiver, AccessType.AlwaysPrivate, ::variablesSaver)
|
||||||
+instance!!.makeGetterExpression()
|
+instance!!.makeGetterExpression()
|
||||||
}.also { expression2MfvcNodeInstanceAccessor[it] = MfvcNodeInstanceAccessor.Getter(instance!!) }
|
}.also { expression2MfvcNodeInstanceAccessor[it] = MfvcNodeInstanceAccessor.Getter(instance!!) }
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
var instance: ReceiverBasedMfvcNodeInstance? = null
|
var instance: ReceiverBasedMfvcNodeInstance? = null
|
||||||
var values: List<IrExpression>? = null
|
var values: List<IrExpression>? = null
|
||||||
return scope.irBlock {
|
return scope.irBlock {
|
||||||
instance = node.createInstanceFromBox(this, typeArguments, expression.receiver, true, ::variablesSaver)
|
instance = node.createInstanceFromBox(this, typeArguments, expression.receiver, AccessType.AlwaysPrivate, ::variablesSaver)
|
||||||
values = makeFlattenedExpressionsWithGivenSafety(node, safe, expression.value)
|
values = makeFlattenedExpressionsWithGivenSafety(node, safe, expression.value)
|
||||||
instance!!.addSetterStatements(this, values!!)
|
instance!!.addSetterStatements(this, values!!)
|
||||||
}.also { expression2MfvcNodeInstanceAccessor[it] = MfvcNodeInstanceAccessor.Setter(instance!!, values!!) }
|
}.also { expression2MfvcNodeInstanceAccessor[it] = MfvcNodeInstanceAccessor.Setter(instance!!, values!!) }
|
||||||
@@ -153,12 +153,19 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
fun makeReplacement(scope: IrBuilderWithScope, expression: IrCall): IrExpression? {
|
fun makeReplacement(scope: IrBuilderWithScope, expression: IrCall): IrExpression? {
|
||||||
val function = expression.symbol.owner
|
val function = expression.symbol.owner
|
||||||
val property = function.property?.takeIf { function.isGetter } ?: return null
|
val property = function.property?.takeIf { function.isGetter } ?: return null
|
||||||
expression.dispatchReceiver?.get(property.name)?.let { return it }
|
val dispatchReceiver = expression.dispatchReceiver
|
||||||
|
dispatchReceiver?.get(property.name)?.let { return it }
|
||||||
val node = replacements.getMfvcPropertyNode(property) ?: return null
|
val node = replacements.getMfvcPropertyNode(property) ?: return null
|
||||||
val typeArguments = makeTypeArgumentsFromFunction(expression)
|
val typeArguments = makeTypeArgumentsFromFunction(expression)
|
||||||
var instance: ReceiverBasedMfvcNodeInstance? = null
|
var instance: ReceiverBasedMfvcNodeInstance? = null
|
||||||
return scope.irBlock {
|
return scope.irBlock {
|
||||||
instance = node.createInstanceFromBox(this, typeArguments, expression.dispatchReceiver, false, ::variablesSaver)
|
// Optimization: pure function access to leaf can be replaced with field access if the field itself is accessible
|
||||||
|
val accessType = when {
|
||||||
|
!node.hasPureUnboxMethod -> AccessType.AlwaysPublic
|
||||||
|
dispatchReceiver == null -> AccessType.PrivateWhenNoBox
|
||||||
|
else -> getOptimizedPublicAccess(dispatchReceiver.type.erasedUpperBound)
|
||||||
|
}
|
||||||
|
instance = node.createInstanceFromBox(this, typeArguments, dispatchReceiver, accessType, ::variablesSaver)
|
||||||
+instance!!.makeGetterExpression()
|
+instance!!.makeGetterExpression()
|
||||||
}.also { expression2MfvcNodeInstanceAccessor[it] = MfvcNodeInstanceAccessor.Getter(instance!!) }
|
}.also { expression2MfvcNodeInstanceAccessor[it] = MfvcNodeInstanceAccessor.Getter(instance!!) }
|
||||||
}
|
}
|
||||||
@@ -502,7 +509,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
val receiver = sourceExplicitParameters[flattenedSourceIndex++]
|
val receiver = sourceExplicitParameters[flattenedSourceIndex++]
|
||||||
val rootNode = remappedTargetParameter.rootMfvcNode
|
val rootNode = remappedTargetParameter.rootMfvcNode
|
||||||
val instance = rootNode.createInstanceFromBox(
|
val instance = rootNode.createInstanceFromBox(
|
||||||
this@irBlock, irGet(receiver), hasAccessToPrivateMembersOf(rootNode.mfvc), ::variablesSaver
|
this@irBlock, irGet(receiver), getOptimizedPublicAccess(rootNode.mfvc), ::variablesSaver,
|
||||||
)
|
)
|
||||||
val flattenedExpressions = instance.makeFlattenedGetterExpressions()
|
val flattenedExpressions = instance.makeFlattenedGetterExpressions()
|
||||||
for (expression in flattenedExpressions) {
|
for (expression in flattenedExpressions) {
|
||||||
@@ -982,17 +989,14 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val expressionInstance = flattenedExpressionInstance ?: rootNode.createInstanceFromBox(
|
val expressionInstance = flattenedExpressionInstance ?: rootNode.createInstanceFromBox(
|
||||||
this,
|
this, transformedExpression, getOptimizedPublicAccess(rootNode.mfvc), ::variablesSaver,
|
||||||
transformedExpression,
|
|
||||||
hasAccessToPrivateMembersOf(rootNode.mfvc),
|
|
||||||
::variablesSaver,
|
|
||||||
)
|
)
|
||||||
require(expressionInstance.size == instance.size) { "Incompatible assignment sizes: ${expressionInstance.size}, ${instance.size}" }
|
require(expressionInstance.size == instance.size) { "Incompatible assignment sizes: ${expressionInstance.size}, ${instance.size}" }
|
||||||
instance.addSetterStatements(this, expressionInstance.makeFlattenedGetterExpressions())
|
instance.addSetterStatements(this, expressionInstance.makeFlattenedGetterExpressions())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasAccessToPrivateMembersOf(parent: IrClass): Boolean =
|
private fun getOptimizedPublicAccess(parent: IrClass): AccessType =
|
||||||
currentScope?.irElement?.let { hasAccessToPrivateMembersOf(it, parent) } == true
|
currentScope?.irElement?.let { getOptimizedPublicAccess(it, parent) } ?: AccessType.AlwaysPublic
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes boxing when the result is not used
|
* Removes boxing when the result is not used
|
||||||
@@ -1123,7 +1127,7 @@ private fun IrStatement.containsUsagesOf(variablesSet: Set<IrVariable>): Boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds declrations of the variables to the most narrow possible block or body.
|
* Adds declarations of the variables to the most narrow possible block or body.
|
||||||
* It adds them before the first usage within the block and inlines initialization of them when possible.
|
* It adds them before the first usage within the block and inlines initialization of them when possible.
|
||||||
*/
|
*/
|
||||||
fun IrBody.makeBodyWithAddedVariables(
|
fun IrBody.makeBodyWithAddedVariables(
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ sealed interface MfvcNode {
|
|||||||
scope: IrBlockBuilder,
|
scope: IrBlockBuilder,
|
||||||
typeArguments: TypeArguments,
|
typeArguments: TypeArguments,
|
||||||
receiver: IrExpression?,
|
receiver: IrExpression?,
|
||||||
isPrivateAccess: Boolean,
|
accessType: AccessType,
|
||||||
saveVariable: (IrVariable) -> Unit,
|
saveVariable: (IrVariable) -> Unit,
|
||||||
): ReceiverBasedMfvcNodeInstance
|
): ReceiverBasedMfvcNodeInstance
|
||||||
}
|
}
|
||||||
@@ -41,10 +41,10 @@ sealed interface MfvcNode {
|
|||||||
fun MfvcNode.createInstanceFromBox(
|
fun MfvcNode.createInstanceFromBox(
|
||||||
scope: IrBlockBuilder,
|
scope: IrBlockBuilder,
|
||||||
receiver: IrExpression,
|
receiver: IrExpression,
|
||||||
isPrivateAccess: Boolean,
|
accessType: AccessType,
|
||||||
saveVariable: (IrVariable) -> Unit
|
saveVariable: (IrVariable) -> Unit
|
||||||
) =
|
) =
|
||||||
createInstanceFromBox(scope, makeTypeArgumentsFromType(receiver.type as IrSimpleType), receiver, isPrivateAccess, saveVariable)
|
createInstanceFromBox(scope, makeTypeArgumentsFromType(receiver.type as IrSimpleType), receiver, accessType, saveVariable)
|
||||||
|
|
||||||
fun MfvcNode.createInstanceFromValueDeclarationsAndBoxType(
|
fun MfvcNode.createInstanceFromValueDeclarationsAndBoxType(
|
||||||
scope: IrBuilderWithScope, type: IrSimpleType, name: Name, saveVariable: (IrVariable) -> Unit,
|
scope: IrBuilderWithScope, type: IrSimpleType, name: Name, saveVariable: (IrVariable) -> Unit,
|
||||||
@@ -314,10 +314,10 @@ class LeafMfvcNode(
|
|||||||
scope: IrBlockBuilder,
|
scope: IrBlockBuilder,
|
||||||
typeArguments: TypeArguments,
|
typeArguments: TypeArguments,
|
||||||
receiver: IrExpression?,
|
receiver: IrExpression?,
|
||||||
isPrivateAccess: Boolean,
|
accessType: AccessType,
|
||||||
saveVariable: (IrVariable) -> Unit,
|
saveVariable: (IrVariable) -> Unit,
|
||||||
) = ReceiverBasedMfvcNodeInstance(
|
) = ReceiverBasedMfvcNodeInstance(
|
||||||
scope, this, typeArguments, receiver, field?.let(::listOf), unboxMethod, isPrivateAccess, saveVariable
|
scope, this, typeArguments, receiver, field?.let(::listOf), unboxMethod, accessType, saveVariable
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun toString(): String = "$fullFieldName: ${type.render()}"
|
override fun toString(): String = "$fullFieldName: ${type.render()}"
|
||||||
@@ -364,10 +364,10 @@ class IntermediateMfvcNode(
|
|||||||
scope: IrBlockBuilder,
|
scope: IrBlockBuilder,
|
||||||
typeArguments: TypeArguments,
|
typeArguments: TypeArguments,
|
||||||
receiver: IrExpression?,
|
receiver: IrExpression?,
|
||||||
isPrivateAccess: Boolean,
|
accessType: AccessType,
|
||||||
saveVariable: (IrVariable) -> Unit,
|
saveVariable: (IrVariable) -> Unit,
|
||||||
) = ReceiverBasedMfvcNodeInstance(
|
) = ReceiverBasedMfvcNodeInstance(
|
||||||
scope, this, typeArguments, receiver, fields, unboxMethod, isPrivateAccess, saveVariable
|
scope, this, typeArguments, receiver, fields, unboxMethod, accessType, saveVariable
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
@@ -460,9 +460,9 @@ class RootMfvcNode internal constructor(
|
|||||||
scope: IrBlockBuilder,
|
scope: IrBlockBuilder,
|
||||||
typeArguments: TypeArguments,
|
typeArguments: TypeArguments,
|
||||||
receiver: IrExpression?,
|
receiver: IrExpression?,
|
||||||
isPrivateAccess: Boolean,
|
accessType: AccessType,
|
||||||
saveVariable: (IrVariable) -> Unit,
|
saveVariable: (IrVariable) -> Unit,
|
||||||
) = ReceiverBasedMfvcNodeInstance(scope, this, typeArguments, receiver, fields, null, isPrivateAccess, saveVariable)
|
) = ReceiverBasedMfvcNodeInstance(scope, this, typeArguments, receiver, fields, null, accessType, saveVariable)
|
||||||
|
|
||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
"${type.render()}\n${subnodes.joinToString("\n").prependIndent(" ")}"
|
"${type.render()}\n${subnodes.joinToString("\n").prependIndent(" ")}"
|
||||||
|
|||||||
@@ -471,16 +471,17 @@ private fun getOverriddenNode(replacements: MemoizedMultiFieldValueClassReplacem
|
|||||||
.firstOrNull { !it.owner.isFakeOverride }
|
.firstOrNull { !it.owner.isFakeOverride }
|
||||||
?.let { replacements.getMfvcPropertyNode(it.owner.correspondingPropertySymbol!!.owner) }
|
?.let { replacements.getMfvcPropertyNode(it.owner.correspondingPropertySymbol!!.owner) }
|
||||||
|
|
||||||
fun hasAccessToPrivateMembersOf(currentElement: IrElement?, parent: IrClass): Boolean {
|
fun getOptimizedPublicAccess(currentElement: IrElement?, parent: IrClass): AccessType {
|
||||||
val declaration = currentElement as? IrDeclaration ?: return false
|
val declaration = currentElement as? IrDeclaration ?: return AccessType.AlwaysPublic
|
||||||
for (cur in declaration.parents.filterIsInstance<IrClass>()) {
|
for (cur in declaration.parents.filterIsInstance<IrClass>()) {
|
||||||
return when {
|
return when {
|
||||||
cur == parent -> true
|
cur == parent -> AccessType.PrivateWhenNoBox
|
||||||
cur.isInner -> continue
|
cur.isInner -> continue
|
||||||
else -> false
|
cur.isCompanion -> continue
|
||||||
|
else -> AccessType.AlwaysPublic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return AccessType.AlwaysPublic
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrProperty.getterIfDeclared(parent: IrDeclarationContainer): IrSimpleFunction? = getter?.takeIf { it in parent.declarations }
|
private fun IrProperty.getterIfDeclared(parent: IrDeclarationContainer): IrSimpleFunction? = getter?.takeIf { it in parent.declarations }
|
||||||
|
|||||||
@@ -142,6 +142,8 @@ fun IrExpression?.isRepeatableSetter(): Boolean = when (this) {
|
|||||||
|
|
||||||
fun IrExpression?.isRepeatableAccessor(): Boolean = isRepeatableGetter() || isRepeatableSetter()
|
fun IrExpression?.isRepeatableAccessor(): Boolean = isRepeatableGetter() || isRepeatableSetter()
|
||||||
|
|
||||||
|
enum class AccessType { AlwaysPublic, PrivateWhenNoBox, AlwaysPrivate }
|
||||||
|
|
||||||
class ReceiverBasedMfvcNodeInstance(
|
class ReceiverBasedMfvcNodeInstance(
|
||||||
override val scope: IrBlockBuilder,
|
override val scope: IrBlockBuilder,
|
||||||
override val node: MfvcNode,
|
override val node: MfvcNode,
|
||||||
@@ -149,7 +151,7 @@ class ReceiverBasedMfvcNodeInstance(
|
|||||||
receiver: IrExpression?,
|
receiver: IrExpression?,
|
||||||
val fields: List<IrField>?,
|
val fields: List<IrField>?,
|
||||||
val unboxMethod: IrSimpleFunction?,
|
val unboxMethod: IrSimpleFunction?,
|
||||||
val isPrivateAccess: Boolean,
|
val accessType: AccessType,
|
||||||
private val saveVariable: (IrVariable) -> Unit,
|
private val saveVariable: (IrVariable) -> Unit,
|
||||||
) : MfvcNodeInstance {
|
) : MfvcNodeInstance {
|
||||||
override val type: IrSimpleType = makeTypeFromMfvcNodeAndTypeArguments(node, typeArguments)
|
override val type: IrSimpleType = makeTypeFromMfvcNodeAndTypeArguments(node, typeArguments)
|
||||||
@@ -169,7 +171,9 @@ class ReceiverBasedMfvcNodeInstance(
|
|||||||
override fun makeFlattenedGetterExpressions(): List<IrExpression> = when (node) {
|
override fun makeFlattenedGetterExpressions(): List<IrExpression> = when (node) {
|
||||||
is LeafMfvcNode -> listOf(makeGetterExpression())
|
is LeafMfvcNode -> listOf(makeGetterExpression())
|
||||||
is MfvcNodeWithSubnodes -> when {
|
is MfvcNodeWithSubnodes -> when {
|
||||||
node is IntermediateMfvcNode && isPrivateAccess && fields != null -> fields.map { scope.irGetField(makeReceiverCopy(), it) }
|
node is IntermediateMfvcNode && canUsePrivateAccessFor(node) && fields != null ->
|
||||||
|
fields.map { scope.irGetField(makeReceiverCopy(), it) }
|
||||||
|
|
||||||
node is IntermediateMfvcNode && !node.hasPureUnboxMethod -> {
|
node is IntermediateMfvcNode && !node.hasPureUnboxMethod -> {
|
||||||
val value = makeGetterExpression()
|
val value = makeGetterExpression()
|
||||||
val asVariable = scope.savableStandaloneVariableWithSetter(
|
val asVariable = scope.savableStandaloneVariableWithSetter(
|
||||||
@@ -180,7 +184,7 @@ class ReceiverBasedMfvcNodeInstance(
|
|||||||
)
|
)
|
||||||
val root = node.rootNode
|
val root = node.rootNode
|
||||||
val variableInstance =
|
val variableInstance =
|
||||||
root.createInstanceFromBox(scope, typeArguments, scope.irGet(asVariable), isPrivateAccess = false, saveVariable)
|
root.createInstanceFromBox(scope, typeArguments, scope.irGet(asVariable), accessType, saveVariable)
|
||||||
variableInstance.makeFlattenedGetterExpressions()
|
variableInstance.makeFlattenedGetterExpressions()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,8 +194,8 @@ class ReceiverBasedMfvcNodeInstance(
|
|||||||
|
|
||||||
override fun makeGetterExpression(): IrExpression = with(scope) {
|
override fun makeGetterExpression(): IrExpression = with(scope) {
|
||||||
when {
|
when {
|
||||||
node is LeafMfvcNode && isPrivateAccess && fields != null -> irGetField(makeReceiverCopy(), fields.single())
|
node is LeafMfvcNode && canUsePrivateAccessFor(node) && fields != null -> irGetField(makeReceiverCopy(), fields.single())
|
||||||
node is IntermediateMfvcNode && isPrivateAccess && fields != null -> node.makeBoxedExpression(
|
node is IntermediateMfvcNode && accessType == AccessType.AlwaysPrivate && fields != null -> node.makeBoxedExpression(
|
||||||
this, typeArguments, fields.map { irGetField(makeReceiverCopy(), it) }
|
this, typeArguments, fields.map { irGetField(makeReceiverCopy(), it) }
|
||||||
)
|
)
|
||||||
unboxMethod != null -> irCall(unboxMethod).apply {
|
unboxMethod != null -> irCall(unboxMethod).apply {
|
||||||
@@ -210,9 +214,12 @@ class ReceiverBasedMfvcNodeInstance(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun canUsePrivateAccessFor(node: NameableMfvcNode) =
|
||||||
|
node.hasPureUnboxMethod && accessType == AccessType.PrivateWhenNoBox || accessType == AccessType.AlwaysPrivate
|
||||||
|
|
||||||
override fun get(name: Name): ReceiverBasedMfvcNodeInstance? {
|
override fun get(name: Name): ReceiverBasedMfvcNodeInstance? {
|
||||||
val (newNode, _) = node.getSubnodeAndIndices(name) ?: return null
|
val (newNode, _) = node.getSubnodeAndIndices(name) ?: return null
|
||||||
return newNode.createInstanceFromBox(scope, typeArguments, makeReceiverCopy(), isPrivateAccess, saveVariable)
|
return newNode.createInstanceFromBox(scope, typeArguments, makeReceiverCopy(), accessType, saveVariable)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun makeStatements(values: List<IrExpression>): List<IrStatement> {
|
override fun makeStatements(values: List<IrExpression>): List<IrStatement> {
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class A {
|
public final class A {
|
||||||
// source: 'MfvcFieldInitializationOrder.kt'
|
// source: 'mfvcFieldInitializationOrder.kt'
|
||||||
private field x-0: double
|
private field x-0: double
|
||||||
private field x-1: double
|
private field x-1: double
|
||||||
public method <init>(p0: double, p1: double): void
|
public method <init>(p0: double, p1: double): void
|
||||||
@@ -12,7 +12,7 @@ public final class A {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class B {
|
public final class B {
|
||||||
// source: 'MfvcFieldInitializationOrder.kt'
|
// source: 'mfvcFieldInitializationOrder.kt'
|
||||||
private field a-0: double
|
private field a-0: double
|
||||||
private field a-1: double
|
private field a-1: double
|
||||||
private final field b-0: double
|
private final field b-0: double
|
||||||
@@ -35,7 +35,7 @@ public final class B {
|
|||||||
@kotlin.jvm.JvmInline
|
@kotlin.jvm.JvmInline
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class DPoint {
|
public final class DPoint {
|
||||||
// source: 'MfvcFieldInitializationOrder.kt'
|
// source: 'mfvcFieldInitializationOrder.kt'
|
||||||
private final field field-0: double
|
private final field field-0: double
|
||||||
private final field field-1: double
|
private final field field-1: double
|
||||||
private synthetic method <init>(p0: double, p1: double): void
|
private synthetic method <init>(p0: double, p1: double): void
|
||||||
@@ -56,6 +56,6 @@ public final class DPoint {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class MfvcFieldInitializationOrderKt {
|
public final class MfvcFieldInitializationOrderKt {
|
||||||
// source: 'MfvcFieldInitializationOrder.kt'
|
// source: 'mfvcFieldInitializationOrder.kt'
|
||||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
}
|
}
|
||||||
+11
-2
@@ -22,6 +22,14 @@ value class D(val x: C) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Regular(private val x: D) {
|
||||||
|
fun privateAccess() {
|
||||||
|
listOf(x.x.x)
|
||||||
|
listOf(x.x)
|
||||||
|
listOf(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun functionWithoutBoxes(x: D, y: D) {
|
fun functionWithoutBoxes(x: D, y: D) {
|
||||||
var z: D = x
|
var z: D = x
|
||||||
val t: D = D(C(1, B(3U), "4"))
|
val t: D = D(C(1, B(3U), "4"))
|
||||||
@@ -61,7 +69,8 @@ fun functionWithoutBoxes(x: D, y: D) {
|
|||||||
// 1 private final Ljava/lang/String; field-2\n
|
// 1 private final Ljava/lang/String; field-2\n
|
||||||
// 1 INVOKESPECIAL C.<init> \(IILjava/lang/String;\)V
|
// 1 INVOKESPECIAL C.<init> \(IILjava/lang/String;\)V
|
||||||
// 1 INVOKESPECIAL D.<init> \(IILjava/lang/String;\)V
|
// 1 INVOKESPECIAL D.<init> \(IILjava/lang/String;\)V
|
||||||
// 1 INVOKESTATIC D.box-impl \(IILjava/lang/String;\)LD;
|
// 2 INVOKESTATIC D.box-impl \(IILjava/lang/String;\)LD;
|
||||||
// 2 INVOKESTATIC C.box-impl \(IILjava/lang/String;\)LC;
|
// 3 INVOKESTATIC C.box-impl \(IILjava/lang/String;\)LC;
|
||||||
// 1 public final static functionWithoutBoxes-GPBa7dw\(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;)))
|
// 0 functionWithoutBoxes.*(\n {3}.*)*(\n {4}(NEW [ABCD]|.*(box|[ABCD]\.<init>|LA;|LB;|LC;|LD;)))
|
||||||
|
// 1 privateAccess.*(\n .+)*(\n GETFIELD Regular\.x-0-0 : I)(\n .+)*(\n INVOKEVIRTUAL Regular\.getX-0 \(\)LC;)(\n .+)*(\n INVOKESPECIAL Regular\.getX \(\)LD;)
|
||||||
+2
-2
@@ -50202,9 +50202,9 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("MfvcFieldInitializationOrder.kt")
|
@TestMetadata("mfvcFieldInitializationOrder.kt")
|
||||||
public void testMfvcFieldInitializationOrder() throws Exception {
|
public void testMfvcFieldInitializationOrder() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/valueClasses/MfvcFieldInitializationOrder.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
runTest("compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+6
-6
@@ -5796,15 +5796,15 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("MFVCDeclaration.kt")
|
@TestMetadata("mfvcDeclaration.kt")
|
||||||
public void testMFVCDeclaration() throws Exception {
|
public void testMfvcDeclaration() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/MFVCDeclaration.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("MFVCReassignments.kt")
|
@TestMetadata("mfvcReassignments.kt")
|
||||||
public void testMFVCReassignments() throws Exception {
|
public void testMfvcReassignments() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/MFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user