diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 6ef635706ff..d21690b5ffa 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -50207,6 +50207,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/valueClasses/equality.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("forStatement.kt") + public void testForStatement() throws Exception { + runTest("compiler/testData/codegen/box/valueClasses/forStatement.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("mfvcFieldInitializationOrder.kt") public void testMfvcFieldInitializationOrder() throws Exception { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index fcc3af36f60..85a2919b6e7 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -235,6 +235,7 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass irClass.declarations.remove(irFunction) irClass.addAbstractMethodStub(irFunction) } + irFunction.modality != Modality.FINAL -> { // If we have a non-abstract, non-final fake-override we need to put in an additional bridge which uses // INVOKESPECIAL to call the special bridge implementation in the superclass. @@ -263,6 +264,7 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass irClass.addSpecialBridge(superBridge, superTarget) } } + else -> { // If the method is final, // then we will not override it in a subclass and we do not need to generate an additional stub method. @@ -624,117 +626,129 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass irCastIfNeeded(irBlock { +irReturn(irCall(target, origin = IrStatementOrigin.BRIDGE_DELEGATION, superQualifierSymbol = superQualifierSymbol).apply { - val targetStructure = run { - val mfvcOrOriginal = - this@BridgeLowering.context.inlineClassReplacements.originalFunctionForMethodReplacement[target] - ?: this@BridgeLowering.context.inlineClassReplacements.originalFunctionForStaticReplacement[target] - ?: target - this@BridgeLowering.context.multiFieldValueClassReplacements - .bindingNewFunctionToParameterTemplateStructure[mfvcOrOriginal] - ?.also { structure -> - val errorMessage = { "Bad parameters structure: $structure" } - require(structure.sumOf { it.valueParameters.size } == target.explicitParametersCount) { errorMessage() } - } + val targetStructure = getStructure(target) + val bridgeStructure = getStructure(bridge) + + if (targetStructure == null && bridgeStructure == null) { + for ((param, targetParam) in bridge.explicitParameters.zip(target.explicitParameters)) { + putArgument(targetParam, irGetOrCast(bridge, param, targetParam)) + } + } else { + this@irBlock.addBoxedAndUnboxedMfvcArguments(targetStructure, bridgeStructure, target, bridge, this) } + }) + }.unwrapBlock(), bridge.returnType.upperBound) - val bridgeStructure = run { - val mfvcOrOriginal = - this@BridgeLowering.context.inlineClassReplacements.originalFunctionForMethodReplacement[bridge] - ?: this@BridgeLowering.context.inlineClassReplacements.originalFunctionForStaticReplacement[bridge] - ?: bridge - this@BridgeLowering.context.multiFieldValueClassReplacements - .bindingNewFunctionToParameterTemplateStructure[mfvcOrOriginal] - ?.also { structure -> - val errorMessage = { "Bad parameters structure: $structure" } - require(structure.sumOf { it.valueParameters.size } == bridge.explicitParametersCount) { errorMessage() } + private fun getStructure(function: IrSimpleFunction): List? { + val mfvcOrOriginal = context.inlineClassReplacements.originalFunctionForMethodReplacement[function] + ?: context.inlineClassReplacements.originalFunctionForStaticReplacement[function] + ?: function + val structure = context.multiFieldValueClassReplacements + .bindingNewFunctionToParameterTemplateStructure[mfvcOrOriginal] ?: return null + require(structure.sumOf { it.valueParameters.size } == function.explicitParametersCount) { + "Bad parameters structure: $structure" + } + + return structure + } + + private fun IrBlockBuilder.addBoxedAndUnboxedMfvcArguments( + targetStructure: List?, + bridgeStructure: List?, + target: IrSimpleFunction, + bridge: IrSimpleFunction, + irCall: IrCall + ) { + require( + targetStructure == null || bridgeStructure == null || + bridgeStructure.size == targetStructure.size && + (targetStructure zip bridgeStructure).none { (targetParameter, bridgeParameter) -> + targetParameter is MultiFieldValueClassMapping && bridgeParameter is MultiFieldValueClassMapping && + targetParameter.rootMfvcNode != bridgeParameter.rootMfvcNode + } + ) { "Incompatible structures: $bridgeStructure and $targetStructure" } + + val targetExplicitParameters = target.explicitParameters + val bridgeExplicitParameters = bridge.explicitParameters + var targetIndex = 0 + var bridgeIndex = 0 + var structureIndex = 0 + while (targetIndex < targetExplicitParameters.size && bridgeIndex < bridgeExplicitParameters.size) { + val targetRemappedParameter = targetStructure?.get(structureIndex) + val bridgeRemappedParameter = bridgeStructure?.get(structureIndex) + when (targetRemappedParameter) { + is MultiFieldValueClassMapping -> when (bridgeRemappedParameter) { + is MultiFieldValueClassMapping -> { + require(bridgeRemappedParameter.rootMfvcNode == targetRemappedParameter.rootMfvcNode) { + "Incompatible parameters: $bridgeRemappedParameter, $targetRemappedParameter" + } + repeat(bridgeRemappedParameter.valueParameters.size) { + val bridgeParameter = bridgeExplicitParameters[bridgeIndex++] + val targetParameter = targetExplicitParameters[targetIndex++] + irCall.putArgument(targetParameter, irGetOrCast(bridge, bridgeParameter, targetParameter)) } - } - - require(targetStructure == null || bridgeStructure == null || - bridgeStructure.size == targetStructure.size && - (targetStructure zip bridgeStructure).none { (targetParameter, bridgeParameter) -> - targetParameter is MultiFieldValueClassMapping && bridgeParameter is MultiFieldValueClassMapping && - targetParameter.rootMfvcNode != bridgeParameter.rootMfvcNode - }) { "Incompatible structures: $bridgeStructure and $targetStructure" } - - fun irGetOrCast(bridgeParameter: IrValueParameter, targetParameter: IrValueParameter) = - irGet(bridgeParameter).let { argument -> - if (bridgeParameter == bridge.dispatchReceiverParameter) - argument - else - irCastIfNeeded(argument, targetParameter.type.upperBound) } - val targetExplicitParameters = target.explicitParameters - val bridgeExplicitParameters = bridge.explicitParameters - var targetIndex = 0 - var bridgeIndex = 0 - var structureIndex = 0 - while (targetIndex < targetExplicitParameters.size && bridgeIndex < bridgeExplicitParameters.size) { - val targetRemappedParameter = targetStructure?.get(structureIndex) - val bridgeRemappedParameter = bridgeStructure?.get(structureIndex) - when (targetRemappedParameter) { - is MultiFieldValueClassMapping -> when (bridgeRemappedParameter) { - is MultiFieldValueClassMapping -> { - require(bridgeRemappedParameter.rootMfvcNode == targetRemappedParameter.rootMfvcNode) { - "Incompatible parameters: $bridgeRemappedParameter, $targetRemappedParameter" - } - repeat(bridgeRemappedParameter.valueParameters.size) { - val bridgeParameter = bridgeExplicitParameters[bridgeIndex++] - val targetParameter = targetExplicitParameters[targetIndex++] - putArgument(targetParameter, irGetOrCast(bridgeParameter, targetParameter)) - } - } + is RegularMapping, null -> { + val bridgeParameter = bridgeExplicitParameters[bridgeIndex++] + val targetParameterType = targetRemappedParameter.rootMfvcNode.mfvc.defaultType + val instance = targetRemappedParameter.rootMfvcNode.createInstanceFromBox( + this, + irCastIfNeeded(irGet(bridgeParameter), targetParameterType), + getOptimizedPublicAccess(target, targetRemappedParameter.rootMfvcNode.mfvc) + ) { error("Not applicable") } + val newArguments = instance.makeFlattenedGetterExpressions() + for (newArgument in newArguments) { + irCall.putArgument(targetExplicitParameters[targetIndex++], newArgument) + } + } + } - is RegularMapping, null -> { - val bridgeParameter = bridgeExplicitParameters[bridgeIndex++] - val targetParameterType = targetRemappedParameter.rootMfvcNode.mfvc.defaultType - val instance = targetRemappedParameter.rootMfvcNode.createInstanceFromBox( - this@irBlock, - irCastIfNeeded(irGet(bridgeParameter), targetParameterType), - getOptimizedPublicAccess(target, targetRemappedParameter.rootMfvcNode.mfvc) - ) { error("Not applicable") } - val newArguments = instance.makeFlattenedGetterExpressions() - for (newArgument in newArguments) { - putArgument(targetExplicitParameters[targetIndex++], newArgument) - } + is RegularMapping, null -> { + val targetParameter = targetExplicitParameters[targetIndex] + when (bridgeRemappedParameter) { + is MultiFieldValueClassMapping -> { + val valueArguments = List(bridgeRemappedParameter.rootMfvcNode.leavesCount) { + irGet(bridgeExplicitParameters[bridgeIndex++]) } + val boxCall = bridgeRemappedParameter.rootMfvcNode.makeBoxedExpression( + this, bridgeRemappedParameter.typeArguments, valueArguments + ) + irCall.putArgument(targetParameter, irCastIfNeeded(boxCall, targetParameter.type.upperBound)) } is RegularMapping, null -> { - val targetParameter = targetExplicitParameters[targetIndex] - when (bridgeRemappedParameter) { - is MultiFieldValueClassMapping -> { - val valueArguments = List(bridgeRemappedParameter.rootMfvcNode.leavesCount) { - irGet(bridgeExplicitParameters[bridgeIndex++]) - } - val boxCall = bridgeRemappedParameter.rootMfvcNode.makeBoxedExpression( - this@irBlock, bridgeRemappedParameter.typeArguments, valueArguments - ) - putArgument(targetParameter, irCastIfNeeded(boxCall, targetParameter.type.upperBound)) - } - - is RegularMapping, null -> { - val bridgeParameter = bridgeExplicitParameters[bridgeIndex++] - putArgument(targetParameter, irGetOrCast(bridgeParameter, targetParameter)) - } - } - targetIndex++ + val bridgeParameter = bridgeExplicitParameters[bridgeIndex++] + irCall.putArgument(targetParameter, irGetOrCast(bridge, bridgeParameter, targetParameter)) } } - structureIndex++ + targetIndex++ } - require(targetIndex == targetExplicitParameters.size && bridgeIndex == bridgeExplicitParameters.size) { - "Incorrect bridge:\n${bridge.dump()}\n\nfor target\n${target.dump()}" - } - require((targetStructure == null || structureIndex == targetStructure.size)) { - "Invalid structure index $structureIndex for $targetStructure" - } - require((bridgeStructure == null || structureIndex == bridgeStructure.size)) { - "Invalid structure index $structureIndex for $bridgeStructure" - } - }) - }.unwrap(), bridge.returnType.upperBound) + } + structureIndex++ + } + require(targetIndex == targetExplicitParameters.size && bridgeIndex == bridgeExplicitParameters.size) { + "Incorrect bridge:\n${bridge.dump()}\n\nfor target\n${target.dump()}" + } + require((targetStructure == null || structureIndex == targetStructure.size)) { + "Invalid structure index $structureIndex for $targetStructure" + } + require((bridgeStructure == null || structureIndex == bridgeStructure.size)) { + "Invalid structure index $structureIndex for $bridgeStructure" + } + } + + private fun IrBuilderWithScope.irGetOrCast( + bridge: IrSimpleFunction, + bridgeParameter: IrValueParameter, + targetParameter: IrValueParameter + ) = + irGet(bridgeParameter).let { argument -> + if (bridgeParameter == bridge.dispatchReceiverParameter) + argument + else + irCastIfNeeded(argument, targetParameter.type.upperBound) + } private fun IrBuilderWithScope.irCastIfNeeded(expression: IrExpression, to: IrType): IrExpression = if (expression.type == to || to.isAny() || to.isNullableAny()) expression else irImplicitCast(expression, to) diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt index 44d0b0ceebb..c82836a7760 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt @@ -95,6 +95,7 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo val superClassType = superMethod.parentAsClass.defaultType val defaultImplFun = context.cachedDeclarations.getDefaultImplsFunction(superMethod) val classStartOffset = classOverride.parentAsClass.startOffset + val backendContext = context context.createIrBuilder(irFunction.symbol, classStartOffset, classStartOffset).apply { irFunction.body = irBlockBody { +irReturn( @@ -107,18 +108,18 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo irFunction.dispatchReceiverParameter?.let { putValueArgument(0, irGet(it).reinterpretAsDispatchReceiverOfType(superClassType)) } - val lowering = this@InheritedDefaultMethodsOnClassesLowering - val mfvcOrOriginal = lowering.context.inlineClassReplacements.originalFunctionForMethodReplacement[classOverride] + val mfvcOrOriginal = backendContext.inlineClassReplacements.originalFunctionForMethodReplacement[classOverride] ?: classOverride - val bindingNewFunctionToParameterTemplateStructure = lowering.context.multiFieldValueClassReplacements + val bindingNewFunctionToParameterTemplateStructure = backendContext.multiFieldValueClassReplacements .bindingNewFunctionToParameterTemplateStructure val structure = bindingNewFunctionToParameterTemplateStructure[mfvcOrOriginal]?.let { structure -> - val errorMessage = { "Bad parameters structure: $structure" } - require(structure.sumOf { it.valueParameters.size } == classOverride.explicitParametersCount) { errorMessage() } + require(structure.sumOf { it.valueParameters.size } == classOverride.explicitParametersCount) { + "Bad parameters structure: $structure" + } if (defaultImplFun.explicitParametersCount == irFunction.explicitParametersCount) { null } else { - require(structure.size == defaultImplFun.explicitParametersCount) { errorMessage() } + require(structure.size == defaultImplFun.explicitParametersCount) { "Bad parameters structure: $structure" } structure } } @@ -127,7 +128,7 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo } val sourceFullValueParameterList = irFunction.fullValueParameterList if (structure == null) { - sourceFullValueParameterList.forEachIndexed { index, parameter -> + for ((index, parameter) in sourceFullValueParameterList.withIndex()) { putValueArgument(1 + index, irGet(parameter)) } } else { @@ -135,7 +136,7 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo for (i in 1 until structure.size) { when (val remappedParameter = structure[i]) { is MultiFieldValueClassMapping -> { - val valueArguments = (0 until remappedParameter.valueParameters.size).map { + val valueArguments = remappedParameter.valueParameters.indices.map { irGet(sourceFullValueParameterList[flattenedIndex++]) } val boxedExpression = remappedParameter.rootMfvcNode.makeBoxedExpression( diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt index 7405f3d406f..fcba70cd461 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.backend.jvm.lower +import org.jetbrains.kotlin.backend.common.lower.MethodsFromAnyGeneratorForLowerings.Companion.isEquals +import org.jetbrains.kotlin.backend.common.lower.MethodsFromAnyGeneratorForLowerings.Companion.isToString import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irCatch import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase @@ -83,22 +85,22 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV oldSymbol2MfvcNodeInstance[original.symbol] = replacement } - fun makeReplacement(scope: IrBuilderWithScope, expression: IrGetValue): IrExpression? = with(scope) { + fun IrBuilderWithScope.makeReplacement(expression: IrGetValue): IrExpression? { oldValueSymbol2NewValueSymbol[expression.symbol]?.let { return irGet(it.owner) } - val instance = oldSymbol2MfvcNodeInstance[expression.symbol] ?: return@with null + val instance = oldSymbol2MfvcNodeInstance[expression.symbol] ?: return null val res = instance.makeGetterExpression() expression2MfvcNodeInstanceAccessor[res] = MfvcNodeInstanceAccessor.Getter(instance) return res } - private fun separateExpressions(expressions: List): Pair, List> { + private fun splitExpressions(expressions: List): Pair, List> { val repeatable = expressions.takeLastWhile { it.isRepeatableGetter() } return expressions.subList(0, expressions.size - repeatable.size) to repeatable } - fun addReplacement(scope: IrBlockBuilder, expression: IrSetValue, safe: Boolean): IrExpression? = with(scope) { + fun IrBlockBuilder.addReplacement(expression: IrSetValue, safe: Boolean): IrExpression? { oldValueSymbol2NewValueSymbol[expression.symbol]?.let { return irSet(it.owner, expression.value) } - val instance = oldSymbol2MfvcNodeInstance[expression.symbol] ?: return@with null + val instance = oldSymbol2MfvcNodeInstance[expression.symbol] ?: return null val values: List = makeFlattenedExpressionsWithGivenSafety(instance.node, safe, expression.value) val setterExpressions = instance.makeSetterExpressions(values) expression2MfvcNodeInstanceAccessor[setterExpressions] = MfvcNodeInstanceAccessor.Setter(instance, values) @@ -112,7 +114,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV private fun IrBlockBuilder.makeFlattenedExpressionsWithGivenSafety( node: MfvcNode, safe: Boolean, expression: IrExpression ) = if (safe) { - val (forVariables, rest) = separateExpressions(flattenExpression(expression)) + val (forVariables, rest) = splitExpressions(flattenExpression(expression)) val variables = when (node) { is LeafMfvcNode -> forVariables.map { expr -> irTemporary(expr) } is MfvcNodeWithSubnodes -> forVariables.zip(node.leaves) { expr, leaf -> @@ -127,38 +129,38 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV private val IrFieldAccessExpression.field: IrField get() = this.symbol.owner - fun addReplacement(scope: IrBlockBuilder, expression: IrGetField): IrExpression? { + fun IrBlockBuilder.addReplacement(expression: IrGetField): IrExpression? { val property = expression.field.property ?: return null - expression.receiver?.get(property.name)?.let { scope.run { +it }; return it } + expression.receiver?.get(property.name)?.let { +it; return it } val node = replacements.getMfvcPropertyNode(property) ?: return null val typeArguments = makeTypeArgumentsFromField(expression) val instance: ReceiverBasedMfvcNodeInstance = - node.createInstanceFromBox(scope, typeArguments, expression.receiver, AccessType.AlwaysPrivate, ::variablesSaver) + node.createInstanceFromBox(this, typeArguments, expression.receiver, AccessType.AlwaysPrivate, ::variablesSaver) val getterExpression = instance.makeGetterExpression() expression2MfvcNodeInstanceAccessor[getterExpression] = MfvcNodeInstanceAccessor.Getter(instance) - scope.run { +getterExpression } + +getterExpression return getterExpression } - fun addReplacement(scope: IrBlockBuilder, expression: IrSetField, safe: Boolean): IrExpression? { + fun IrBlockBuilder.addReplacement(expression: IrSetField, safe: Boolean): IrExpression? { val property = expression.field.property ?: return null - expression.receiver?.get(property.name)?.let { scope.run { +it }; return it } + expression.receiver?.get(property.name)?.let { +it; return it } val node = replacements.getMfvcPropertyNode(property) ?: return null val typeArguments = makeTypeArgumentsFromField(expression) val instance: ReceiverBasedMfvcNodeInstance = - node.createInstanceFromBox(scope, typeArguments, expression.receiver, AccessType.AlwaysPrivate, ::variablesSaver) - val values: List = scope.makeFlattenedExpressionsWithGivenSafety(node, safe, expression.value) + node.createInstanceFromBox(this, typeArguments, expression.receiver, AccessType.AlwaysPrivate, ::variablesSaver) + val values: List = makeFlattenedExpressionsWithGivenSafety(node, safe, expression.value) val setterExpressions = instance.makeSetterExpressions(values) expression2MfvcNodeInstanceAccessor[setterExpressions] = MfvcNodeInstanceAccessor.Setter(instance, values) - scope.run { +setterExpressions } + +setterExpressions return setterExpressions } - fun addReplacement(scope: IrBlockBuilder, expression: IrCall): IrExpression? { + fun IrBlockBuilder.addReplacement(expression: IrCall): IrExpression? { val function = expression.symbol.owner val property = function.property?.takeIf { function.isGetter } ?: return null val dispatchReceiver = expression.dispatchReceiver - dispatchReceiver?.get(property.name)?.let { scope.run { +it }; return it } + dispatchReceiver?.get(property.name)?.let { +it; return it } val node = replacements.getMfvcPropertyNode(property) ?: return null val typeArguments = makeTypeArgumentsFromFunction(expression) // Optimization: pure function access to leaf can be replaced with field access if the field itself is accessible @@ -168,18 +170,13 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV else -> getOptimizedPublicAccess(dispatchReceiver.type.erasedUpperBound) } val instance: ReceiverBasedMfvcNodeInstance = - node.createInstanceFromBox(scope, typeArguments, dispatchReceiver, accessType, ::variablesSaver) + node.createInstanceFromBox(this, typeArguments, dispatchReceiver, accessType, ::variablesSaver) val getterExpression = instance.makeGetterExpression() expression2MfvcNodeInstanceAccessor[getterExpression] = MfvcNodeInstanceAccessor.Getter(instance) - scope.run { +getterExpression } + +getterExpression return getterExpression } - private val IrField.property - get() = correspondingPropertySymbol?.owner - private val IrSimpleFunction.property - get() = correspondingPropertySymbol?.owner - private fun makeTypeArgumentsFromField(expression: IrFieldAccessExpression) = buildMap { val field = expression.symbol.owner putAll(makeTypeArgumentsFromType(field.type as IrSimpleType)) @@ -243,6 +240,11 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV } } + private val IrField.property + get() = correspondingPropertySymbol?.owner + private val IrSimpleFunction.property + get() = correspondingPropertySymbol?.owner + private val valueDeclarationsRemapper = ValueDeclarationRemapper() override val replacements @@ -273,8 +275,8 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV } else { memberDeclaration.accept(this, null) null - }).apply { - for (replacingDeclaration in this ?: listOf(memberDeclaration)) { + }).also { declarations -> + for (replacingDeclaration in declarations ?: listOf(memberDeclaration)) { when (replacingDeclaration) { is IrFunction -> replacingDeclaration.body = replacingDeclaration.body?.makeBodyWithAddedVariables( context, variablesToAdd[replacingDeclaration] ?: emptySet(), replacingDeclaration.symbol @@ -301,7 +303,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV val oldBackingFields = properties.mapNotNull { property -> property.backingField?.let { property to it } }.toMap() val propertiesReplacement = collectRegularClassMfvcPropertiesReplacement(properties) // resets backing fields - val fieldsToRemove = LinkedHashSet(propertiesReplacement.keys.mapNotNull { oldBackingFields[it] }) + val fieldsToRemove = propertiesReplacement.keys.mapNotNull { oldBackingFields[it] }.toSet() val newDeclarations = makeNewDeclarationsForRegularClass(fieldsToRemove, propertiesReplacement, irClass) irClass.declarations.replaceAll(newDeclarations) @@ -316,15 +318,15 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV } private fun makeNewDeclarationsForRegularClass( - fieldsToRemove: LinkedHashSet, - propertiesReplacement: LinkedHashMap, + fieldsToRemove: Set, + propertiesReplacement: Map, irClass: IrClass, ) = buildList { for (element in irClass.declarations) { when (element) { !is IrField, !in fieldsToRemove -> add(element) else -> { - val replacement = propertiesReplacement[element.correspondingPropertySymbol!!.owner]!! + val replacement = propertiesReplacement[element.property!!]!! addAll(replacement.fields!!) element.initializer?.let { initializer -> add(makeInitializerReplacement(irClass, element, initializer)) } } @@ -360,7 +362,9 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV } override fun transformSecondaryConstructorFlat(constructor: IrConstructor, replacement: IrSimpleFunction): List { - replacement.valueParameters.forEach { it.transformChildrenVoid() } + for (param in replacement.valueParameters) { + param.transformChildrenVoid() + } allScopes.push(createScope(replacement)) replacement.body = context.createIrBuilder(replacement.symbol).irBlockBody { @@ -440,10 +444,9 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV valueParameters = replacement.valueParameters.drop(offset).map { it.copyTo(this, type = it.type.substitute(substitutionMap), index = it.index - offset) } - val bridgeStructure = - replacementStructure.toMutableList().apply { - set(0, RegularMapping(dispatchReceiverParameter!!)) - } + val bridgeStructure = replacementStructure.toMutableList().apply { + set(0, RegularMapping(dispatchReceiverParameter!!)) + } replacements.bindingNewFunctionToParameterTemplateStructure[this] = bridgeStructure } else { copyParameterDeclarationsFrom(source) @@ -625,7 +628,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV mfvc.declarations.removeIf { it is IrConstructor && it.isPrimary } mfvc.declarations += listOf(newPrimaryConstructor, primaryConstructorImpl) - val initializersStatements = mfvc.declarations.filterIsInstance() + val initializersBlocks = mfvc.declarations.filterIsInstance() val typeArguments = makeTypeParameterSubstitutionMap(mfvc, primaryConstructorImpl) primaryConstructorImpl.body = context.createIrBuilder(primaryConstructorImpl.symbol).irBlockBody { val mfvcNodeInstance = @@ -634,7 +637,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV oldPrimaryConstructor.constructedClass.thisReceiver!!, mfvcNodeInstance ) - for (initializer in initializersStatements) { + for (initializer in initializersBlocks) { +irBlock { for (stmt in initializer.body.statements) { +stmt.patchDeclarationParents(primaryConstructorImpl) // transformation is done later @@ -658,9 +661,8 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV function is IrConstructor && function.isPrimary && function.constructedClass.isMultiFieldValueClass && currentScope.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER -> { context.createIrBuilder(currentScope.symbol).irBlock { - val instance: MfvcNodeInstance val rootNode = replacements.getRootMfvcNode(function.constructedClass)!! - instance = rootNode.createInstanceFromValueDeclarationsAndBoxType( + val instance = rootNode.createInstanceFromValueDeclarationsAndBoxType( this, function.constructedClassType as IrSimpleType, Name.identifier("constructor_tmp"), ::variablesSaver ) flattenExpressionTo(expression, instance) @@ -674,33 +676,37 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV buildReplacement(function, expression, replacement) } - else -> - when (val newConstructor = - (function as? IrConstructor)?.let { replacements.getReplacementForRegularClassConstructor(it) }) { - null -> return super.visitFunctionAccess(expression) - else -> context.createIrBuilder(currentScope.symbol).irBlock { - buildReplacement(function, expression, newConstructor) - } + else -> { + val newConstructor = (function as? IrConstructor) + ?.let { replacements.getReplacementForRegularClassConstructor(it) } + ?: return super.visitFunctionAccess(expression) + context.createIrBuilder(currentScope.symbol).irBlock { + buildReplacement(function, expression, newConstructor) } + } } } override fun visitCall(expression: IrCall): IrExpression { val callee = expression.symbol.owner - val property = callee.correspondingPropertySymbol?.owner + val property = callee.property if ( property != null && callee.extensionReceiverParameter == null && + callee.contextReceiverParametersCount == 0 && callee.isGetter && (expression.type.needsMfvcFlattening() || expression.dispatchReceiver?.type?.needsMfvcFlattening() == true) ) { require(callee.valueParameters.isEmpty()) { "Unexpected getter:\n${callee.dump()}" } expression.dispatchReceiver = expression.dispatchReceiver?.transform(this, null) return context.createIrBuilder(getCurrentScopeSymbol()).irBlock { - valueDeclarationsRemapper.addReplacement(this, expression) ?: return expression + with(valueDeclarationsRemapper) { + addReplacement(expression) ?: return expression + } } } if (expression.isSpecializedMFVCEqEq) { + val backendContext = context return context.createIrBuilder(getCurrentScopeSymbol()).irBlock { val leftArgument = expression.getValueArgument(0)!! val rightArgument = expression.getValueArgument(1)!! @@ -731,7 +737,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV } } else { // left one is unboxed, right is not - val equals = leftClass.functions.single { it.name.asString() == "equals" && it.overriddenSymbols.isNotEmpty() } + val equals = leftClass.functions.single { it.isEquals(backendContext) } +irCall(equals).apply { copyTypeArgumentsFrom(expression) dispatchReceiver = leftArgument @@ -805,9 +811,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV val argument = expression.arguments[i] if (argument.type.needsMfvcFlattening()) { expression.arguments[i] = context.createIrBuilder(getCurrentScopeSymbol()).run { - val toString = argument.type.erasedUpperBound.functions.single { - it.name.asString() == "toString" && it.valueParameters.isEmpty() - } + val toString = argument.type.erasedUpperBound.functions.single { it.isToString() } require(toString.typeParameters.isEmpty()) { "Bad toString: ${toString.render()}" } irCall(toString).apply { dispatchReceiver = argument @@ -910,31 +914,38 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV // so it is enough to check for eqeq. private val IrCall.isSpecializedMFVCEqEq: Boolean get() = symbol == context.irBuiltIns.eqeqSymbol && - listOf(getValueArgument(0)!!, getValueArgument(1)!!) - .any { argument -> argument.type.erasedUpperBound.takeIf { it.isMultiFieldValueClass } != null } + listOf(getValueArgument(0), getValueArgument(1)) + .any { it!!.type.erasedUpperBound.isMultiFieldValueClass } override fun visitGetField(expression: IrGetField): IrExpression { expression.receiver = expression.receiver?.transform(this, null) - return context.createIrBuilder(expression.symbol).irBlock { - valueDeclarationsRemapper.addReplacement(this, expression) ?: return expression + with(valueDeclarationsRemapper) { + return context.createIrBuilder(expression.symbol).irBlock { + addReplacement(expression) ?: return expression + } } } override fun visitSetField(expression: IrSetField): IrExpression { expression.receiver = expression.receiver?.transform(this, null) - return context.createIrBuilder(getCurrentScopeSymbol()).irBlock { - valueDeclarationsRemapper.addReplacement(this, expression, safe = expression.origin != UNSAFE_MFVC_SET_ORIGIN) - ?: return expression.also { it.value = it.value.transform(this@JvmMultiFieldValueClassLowering, null) } + with(valueDeclarationsRemapper) { + return context.createIrBuilder(getCurrentScopeSymbol()).irBlock { + addReplacement(expression, safe = expression.origin != UNSAFE_MFVC_SET_ORIGIN) + ?: return expression.also { it.value = it.value.transform(this@JvmMultiFieldValueClassLowering, null) } + } } } - override fun visitGetValue(expression: IrGetValue): IrExpression = with(context.createIrBuilder(getCurrentScopeSymbol())) b@{ - valueDeclarationsRemapper.makeReplacement(this@b, expression) ?: super.visitGetValue(expression) - } + override fun visitGetValue(expression: IrGetValue): IrExpression = + with(valueDeclarationsRemapper) { + context.createIrBuilder(getCurrentScopeSymbol()).makeReplacement(expression) ?: super.visitGetValue(expression) + } - override fun visitSetValue(expression: IrSetValue): IrExpression = context.createIrBuilder(getCurrentScopeSymbol()).irBlock b@{ - valueDeclarationsRemapper.addReplacement(this@b, expression, safe = expression.origin != UNSAFE_MFVC_SET_ORIGIN) - ?: return super.visitSetValue(expression) + override fun visitSetValue(expression: IrSetValue): IrExpression = context.createIrBuilder(getCurrentScopeSymbol()).irBlock { + with(valueDeclarationsRemapper) { + addReplacement(expression, safe = expression.origin != UNSAFE_MFVC_SET_ORIGIN) + ?: return super.visitSetValue(expression) + } } override fun visitVariable(declaration: IrVariable): IrStatement { @@ -1006,14 +1017,14 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV branch.condition = branch.condition.transform(lowering, null) branch.result = irBlock { flattenExpressionTo(branch.result, instance) - }.unwrap() + }.unwrapBlock() } +expression return } if (expression is IrTry) { - expression.tryResult = irBlock { flattenExpressionTo(expression.tryResult, instance) }.unwrap() - expression.catches.replaceAll { irCatch(it.catchParameter, irBlock { flattenExpressionTo(it.result, instance) }.unwrap()) } + expression.tryResult = irBlock { flattenExpressionTo(expression.tryResult, instance) }.unwrapBlock() + expression.catches.replaceAll { irCatch(it.catchParameter, irBlock { flattenExpressionTo(it.result, instance) }.unwrapBlock()) } expression.finallyExpression = expression.finallyExpression?.transform(lowering, null) +expression return @@ -1112,19 +1123,21 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV } private fun handleStatementContainer(expression: IrStatementContainer, resultIsUsed: Boolean) { - expression.statements.dropLast(1).forEach { it.accept(this, false) } + for (statement in expression.statements.dropLast(1)) { + statement.accept(this, false) + } expression.statements.lastOrNull()?.accept(this, resultIsUsed) - val indexesToRemove = mutableListOf() - for (i in 0 until (expression.statements.size - if (resultIsUsed) 1 else 0)) { - val call = getFunctionCallOrNull(expression.statements[i]) ?: continue + val statementsToRemove = mutableSetOf() + for (statement in expression.statements.dropLast(if (resultIsUsed) 1 else 0)) { + val call = getFunctionCallOrNull(statement) ?: continue val node = replacements.getRootMfvcNode(call.type.erasedUpperBound) ?: continue - if (node.boxMethod == call.symbol.owner && List(call.valueArgumentsCount) { call.getValueArgument(it) }.all { it.isRepeatableGetter() }) { - indexesToRemove.add(i) + if (node.boxMethod == call.symbol.owner && + List(call.valueArgumentsCount) { call.getValueArgument(it) }.all { it.isRepeatableGetter() } + ) { + statementsToRemove.add(statement) } } - if (indexesToRemove.isNotEmpty()) { - expression.statements.replaceAll(expression.statements.filterIndexed { index, _ -> index !in indexesToRemove }) - } + expression.statements.removeIf { it in statementsToRemove } } }, false) } @@ -1255,16 +1268,16 @@ fun IrBody.makeBodyWithAddedVariables( val variablesSet = variables.toSet() val statementsWithoutUsages = container.statements.takeWhile { !it.containsUsagesOf(variablesSet) } container.statements.replaceAll(container.statements.drop(statementsWithoutUsages.size)) - val values = sequence { + val values = buildList { for ((variable, statement) in variables.asSequence() zip getFlattenedStatements(container)) { when { variable.initializer != null -> break statement !is IrSetValue -> break statement.symbol.owner != variable -> break - else -> yield(statement.value) + else -> add(statement.value) } } - }.toList() + } for ((variable, value) in variables zip values) { variable.initializer = value diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt index bef2254aa76..72ecec9d46a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt @@ -155,10 +155,12 @@ val IrClass.inlineClassFieldName: Name val IrFunction.isInlineClassFieldGetter: Boolean get() = (parent as? IrClass)?.isSingleFieldValueClass == true && this is IrSimpleFunction && extensionReceiverParameter == null && + contextReceiverParametersCount == 0 && !isStatic && correspondingPropertySymbol?.let { it.owner.getter == this && it.owner.name == parentAsClass.inlineClassFieldName } == true val IrFunction.isMultiFieldValueClassFieldGetter: Boolean get() = (parent as? IrClass)?.isMultiFieldValueClass == true && this is IrSimpleFunction && extensionReceiverParameter == null && + contextReceiverParametersCount == 0 && !isStatic && correspondingPropertySymbol?.let { val multiFieldValueClassRepresentation = parentAsClass.multiFieldValueClassRepresentation ?: error("Multi-field value class must have multiFieldValueClassRepresentation: ${parentAsClass.render()}") diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt index 51559f23ae8..735a22e896b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt @@ -224,7 +224,8 @@ class MemoizedMultiFieldValueClassReplacements( function.isStaticValueClassReplacement || function.origin == IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER && function.isAccessor || function.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD || - function.origin.isSynthetic && function.origin != IrDeclarationOrigin.SYNTHETIC_GENERATED_SAM_IMPLEMENTATION -> null + function.origin.isSynthetic && function.origin != IrDeclarationOrigin.SYNTHETIC_GENERATED_SAM_IMPLEMENTATION || + function.isMultiFieldValueClassFieldGetter -> null function.parent.safeAs()?.isMultiFieldValueClass == true -> when { function.isRemoveAtSpecialBuiltinStub() -> @@ -279,6 +280,7 @@ class MemoizedMultiFieldValueClassReplacements( when { parent !is IrClass -> null property.isFakeOverride -> null + property.getter.let { it != null && (it.contextReceiverParametersCount > 0 || it.extensionReceiverParameter != null) } -> null useRootNode(parent, property) -> null property.run { backingField?.type ?: getter?.returnType }?.needsMfvcFlattening() != true -> null else -> createIntermediateNodeForMfvcPropertyOfRegularClass(parent, context, property) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt index 7cf615d4c3a..a8912f40b58 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt @@ -79,16 +79,6 @@ fun makeTypeArgumentsFromType(type: IrSimpleType): TypeArguments { } -private fun MfvcNode.createInstanceFromBoxTypeImpl( - scope: Scope, - boxType: IrSimpleType, - fieldValues: List, - gen: (Scope, MfvcNode, TypeArguments, List) -> Instance -): Instance { - val typeArguments = makeTypeArgumentsFromType(boxType) - return gen(scope, this, typeArguments, fieldValues) -} - sealed interface NameableMfvcNode : MfvcNode { val namedNodeImpl: NameableMfvcNodeImpl } @@ -268,12 +258,6 @@ private fun requireSameClasses(vararg classes: IrClass?) { } } -private fun requireSameTypes(vararg types: List) { - require(types.asList().zipWithNext { a, b -> a == b }.all { it }) { - "Found different types: ${types.joinToString("\n") { list -> list.map { it.render() }.toString() }}" - } -} - private fun requireSameSizes(vararg sizes: Int) { require(sizes.asList().zipWithNext { a, b -> a == b }.all { it }) { "Found different sizes: ${sizes.joinToString()}" diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeFabric.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeFactory.kt similarity index 97% rename from compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeFabric.kt rename to compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeFactory.kt index edd15272700..0cf287b84b7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeFabric.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeFactory.kt @@ -231,7 +231,8 @@ fun createIntermediateMfvcNode( val unboxMethod = if (useOldGetter) oldGetter!! else makeUnboxMethod( context, fullMethodName, type, parent, overriddenNode, static, defaultMethodsImplementationSourceNode, oldGetter, modality ) { receiver -> - val valueArguments = subnodes.flatMap { it.fields!! }.map { field -> irGetField(if (field.isStatic) null else irGet(receiver!!), field) } + val valueArguments = subnodes.flatMap { it.fields!! } + .map { field -> irGetField(if (field.isStatic) null else irGet(receiver!!), field) } rootNode.makeBoxedExpression(this, typeArguments, valueArguments) } @@ -244,7 +245,7 @@ fun collectPropertiesAfterLowering(irClass: IrClass) = LinkedHashSet for (element in irClass.declarations) { if (element is IrField) { element.correspondingPropertySymbol?.owner?.let { add(it) } - } else if (element is IrSimpleFunction) { + } else if (element is IrSimpleFunction && element.extensionReceiverParameter == null && element.contextReceiverParametersCount == 0) { element.correspondingPropertySymbol?.owner?.let { add(it) } } } @@ -387,9 +388,7 @@ private fun makeMfvcPrimaryConstructor( origin = JvmLoweredDeclarationOrigin.SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER returnType = oldPrimaryConstructor.returnType }.apply { - require(oldPrimaryConstructor.typeParameters.isEmpty()) { - "Constructors do not support type parameters yet" - } + require(oldPrimaryConstructor.typeParameters.isEmpty()) { "Constructors do not support type parameters yet" } this.parent = mfvc val parameters = leaves.map { addValueParameter(it.fullFieldName, it.type) } val irConstructor = this@apply diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeInstance.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeInstance.kt index 76aaf278fc4..07f2d7c1dd2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeInstance.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNodeInstance.kt @@ -188,9 +188,9 @@ class ReceiverBasedMfvcNodeInstance( override fun makeGetterExpression(): IrExpression = with(scope) { when { node is LeafMfvcNode && canUsePrivateAccessFor(node) && fields != null -> irGetField(makeReceiverCopy(), fields.single()) - node is IntermediateMfvcNode && accessType == AccessType.AlwaysPrivate && fields != null -> node.makeBoxedExpression( - this, typeArguments, fields.map { irGetField(makeReceiverCopy(), it) } - ) + node is IntermediateMfvcNode && accessType == AccessType.AlwaysPrivate && fields != null -> + node.makeBoxedExpression(this, typeArguments, fields.map { irGetField(makeReceiverCopy(), it) }) + unboxMethod != null -> irCall(unboxMethod).apply { val dispatchReceiverParameter = unboxMethod.dispatchReceiverParameter if (dispatchReceiverParameter != null) { @@ -225,7 +225,7 @@ class ReceiverBasedMfvcNodeInstance( val MfvcNodeInstance.size: Int get() = node.leavesCount -fun IrContainerExpression.unwrap(): IrExpression = statements.singleOrNull() as? IrExpression ?: this +fun IrContainerExpression.unwrapBlock(): IrExpression = statements.singleOrNull() as? IrExpression ?: this /** * Creates a variable and doesn't add it to a container. It saves the variable with given saveVariable. @@ -276,4 +276,4 @@ fun IrStatementsBuilder.savableStandaloneVariableWithSetter( saveVariable: (IrVariable) -> Unit, ) = savableStandaloneVariable(expression.type, name, isMutable, origin, isTemporary, saveVariable).also { +irSet(it, expression) -} \ No newline at end of file +} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt index d8b3ed2bc80..a4a995f224f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt @@ -244,7 +244,8 @@ fun IrProperty.needsAccessor(accessor: IrSimpleFunction): Boolean = when { // Properties in annotation classes become abstract methods named after the property. (parent as? IrClass)?.kind == ClassKind.ANNOTATION_CLASS -> true // Multi-field value class getters must always be added. Getters for properties of MFVC itself follow general rules. - accessor.isGetter && !accessor.parent.let { it is IrClass && it.isMultiFieldValueClass } && accessor.returnType.needsMfvcFlattening() -> true + accessor.isGetter && accessor.contextReceiverParametersCount == 0 && accessor.extensionReceiverParameter == null && + !accessor.parent.let { it is IrClass && it.isMultiFieldValueClass } && accessor.returnType.needsMfvcFlattening() -> true // @JvmField properties have no getters/setters resolveFakeOverride()?.backingField?.hasAnnotation(JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME) == true -> false // We do not produce default accessors for private fields diff --git a/compiler/testData/codegen/box/valueClasses/classFlattening.kt b/compiler/testData/codegen/box/valueClasses/classFlattening.kt index 5d9b6c188f8..4d7a6aa0d15 100644 --- a/compiler/testData/codegen/box/valueClasses/classFlattening.kt +++ b/compiler/testData/codegen/box/valueClasses/classFlattening.kt @@ -1,7 +1,8 @@ +// IGNORE_BACKEND_FIR: JVM_IR // WITH_STDLIB // TARGET_BACKEND: JVM_IR // WORKS_WHEN_VALUE_CLASS -// LANGUAGE: +ValueClasses +// LANGUAGE: +ValueClasses +ContextReceivers // CHECK_BYTECODE_LISTING @JvmInline @@ -10,21 +11,148 @@ value class IC(val x: UInt) fun ic(x: IC) = x.x @JvmInline -value class SimpleMFVC(val x: UInt, val y: IC, val z: String) +value class SimpleMfvc(val x: UInt, val y: IC, val z: String) { + companion object { + val SimpleMfvc.a1: SimpleMfvc + get() = this -fun smfvc(ic: IC, x: SimpleMFVC, ic1: UInt) = ic(ic) + x.x + ic(x.y) + ic1 + @JvmStatic + val SimpleMfvc.b1: SimpleMfvc + get() = this + + context(b@SimpleMfvc) + val a2: SimpleMfvc + get() = this@b + + context(b@SimpleMfvc) + @JvmStatic + val b2: SimpleMfvc + get() = this@b + + + private val SimpleMfvc.private1: SimpleMfvc + get() = this + + @JvmStatic + private val SimpleMfvc.private2: SimpleMfvc + get() = this + + context(b@SimpleMfvc) + private val private3: SimpleMfvc + get() = this@b + + context(b@SimpleMfvc) + @JvmStatic + private val private4: SimpleMfvc + get() = this@b + } + + val SimpleMfvc.a3: SimpleMfvc + get() = this + + context(SimpleMfvc) + val b3: SimpleMfvc + get() = this@SimpleMfvc + + + private val SimpleMfvc.private1: SimpleMfvc + get() = this@SimpleMfvc + context(SimpleMfvc) + private val private2: SimpleMfvc + get() = this@SimpleMfvc +} + +fun smfvc(ic: IC, x: SimpleMfvc, ic1: UInt) = ic(ic) + x.x + ic(x.y) + ic1 @JvmInline -value class GreaterMFVC(val x: SimpleMFVC, val y: IC, val z: SimpleMFVC) +value class GreaterMfvc(val x: SimpleMfvc, val y: IC, val z: SimpleMfvc) -fun gmfvc(ic: IC, x: GreaterMFVC, ic1: UInt) = smfvc(ic, x.x, 0U) + ic(x.y) + smfvc(IC(0U), x.z, ic1) +fun gmfvc(ic: IC, x: GreaterMfvc, ic1: UInt) = smfvc(ic, x.x, 0U) + ic(x.y) + smfvc(IC(0U), x.z, ic1) + +class Extensions { + val SimpleMfvc.x1: SimpleMfvc + get() = this + private val SimpleMfvc.private_: SimpleMfvc + get() = this + + companion object { + val SimpleMfvc.y1: SimpleMfvc + get() = this + + @JvmStatic + val SimpleMfvc.z1: SimpleMfvc + get() = this + + private val SimpleMfvc.private1: SimpleMfvc + get() = this + + @JvmStatic + private val SimpleMfvc.private2: SimpleMfvc + get() = this + } +} + +class Contexts { + context(b@SimpleMfvc) + val x1: SimpleMfvc + get() = this@b + context(b@SimpleMfvc) + private val private_: SimpleMfvc + get() = this@b + + companion object { + context(b@SimpleMfvc) + val y1: SimpleMfvc + get() = this@b + + context(b@SimpleMfvc) + @JvmStatic + val z1: SimpleMfvc + get() = this@b + + context(b@SimpleMfvc) + private val private1: SimpleMfvc + get() = this@b + + context(b@SimpleMfvc) + @JvmStatic + private val private2: SimpleMfvc + get() = this@b + } +} + +fun idUnboxed(x: SimpleMfvc) = x +fun idBoxed(x: SimpleMfvc?) = x!! fun box(): String { val o1 = IC(2U) require(ic(o1) == 2U) - val o2 = SimpleMFVC(1U, o1, "3") + val o2 = SimpleMfvc(1U, o1, "3") + val o2_ = SimpleMfvc(1U, o1, "-3") require(smfvc(IC(4U), o2, 5U) == 12U) - val o3 = GreaterMFVC(o2, IC(6U), SimpleMFVC(7U, IC(8U), "9")) + val o3 = GreaterMfvc(o2, IC(6U), SimpleMfvc(7U, IC(8U), "9")) require(gmfvc(IC(10U), o3, 11U) == 45U) + with(Extensions()) { + require(o2.x1 == o2) + } + with(Extensions.Companion) { + require(o2.y1 == o2) + require(o2.z1 == o2) + } + with(o2) { + require(Contexts().x1 == o2) + require(Contexts.y1 == o2) + require(Contexts.z1 == o2) + require(o2_.a3 == o2_) + require(o2_.b3 == o2_) + require(SimpleMfvc.a2 == o2) + require(SimpleMfvc.b2 == o2) + } + with(SimpleMfvc.Companion) { + require(o2_.a1 == o2_) + require(o2_.b1 == o2_) + } + + require(idUnboxed(idBoxed(idUnboxed(o2) /*boxing*/) /*unbox*/) == o2) return "OK" -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/valueClasses/classFlattening.txt b/compiler/testData/codegen/box/valueClasses/classFlattening.txt index fd53ac61834..2b0613d1bc3 100644 --- a/compiler/testData/codegen/box/valueClasses/classFlattening.txt +++ b/compiler/testData/codegen/box/valueClasses/classFlattening.txt @@ -4,12 +4,73 @@ public final class ClassFlatteningKt { public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String public final static method gmfvc-Ket90g4(p0: int, p1: int, p2: int, @org.jetbrains.annotations.NotNull p3: java.lang.String, p4: int, p5: int, p6: int, @org.jetbrains.annotations.NotNull p7: java.lang.String, p8: int): int public final static method ic-K5cTq2M(p0: int): int + public final static @org.jetbrains.annotations.NotNull method idBoxed(@org.jetbrains.annotations.Nullable p0: SimpleMfvc): SimpleMfvc + public final static @org.jetbrains.annotations.NotNull method idUnboxed-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc public final static method smfvc-Ket90g4(p0: int, p1: int, p2: int, @org.jetbrains.annotations.NotNull p3: java.lang.String, p4: int): int + public final inner class Contexts$Companion + public final inner class Extensions$Companion + public final inner class SimpleMfvc$Companion +} + +@kotlin.Metadata +public final class Contexts$Companion { + // source: 'classFlattening.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$getPrivate2-sUp7gFk(p0: Contexts$Companion, p1: int, p2: int, p3: java.lang.String): SimpleMfvc + private final method getPrivate1-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private synthetic deprecated static @kotlin.jvm.JvmStatic method getPrivate2$annotations(): void + private final method getPrivate2-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + public final @org.jetbrains.annotations.NotNull method getY1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public synthetic deprecated static @kotlin.jvm.JvmStatic method getZ1$annotations(): void + public final @org.jetbrains.annotations.NotNull method getZ1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final inner class Contexts$Companion +} + +@kotlin.Metadata +public final class Contexts { + // source: 'classFlattening.kt' + public final static @org.jetbrains.annotations.NotNull field Companion: Contexts$Companion + static method (): void + public method (): void + private final static method getPrivate2-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private final method getPrivate_-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + public final @org.jetbrains.annotations.NotNull method getX1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final static @org.jetbrains.annotations.NotNull method getZ1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final inner class Contexts$Companion +} + +@kotlin.Metadata +public final class Extensions$Companion { + // source: 'classFlattening.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$getPrivate2-sUp7gFk(p0: Extensions$Companion, p1: int, p2: int, p3: java.lang.String): SimpleMfvc + private final method getPrivate1-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private synthetic deprecated static @kotlin.jvm.JvmStatic method getPrivate2$annotations(p0: SimpleMfvc): void + private final method getPrivate2-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + public final @org.jetbrains.annotations.NotNull method getY1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public synthetic deprecated static @kotlin.jvm.JvmStatic method getZ1$annotations(p0: SimpleMfvc): void + public final @org.jetbrains.annotations.NotNull method getZ1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final inner class Extensions$Companion +} + +@kotlin.Metadata +public final class Extensions { + // source: 'classFlattening.kt' + public final static @org.jetbrains.annotations.NotNull field Companion: Extensions$Companion + static method (): void + public method (): void + private final static method getPrivate2-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private final method getPrivate_-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + public final @org.jetbrains.annotations.NotNull method getX1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final static @org.jetbrains.annotations.NotNull method getZ1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final inner class Extensions$Companion } @kotlin.jvm.JvmInline @kotlin.Metadata -public final class GreaterMFVC { +public final class GreaterMfvc { // source: 'classFlattening.kt' private final field field-0-0: int private final field field-0-1: int @@ -19,24 +80,24 @@ public final class GreaterMFVC { private final field field-2-1: int private final @org.jetbrains.annotations.NotNull field field-2-2: java.lang.String private synthetic method (p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: int, p6: java.lang.String): void - public synthetic final static method box-impl(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: int, p6: java.lang.String): GreaterMFVC + public synthetic final static method box-impl(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: int, p6: java.lang.String): GreaterMfvc public final static method constructor-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String): 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.String, p3: int, p4: int, p5: int, p6: java.lang.String, p7: java.lang.Object): boolean public final static method equals-impl0(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String, p10: int, p11: int, p12: int, p13: java.lang.String): boolean - public final static @org.jetbrains.annotations.NotNull method getX-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String): SimpleMFVC - public final static method getY-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String): int - public final static @org.jetbrains.annotations.NotNull method getZ-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String): SimpleMFVC + public final @org.jetbrains.annotations.NotNull method getX(): SimpleMfvc + public final method getY-fhib4bs(): int + public final @org.jetbrains.annotations.NotNull method getZ(): SimpleMfvc public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: int, p6: java.lang.String): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String public static method toString-impl(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: int, p6: java.lang.String): java.lang.String - public synthetic final method unbox-impl-0(): SimpleMFVC + public synthetic final method unbox-impl-0(): SimpleMfvc public synthetic final method unbox-impl-0-0(): int public synthetic final method unbox-impl-0-1(): int public synthetic final method unbox-impl-0-2(): java.lang.String public synthetic final method unbox-impl-1(): int - public synthetic final method unbox-impl-2(): SimpleMFVC + public synthetic final method unbox-impl-2(): SimpleMfvc public synthetic final method unbox-impl-2-0(): int public synthetic final method unbox-impl-2-1(): int public synthetic final method unbox-impl-2-2(): java.lang.String @@ -61,22 +122,54 @@ public final class IC { public synthetic final method unbox-impl(): int } +@kotlin.Metadata +public final class SimpleMfvc$Companion { + // source: 'classFlattening.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic final static method access$getPrivate2-sUp7gFk(p0: SimpleMfvc$Companion, p1: int, p2: int, p3: java.lang.String): SimpleMfvc + public synthetic final static method access$getPrivate4-sUp7gFk(p0: SimpleMfvc$Companion, p1: int, p2: int, p3: java.lang.String): SimpleMfvc + public final @org.jetbrains.annotations.NotNull method getA1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final @org.jetbrains.annotations.NotNull method getA2-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public synthetic deprecated static @kotlin.jvm.JvmStatic method getB1$annotations(p0: SimpleMfvc): void + public final @org.jetbrains.annotations.NotNull method getB1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public synthetic deprecated static @kotlin.jvm.JvmStatic method getB2$annotations(): void + public final @org.jetbrains.annotations.NotNull method getB2-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + private final method getPrivate1-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private synthetic deprecated static @kotlin.jvm.JvmStatic method getPrivate2$annotations(p0: SimpleMfvc): void + private final method getPrivate2-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private final method getPrivate3-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private synthetic deprecated static @kotlin.jvm.JvmStatic method getPrivate4$annotations(): void + private final method getPrivate4-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + public final inner class SimpleMfvc$Companion +} + @kotlin.jvm.JvmInline @kotlin.Metadata -public final class SimpleMFVC { +public final class SimpleMfvc { // source: 'classFlattening.kt' + public final static @org.jetbrains.annotations.NotNull field Companion: SimpleMfvc$Companion private final field field-0: int private final field field-1: int private final @org.jetbrains.annotations.NotNull field field-2: java.lang.String + static method (): void private synthetic method (p0: int, p1: int, p2: java.lang.String): void - public synthetic final static method box-impl(p0: int, p1: int, p2: java.lang.String): SimpleMFVC + public synthetic final static method box-impl(p0: int, p1: int, p2: java.lang.String): SimpleMfvc public final static method constructor-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): 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.String, p3: java.lang.Object): boolean public final static method equals-impl0(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: java.lang.String): boolean - public final static method getX-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): int - public final static method getY-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): int - public final static @org.jetbrains.annotations.NotNull method getZ-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): java.lang.String + public final static @org.jetbrains.annotations.NotNull method getA3-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String, p3: int, p4: int, @org.jetbrains.annotations.NotNull p5: java.lang.String): SimpleMfvc + public final static @org.jetbrains.annotations.NotNull method getB1-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final static @org.jetbrains.annotations.NotNull method getB2-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): SimpleMfvc + public final static @org.jetbrains.annotations.NotNull method getB3-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String, p3: int, p4: int, @org.jetbrains.annotations.NotNull p5: java.lang.String): SimpleMfvc + private final static method getPrivate1-sUp7gFk(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: java.lang.String): SimpleMfvc + private final static method getPrivate2-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + private final static method getPrivate2-sUp7gFk(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: java.lang.String): SimpleMfvc + private final static method getPrivate4-sUp7gFk(p0: int, p1: int, p2: java.lang.String): SimpleMfvc + public final method getX-pVg5ArA(): int + public final method getY-fhib4bs(): int + public final @org.jetbrains.annotations.NotNull method getZ(): java.lang.String public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: java.lang.String): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -84,4 +177,5 @@ public final class SimpleMFVC { public synthetic final method unbox-impl-0(): int public synthetic final method unbox-impl-1(): int public synthetic final method unbox-impl-2(): java.lang.String + public final inner class SimpleMfvc$Companion } diff --git a/compiler/testData/codegen/box/valueClasses/complex.kt b/compiler/testData/codegen/box/valueClasses/complex.kt index f5d227cb586..68366a89412 100644 --- a/compiler/testData/codegen/box/valueClasses/complex.kt +++ b/compiler/testData/codegen/box/valueClasses/complex.kt @@ -21,7 +21,7 @@ value class D(val x: C) { constructor(x: Int, y: UInt, z: Int) : this(C(x, B(y), z.toString())) init { - println(x.x) + supply(x.x) } } @@ -46,18 +46,18 @@ interface Base3 { value class R(val x: Int, val y: UInt, override val z: E, val t: A) : Base1, Base3 fun > f(r: R) { - println(r) - println(r.x) - println(r.y) - println(r.z) - println(r.t) - println(r.t.x) - println(r.z.x) - println(r.z.x.x) - println(r.z.x.x.x) - println(r.z.x.x.y) - println(r.z.x.x.z) - println(r.z.x.x.y.x) + supply(r) + supply(r.x) + supply(r.y) + supply(r.z) + supply(r.t) + supply(r.t.x) + supply(r.z.x) + supply(r.z.x.x) + supply(r.z.x.x.x) + supply(r.z.x.x.y) + supply(r.z.x.x.z) + supply(r.z.x.x.y.x) } fun g(e: E) { @@ -71,19 +71,19 @@ fun > h(r: R) { D(C(2, B(3U), "")) val x = D(C(2, B(3U), "")) var y = D(C(4, B(5U), "1")) - println(y) + supply(y) y = D(C(6, B(7U), "2")) y = D(6, 7U, 2) y = inlined(6, 7U, 2) y = notInlined(6, 7U, 2) - println(y) + supply(y) } fun h1() { var y = inlined(1, 2U, 3) // todo fix box - println(y) + supply(y) y = inlined(4, 5U, 6) - println(y) + supply(y) } interface Base1 { @@ -118,22 +118,22 @@ class NotInlined(override var l: R>, var y: Int) : Base1, Base2, Base4 var withNonTrivialSettersWithBF: R> = l get() { - println("1") + supply("1") field field.t field == field return field } set(value) { - println("3") + supply("3") field = value field = field - println("4") + supply("4") } val withNonTrivialGettersWithBF: R> = l get() { - println("1") + supply("1") field field.t field == field @@ -146,7 +146,7 @@ fun testVars(x: NotInlined) { var y = x.l y.toString() y = x.l - println(y) + supply(y) x.l = x.l x.l = R>(x.l.x, x.l.y, x.l.z, x.l.t) } @@ -155,7 +155,7 @@ fun reuseBoxed(list: MutableList>>) { list.add(list.last()) } -fun supply(x: Boolean) {} +fun supply(x: Any) {} fun equalsChecks1(x: A>) {} fun equalsChecks(left: R>, right: R>) { diff --git a/compiler/testData/codegen/box/valueClasses/complex.txt b/compiler/testData/codegen/box/valueClasses/complex.txt index 8049e2dec46..3e01a889d50 100644 --- a/compiler/testData/codegen/box/valueClasses/complex.txt +++ b/compiler/testData/codegen/box/valueClasses/complex.txt @@ -117,9 +117,9 @@ public final class C { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: int, p1: int, p2: java.lang.String, p3: java.lang.Object): boolean public final static method equals-impl0(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: java.lang.String): boolean - public final static method getX-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): int - public final static method getY-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): int - public final static @org.jetbrains.annotations.NotNull method getZ-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): java.lang.String + public final method getX(): int + public final method getY-GsR9Xnw(): int + public final @org.jetbrains.annotations.NotNull method getZ(): java.lang.String public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: java.lang.String): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -142,7 +142,7 @@ public final class ComplexKt { 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 public final static method reuseBoxed(@org.jetbrains.annotations.NotNull p0: java.util.List): void - public final static method supply(p0: boolean): void + public final static method supply(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void public final static method testVars(@org.jetbrains.annotations.NotNull p0: NotInlined): void } @@ -160,7 +160,7 @@ public final class D { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: int, p1: int, p2: java.lang.String, p3: java.lang.Object): boolean public final static method equals-impl0(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: java.lang.String): boolean - public final static @org.jetbrains.annotations.NotNull method getX-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): C + public final @org.jetbrains.annotations.NotNull method getX(): C public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: java.lang.String): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -185,7 +185,7 @@ public final class E { public static method equals-impl(p0: int, p1: int, p2: java.lang.String, p3: java.lang.Object): boolean public final static method equals-impl0(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: java.lang.String): boolean public final static @org.jetbrains.annotations.NotNull method getWithNonTrivialSetters-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): D - public final static @org.jetbrains.annotations.NotNull method getX-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): D + public final @org.jetbrains.annotations.NotNull method getX(): D public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: java.lang.String): int public final static method setWithNonTrivialSetters-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String, p3: int, p4: int, @org.jetbrains.annotations.NotNull p5: java.lang.String): void @@ -296,16 +296,15 @@ public final class R { public static @org.jetbrains.annotations.NotNull method getFakeOverrideMFVC-impl(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): R public method getFakeOverrideRegular(): int public static method getFakeOverrideRegular-impl(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): int - public final static @org.jetbrains.annotations.NotNull method getT-impl(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): java.util.List - public final static method getX-impl(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): int - public final static method getY-impl(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): int + public final @org.jetbrains.annotations.NotNull method getT-GKOAj6k(): java.util.List + public final method getX(): int + public final method getY-pVg5ArA(): int public @org.jetbrains.annotations.NotNull method getZ(): E public synthetic bridge method getZ-0(): D public synthetic bridge method getZ-0-0(): C public synthetic bridge method getZ-0-0-0(): int public synthetic bridge method getZ-0-0-1(): int public synthetic bridge method getZ-0-0-2(): java.lang.String - public static @org.jetbrains.annotations.NotNull method getZ-impl(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): E public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: int, p3: int, p4: java.lang.String, p5: java.util.List): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String diff --git a/compiler/testData/codegen/box/valueClasses/conditionalExpressions.txt b/compiler/testData/codegen/box/valueClasses/conditionalExpressions.txt index b5201384fd2..fa581313feb 100644 --- a/compiler/testData/codegen/box/valueClasses/conditionalExpressions.txt +++ b/compiler/testData/codegen/box/valueClasses/conditionalExpressions.txt @@ -38,8 +38,8 @@ public final class DPoint { public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean public final static method getCounter(): int - public final static method getX-impl(p0: double, p1: double): double - public final static method getY-impl(p0: double, p1: double): double + public final method getX(): double + public final method getY(): double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public final static method setCounter(p0: int): void diff --git a/compiler/testData/codegen/box/valueClasses/equality.txt b/compiler/testData/codegen/box/valueClasses/equality.txt index 2f73be4acd0..5b016a7f9e7 100644 --- a/compiler/testData/codegen/box/valueClasses/equality.txt +++ b/compiler/testData/codegen/box/valueClasses/equality.txt @@ -18,15 +18,15 @@ public final class A { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String, p10: java.lang.Object): boolean public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String, p10: int, p11: int, p12: int, p13: int, p14: int, p15: int, p16: java.lang.String, p17: int, p18: int, p19: java.lang.String): boolean - public final static method getF1-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): int - public final static method getF2-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): int - public final static @org.jetbrains.annotations.NotNull method getF3-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): F3 - public final static method getF4-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): int - public final static method getF5-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): int - public final static @org.jetbrains.annotations.NotNull method getF6-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): java.lang.String - public final static method getF7-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): int - public final static method getF8-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): int - public final static @org.jetbrains.annotations.NotNull method getF9-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String): java.lang.String + public final method getF1-DbFnDB4(): int + public final method getF2-ejSTSP4(): int + public final @org.jetbrains.annotations.NotNull method getF3(): F3 + public final method getF4-4yoqybc(): int + public final method getF5-z3qHWqM(): int + public final @org.jetbrains.annotations.NotNull method getF6-OgMO970(): java.lang.String + public final method getF7(): int + public final method getF8-pVg5ArA(): int + public final @org.jetbrains.annotations.NotNull method getF9(): java.lang.String public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -74,8 +74,8 @@ public final class B { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String, p10: int, p11: int, p12: int, p13: int, p14: int, p15: int, p16: java.lang.String, p17: int, p18: int, p19: java.lang.String, p20: java.lang.Object): boolean public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String, p10: int, p11: int, p12: int, p13: int, p14: int, p15: int, p16: java.lang.String, p17: int, p18: int, p19: java.lang.String, p20: int, p21: int, p22: int, p23: int, p24: int, p25: int, p26: java.lang.String, p27: int, p28: int, p29: java.lang.String, p30: int, p31: int, p32: int, p33: int, p34: int, p35: int, p36: java.lang.String, p37: int, p38: int, p39: java.lang.String): boolean - public final static @org.jetbrains.annotations.NotNull method getA1-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String, p10: int, p11: int, p12: int, p13: int, p14: int, p15: int, @org.jetbrains.annotations.NotNull p16: java.lang.String, p17: int, p18: int, @org.jetbrains.annotations.NotNull p19: java.lang.String): A - public final static @org.jetbrains.annotations.NotNull method getA2-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, @org.jetbrains.annotations.NotNull p6: java.lang.String, p7: int, p8: int, @org.jetbrains.annotations.NotNull p9: java.lang.String, p10: int, p11: int, p12: int, p13: int, p14: int, p15: int, @org.jetbrains.annotations.NotNull p16: java.lang.String, p17: int, p18: int, @org.jetbrains.annotations.NotNull p19: java.lang.String): A + public final @org.jetbrains.annotations.NotNull method getA1(): A + public final @org.jetbrains.annotations.NotNull method getA2(): A public method hashCode(): int public static method hashCode-impl(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String, p10: int, p11: int, p12: int, p13: int, p14: int, p15: int, p16: java.lang.String, p17: int, p18: int, p19: java.lang.String): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -162,8 +162,8 @@ public final class F3 { 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 static method getX-impl(p0: int, p1: int): int - public final static method getY-impl(p0: int, p1: int): int + public final method getX-DbFnDB4(): int + public final method getY-ejSTSP4(): 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 diff --git a/compiler/testData/codegen/box/valueClasses/forStatement.kt b/compiler/testData/codegen/box/valueClasses/forStatement.kt new file mode 100644 index 00000000000..4de0f9760dd --- /dev/null +++ b/compiler/testData/codegen/box/valueClasses/forStatement.kt @@ -0,0 +1,18 @@ +// 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 DPoint(val x: Double, val y: Double) + +fun box(): String { + var res = 0.0 + for (x in listOf(DPoint(1.0, 2.0), DPoint(3.0, 4.0))) { + res += x.x + x.y + } + require(res == 10.0) + return "OK" +} diff --git a/compiler/testData/codegen/box/valueClasses/forStatement.txt b/compiler/testData/codegen/box/valueClasses/forStatement.txt new file mode 100644 index 00000000000..98f635ef941 --- /dev/null +++ b/compiler/testData/codegen/box/valueClasses/forStatement.txt @@ -0,0 +1,27 @@ +@kotlin.jvm.JvmInline +@kotlin.Metadata +public final class DPoint { + // source: 'forStatement.kt' + private final field field-0: double + private final field field-1: double + private synthetic method (p0: double, p1: double): void + public synthetic final static method box-impl(p0: double, p1: double): DPoint + public final static method constructor-impl(p0: double, p1: double): void + public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean + public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean + public final method getX(): double + public final method getY(): double + public method hashCode(): int + public static method hashCode-impl(p0: double, p1: double): int + 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-impl-0(): double + public synthetic final method unbox-impl-1(): double +} + +@kotlin.Metadata +public final class ForStatementKt { + // source: 'forStatement.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.txt b/compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.txt index 4e42bf50702..c4f7b3babf5 100644 --- a/compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.txt +++ b/compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.txt @@ -44,8 +44,8 @@ public final class DPoint { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getX-impl(p0: double, p1: double): double - public final static method getY-impl(p0: double, p1: double): double + public final method getX(): double + public final method getY(): double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String diff --git a/compiler/testData/codegen/box/valueClasses/overrides.txt b/compiler/testData/codegen/box/valueClasses/overrides.txt index 046dd18ec82..829bb004e5e 100644 --- a/compiler/testData/codegen/box/valueClasses/overrides.txt +++ b/compiler/testData/codegen/box/valueClasses/overrides.txt @@ -26,10 +26,8 @@ public final class DPoint { public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean public @org.jetbrains.annotations.NotNull method getX(): java.lang.Double public synthetic bridge method getX(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getX-impl(p0: double, p1: double): java.lang.Double public @org.jetbrains.annotations.NotNull method getY(): java.lang.Double public synthetic bridge method getY(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getY-impl(p0: double, p1: double): java.lang.Double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -57,8 +55,8 @@ public final class DPointWithInterface { public static @org.jetbrains.annotations.NotNull method getSomethingMFVC-impl(p0: double, p1: double): DPoint public method getSomethingRegular(): int public static method getSomethingRegular-impl(p0: double, p1: double): int - public final static method getX-impl(p0: double, p1: double): double - public final static method getY-impl(p0: double, p1: double): double + public final method getX(): double + public final method getY(): double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public synthetic bridge method setSomethingGeneric(p0: java.lang.Object): void @@ -90,10 +88,8 @@ public final class DSegment { public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double, p6: double, p7: double): boolean public @org.jetbrains.annotations.NotNull method getP1(): DPoint public synthetic bridge method getP1(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getP1-impl(p0: double, p1: double, p2: double, p3: double): DPoint public @org.jetbrains.annotations.NotNull method getP2(): DPoint public synthetic bridge method getP2(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getP2-impl(p0: double, p1: double, p2: double, p3: double): DPoint public method hashCode(): int public static method hashCode-impl(p0: double, p1: double, p2: double, p3: double): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -147,8 +143,8 @@ public final class GenericFakeOverrideMFVC { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getField1-impl(p0: double, p1: double): double - public final static method getField2-impl(p0: double, p1: double): double + public final method getField1(): double + public final method getField2(): double public @org.jetbrains.annotations.NotNull method getP(): DPoint public synthetic bridge method getP(): java.lang.Object public static @org.jetbrains.annotations.NotNull method getP-impl(p0: double, p1: double): DPoint @@ -182,8 +178,8 @@ public final class GenericFakeOverrideMFVCWithMFVCUpperBound { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getField1-impl(p0: double, p1: double): double - public final static method getField2-impl(p0: double, p1: double): double + public final method getField1(): double + public final method getField2(): double public @org.jetbrains.annotations.NotNull method getP(): DPoint public static @org.jetbrains.annotations.NotNull method getP-impl(p0: double, p1: double): DPoint public @org.jetbrains.annotations.NotNull method getP1(): DPoint @@ -2509,8 +2505,8 @@ public final class ReifiedFakeOverrideMFVC { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getField1-impl(p0: double, p1: double): double - public final static method getField2-impl(p0: double, p1: double): double + public final method getField1(): double + public final method getField2(): double public @org.jetbrains.annotations.NotNull method getP(): DPoint public static @org.jetbrains.annotations.NotNull method getP-impl(p0: double, p1: double): DPoint public @org.jetbrains.annotations.NotNull method getP1(): DPoint diff --git a/compiler/testData/codegen/box/valueClasses/overrides_inlineClass.txt b/compiler/testData/codegen/box/valueClasses/overrides_inlineClass.txt index b97c35af023..faa05b5a938 100644 --- a/compiler/testData/codegen/box/valueClasses/overrides_inlineClass.txt +++ b/compiler/testData/codegen/box/valueClasses/overrides_inlineClass.txt @@ -26,10 +26,8 @@ public final class DPoint { public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean public synthetic bridge method getX(): java.lang.Object public method getX-3cLST_U(): double - public static method getX-impl(p0: double, p1: double): double public synthetic bridge method getY(): java.lang.Object public method getY-3cLST_U(): double - public static method getY-impl(p0: double, p1: double): double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -57,8 +55,8 @@ public final class DPointWithInterface { public static @org.jetbrains.annotations.NotNull method getSomethingMFVC-impl(p0: double, p1: double): DPoint public method getSomethingRegular(): int public static method getSomethingRegular-impl(p0: double, p1: double): int - public final static method getX-impl(p0: double, p1: double): double - public final static method getY-impl(p0: double, p1: double): double + public final method getX-3cLST_U(): double + public final method getY-3cLST_U(): double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public synthetic bridge method setSomethingGeneric(p0: java.lang.Object): void @@ -90,10 +88,8 @@ public final class DSegment { public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double, p6: double, p7: double): boolean public @org.jetbrains.annotations.NotNull method getP1(): DPoint public synthetic bridge method getP1(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getP1-impl(p0: double, p1: double, p2: double, p3: double): DPoint public @org.jetbrains.annotations.NotNull method getP2(): DPoint public synthetic bridge method getP2(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getP2-impl(p0: double, p1: double, p2: double, p3: double): DPoint public method hashCode(): int public static method hashCode-impl(p0: double, p1: double, p2: double, p3: double): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String @@ -147,8 +143,8 @@ public final class GenericFakeOverrideMFVC { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getField1-impl(p0: double, p1: double): double - public final static method getField2-impl(p0: double, p1: double): double + public final method getField1-3cLST_U(): double + public final method getField2-3cLST_U(): double public @org.jetbrains.annotations.NotNull method getP(): DPoint public synthetic bridge method getP(): java.lang.Object public static @org.jetbrains.annotations.NotNull method getP-impl(p0: double, p1: double): DPoint @@ -182,8 +178,8 @@ public final class GenericFakeOverrideMFVCWithMFVCUpperBound { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getField1-impl(p0: double, p1: double): double - public final static method getField2-impl(p0: double, p1: double): double + public final method getField1-3cLST_U(): double + public final method getField2-3cLST_U(): double public @org.jetbrains.annotations.NotNull method getP(): DPoint public static @org.jetbrains.annotations.NotNull method getP-impl(p0: double, p1: double): DPoint public @org.jetbrains.annotations.NotNull method getP1(): DPoint @@ -2526,8 +2522,8 @@ public final class ReifiedFakeOverrideMFVC { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getField1-impl(p0: double, p1: double): double - public final static method getField2-impl(p0: double, p1: double): double + public final method getField1-3cLST_U(): double + public final method getField2-3cLST_U(): double public @org.jetbrains.annotations.NotNull method getP(): DPoint public static @org.jetbrains.annotations.NotNull method getP-impl(p0: double, p1: double): DPoint public @org.jetbrains.annotations.NotNull method getP1(): DPoint diff --git a/compiler/testData/codegen/box/valueClasses/overrides_typeParameters.txt b/compiler/testData/codegen/box/valueClasses/overrides_typeParameters.txt index 6df22aedf9c..0cd4daada21 100644 --- a/compiler/testData/codegen/box/valueClasses/overrides_typeParameters.txt +++ b/compiler/testData/codegen/box/valueClasses/overrides_typeParameters.txt @@ -53,8 +53,8 @@ public final class GenericFakeOverrideMFVC { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): boolean public final static method equals-impl0(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object): boolean - public final static method getField1-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object - public final static method getField2-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public final method getField1(): java.lang.Object + public final method getField2(): java.lang.Object public @org.jetbrains.annotations.NotNull method getP(): XPoint public synthetic bridge method getP(): java.lang.Object public static @org.jetbrains.annotations.NotNull method getP-impl(p0: java.lang.Object, p1: java.lang.Object): XPoint @@ -88,8 +88,8 @@ public final class GenericFakeOverrideMFVCWithMFVCUpperBound { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): boolean public final static method equals-impl0(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object): boolean - public final static method getField1-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object - public final static method getField2-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public final method getField1(): java.lang.Object + public final method getField2(): java.lang.Object public @org.jetbrains.annotations.NotNull method getP(): XPoint public static @org.jetbrains.annotations.NotNull method getP-impl(p0: java.lang.Object, p1: java.lang.Object): XPoint public @org.jetbrains.annotations.NotNull method getP1(): XPoint @@ -2417,8 +2417,8 @@ public final class ReifiedFakeOverrideMFVC { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): boolean public final static method equals-impl0(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object): boolean - public final static method getField1-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object - public final static method getField2-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public final method getField1(): java.lang.Object + public final method getField2(): java.lang.Object public @org.jetbrains.annotations.NotNull method getP(): XPoint public static @org.jetbrains.annotations.NotNull method getP-impl(p0: java.lang.Object, p1: java.lang.Object): XPoint public @org.jetbrains.annotations.NotNull method getP1(): XPoint @@ -2534,9 +2534,7 @@ public final class XPoint { public static method equals-impl(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): boolean public final static method equals-impl0(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object): boolean public method getX(): java.lang.Object - public static method getX-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object public method getY(): java.lang.Object - public static method getY-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object public method hashCode(): int public static method hashCode-impl(p0: java.lang.Object, p1: java.lang.Object): int public method someFunction1(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): void @@ -2568,8 +2566,8 @@ public final class XPointWithInterface { public static @org.jetbrains.annotations.NotNull method getSomethingMFVC-impl(p0: java.lang.Object, p1: java.lang.Object): XPoint public method getSomethingRegular(): int public static method getSomethingRegular-impl(p0: java.lang.Object, p1: java.lang.Object): int - public final static method getX-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object - public final static method getY-impl(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public final method getX(): java.lang.Object + public final method getY(): java.lang.Object public method hashCode(): int public static method hashCode-impl(p0: java.lang.Object, p1: java.lang.Object): int public synthetic bridge method setSomethingGeneric(p0: java.lang.Object): void @@ -2601,10 +2599,8 @@ public final class XSegment { public final static method equals-impl0(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object, p4: java.lang.Object, p5: java.lang.Object, p6: java.lang.Object, p7: java.lang.Object): boolean public @org.jetbrains.annotations.NotNull method getP1(): XPoint public synthetic bridge method getP1(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getP1-impl(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object): XPoint public @org.jetbrains.annotations.NotNull method getP2(): XPoint public synthetic bridge method getP2(): java.lang.Object - public static @org.jetbrains.annotations.NotNull method getP2-impl(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object): XPoint public method hashCode(): int public static method hashCode-impl(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object, p3: java.lang.Object): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String diff --git a/compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.txt b/compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.txt index 0f7e98b0c3c..acf12a7a4dc 100644 --- a/compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.txt +++ b/compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.txt @@ -10,8 +10,8 @@ public final class DPoint { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getX-impl(p0: double, p1: double): double - public final static method getY-impl(p0: double, p1: double): double + public final method getX(): double + public final method getY(): double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String diff --git a/compiler/testData/codegen/box/valueClasses/tryExpressions.txt b/compiler/testData/codegen/box/valueClasses/tryExpressions.txt index f21ff8086d3..ad19332a692 100644 --- a/compiler/testData/codegen/box/valueClasses/tryExpressions.txt +++ b/compiler/testData/codegen/box/valueClasses/tryExpressions.txt @@ -10,8 +10,8 @@ public final class DPoint { public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean - public final static method getX-impl(p0: double, p1: double): double - public final static method getY-impl(p0: double, p1: double): double + public final method getX(): double + public final method getY(): double public method hashCode(): int public static method hashCode-impl(p0: double, p1: double): int public @org.jetbrains.annotations.NotNull method toString(): java.lang.String diff --git a/compiler/testData/codegen/box/valueClasses/visibility.txt b/compiler/testData/codegen/box/valueClasses/visibility.txt index a25ec4b1106..3a2b8f5c636 100644 --- a/compiler/testData/codegen/box/valueClasses/visibility.txt +++ b/compiler/testData/codegen/box/valueClasses/visibility.txt @@ -41,10 +41,10 @@ public final class Internal { 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 static @org.jetbrains.annotations.NotNull method getT(): Internal + public final method getX$main(): int public final static method getX(): int - public final static method getX-impl$main(p0: int, p1: int): int + public final method getY$main(): int public final static method getY(): int - public final static method getY-impl$main(p0: int, p1: int): int public method hashCode(): int public static method hashCode-impl(p0: int, p1: int): int public final static method setX(p0: int): void @@ -67,7 +67,7 @@ public final class InternalInternal { 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 static @org.jetbrains.annotations.NotNull method getValue-impl$main(p0: int, p1: int): Internal + public final @org.jetbrains.annotations.NotNull method getValue$main(): 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 @@ -89,7 +89,7 @@ public final class InternalPrivate { 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 static @org.jetbrains.annotations.NotNull method getValue-impl$main(p0: int, p1: int): Private + public final @org.jetbrains.annotations.NotNull method getValue$main(): 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 @@ -111,7 +111,7 @@ public final class InternalPublic { 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 static @org.jetbrains.annotations.NotNull method getValue-impl$main(p0: int, p1: int): Public + public final @org.jetbrains.annotations.NotNull method getValue$main(): 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 @@ -243,8 +243,8 @@ public final class Public { 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 static method getX-impl(p0: int, p1: int): int - public final static method getY-impl(p0: int, p1: int): int + 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 @@ -266,7 +266,7 @@ public final class PublicInternal { 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 static @org.jetbrains.annotations.NotNull method getValue-impl(p0: int, p1: int): Internal + 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 @@ -288,7 +288,7 @@ public final class PublicPrivate { 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 static @org.jetbrains.annotations.NotNull method getValue-impl(p0: int, p1: int): Private + 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 @@ -310,7 +310,7 @@ public final class PublicPublic { 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 static @org.jetbrains.annotations.NotNull method getValue-impl(p0: int, p1: int): Public + 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 diff --git a/compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt b/compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt index 23ce0fb1a4e..756d7ef4399 100644 --- a/compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt +++ b/compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt @@ -49,7 +49,7 @@ fun functionWithoutBoxes(x: D, y: D) { // 2 public final static constructor-impl\(IILjava/lang/String;\)V // 2 INVOKESTATIC D.constructor-impl \(IILjava/lang/String;\)V // 2 INVOKESTATIC C.constructor-impl \(IILjava/lang/String;\)V -// 1 public final static getX-impl\(.+\)LC; +// 1 public final getX\(\)LC; // 1 public final synthetic unbox-impl-0-0\(\)I // 1 public final synthetic unbox-impl-0-1\(\)I // 1 public final synthetic unbox-impl-0-2\(\)Ljava/lang/String; diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 049772afd6d..354a4323361 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -50207,6 +50207,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/valueClasses/equality.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("forStatement.kt") + public void testForStatement() throws Exception { + runTest("compiler/testData/codegen/box/valueClasses/forStatement.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("mfvcFieldInitializationOrder.kt") public void testMfvcFieldInitializationOrder() throws Exception {