Revert "rra/zhelenskiy/flattening_impl"
This reverts commit b7f5c039a6.
This commit is contained in:
committed by
teamcity
parent
dff949344d
commit
d4969e9b97
+2
-4
@@ -301,16 +301,14 @@ private fun MethodInsnNode.isInlineClassBoxingMethodDescriptor(state: Generation
|
||||
if (name != KotlinTypeMapper.BOX_JVM_METHOD_NAME) return false
|
||||
|
||||
val ownerType = Type.getObjectType(owner)
|
||||
val unboxedType = unboxedTypeOfInlineClass(ownerType, state) ?: return false
|
||||
return desc == Type.getMethodDescriptor(ownerType, unboxedType)
|
||||
return desc == Type.getMethodDescriptor(ownerType, unboxedTypeOfInlineClass(ownerType, state))
|
||||
}
|
||||
|
||||
private fun MethodInsnNode.isInlineClassUnboxingMethodDescriptor(state: GenerationState): Boolean {
|
||||
if (name != KotlinTypeMapper.UNBOX_JVM_METHOD_NAME) return false
|
||||
|
||||
val ownerType = Type.getObjectType(owner)
|
||||
val unboxedType = unboxedTypeOfInlineClass(ownerType, state) ?: return false
|
||||
return desc == Type.getMethodDescriptor(unboxedType)
|
||||
return desc == Type.getMethodDescriptor(unboxedTypeOfInlineClass(ownerType, state))
|
||||
}
|
||||
|
||||
fun AbstractInsnNode.isNextMethodCallOfProgressionIterator(values: List<BasicValue>) =
|
||||
|
||||
-60
@@ -50189,71 +50189,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/valueClasses/classFlattening.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("complex.kt")
|
||||
public void testComplex() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/complex.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionalExpressions.kt")
|
||||
public void testConditionalExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/conditionalExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equality.kt")
|
||||
public void testEquality() throws Exception {
|
||||
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 {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrides.kt")
|
||||
public void testOverrides() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/overrides.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrides_inlineClass.kt")
|
||||
public void testOverrides_inlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/overrides_inlineClass.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrides_typeParameters.kt")
|
||||
public void testOverrides_typeParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/overrides_typeParameters.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("throwingMFVCReassignments.kt")
|
||||
public void testThrowingMFVCReassignments() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("tryExpressions.kt")
|
||||
public void testTryExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("visibility.kt")
|
||||
public void testVisibility() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/visibility.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
-53
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.test.runners.codegen;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -5780,58 +5779,6 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/valueClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ValueClasses {
|
||||
@Test
|
||||
public void testAllFilesPresentInValueClasses() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/valueClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionalExpressions.kt")
|
||||
public void testConditionalExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/conditionalExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalsBoxTest.kt")
|
||||
public void testEqualsBoxTest() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/equalsBoxTest.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcDeclaration.kt")
|
||||
public void testMfvcDeclaration() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcReassignments.kt")
|
||||
public void testMfvcReassignments() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("passingMFVC2Functions.kt")
|
||||
public void testPassingMFVC2Functions() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/passingMFVC2Functions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("regularClassWithMFVC.kt")
|
||||
public void testRegularClassWithMFVC() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/regularClassWithMFVC.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("tryExpressions.kt")
|
||||
public void testTryExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/varargs")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
-1
@@ -346,7 +346,6 @@ abstract class AnnotationCodegen(
|
||||
declaration.origin.isSynthetic ->
|
||||
true
|
||||
declaration.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
declaration.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
declaration.origin == IrDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION ->
|
||||
true
|
||||
else ->
|
||||
|
||||
-1
@@ -294,7 +294,6 @@ class ExpressionCodegen(
|
||||
(irFunction is IrConstructor && irFunction.parentAsClass.isAnonymousObject) ||
|
||||
// TODO: Implement this as a lowering, so that we can more easily exclude generated methods.
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
// Although these are accessible from Java, the functions they bridge to already have the assertions.
|
||||
irFunction.origin == IrDeclarationOrigin.BRIDGE_SPECIAL ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE ||
|
||||
|
||||
+1
-2
@@ -37,10 +37,9 @@ object HashCode : IntrinsicMethod() {
|
||||
val target = context.state.target
|
||||
when {
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ||
|
||||
irFunction.origin == IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER -> {
|
||||
// TODO generate or lower IR for data class / value class 'hashCode'?
|
||||
// TODO generate or lower IR for data class / inline class 'hashCode'?
|
||||
DescriptorAsmUtil.genHashCode(mv, mv, receiverType, target)
|
||||
}
|
||||
target >= JvmTarget.JVM_1_8 && AsmUtil.isPrimitive(receiverJvmType) -> {
|
||||
|
||||
@@ -309,7 +309,6 @@ private val jvmFilePhases = listOf(
|
||||
forLoopsPhase,
|
||||
collectionStubMethodLowering,
|
||||
singleAbstractMethodPhase,
|
||||
jvmMultiFieldValueClassPhase,
|
||||
jvmInlineClassPhase,
|
||||
tailrecPhase,
|
||||
// makePatchParentsPhase(),
|
||||
|
||||
+19
-142
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.MultiFieldValueClassMapping
|
||||
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.RegularMapping
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.SpecialBridge
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import kotlin.collections.set
|
||||
|
||||
/*
|
||||
* Generate bridge methods to fix virtual dispatch after type erasure and to adapt Kotlin collections to
|
||||
@@ -113,7 +112,7 @@ internal val bridgePhase = makeIrFilePhase(
|
||||
::BridgeLowering,
|
||||
name = "Bridge",
|
||||
description = "Generate bridges",
|
||||
prerequisite = setOf(jvmInlineClassPhase, jvmMultiFieldValueClassPhase, inheritedDefaultMethodsOnClassesPhase)
|
||||
prerequisite = setOf(jvmInlineClassPhase)
|
||||
)
|
||||
|
||||
internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() {
|
||||
@@ -235,7 +234,6 @@ 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.
|
||||
@@ -264,7 +262,6 @@ 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.
|
||||
@@ -434,11 +431,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
}.apply {
|
||||
copyAttributes(target)
|
||||
copyParametersWithErasure(this@addBridge, bridge.overridden)
|
||||
with(context.multiFieldValueClassReplacements) {
|
||||
bindingNewFunctionToParameterTemplateStructure[bridge.overridden]?.also {
|
||||
bindingNewFunctionToParameterTemplateStructure[this@apply] = it
|
||||
}
|
||||
}
|
||||
|
||||
// If target is a throwing stub, bridge also should just throw UnsupportedOperationException.
|
||||
// Otherwise, it might throw ClassCastException when downcasting bridge argument to expected type.
|
||||
@@ -494,11 +486,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
context.functionsWithSpecialBridges.add(target)
|
||||
|
||||
copyParametersWithErasure(this@addSpecialBridge, specialBridge.overridden, specialBridge.substitutedParameterTypes)
|
||||
with(context.multiFieldValueClassReplacements) {
|
||||
bindingNewFunctionToParameterTemplateStructure[specialBridge.overridden]?.also {
|
||||
bindingNewFunctionToParameterTemplateStructure[this@apply] = it
|
||||
}
|
||||
}
|
||||
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody {
|
||||
specialBridge.methodInfo?.let { info ->
|
||||
@@ -623,132 +610,22 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
target: IrSimpleFunction,
|
||||
superQualifierSymbol: IrClassSymbol? = null
|
||||
) =
|
||||
irCastIfNeeded(irBlock {
|
||||
+irReturn(irCall(target, origin = IrStatementOrigin.BRIDGE_DELEGATION, superQualifierSymbol = superQualifierSymbol).apply {
|
||||
|
||||
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)
|
||||
irCastIfNeeded(
|
||||
irCall(target, origin = IrStatementOrigin.BRIDGE_DELEGATION, superQualifierSymbol = superQualifierSymbol).apply {
|
||||
for ((param, targetParam) in bridge.explicitParameters.zip(target.explicitParameters)) {
|
||||
putArgument(
|
||||
targetParam,
|
||||
irGet(param).let { argument ->
|
||||
if (param == bridge.dispatchReceiverParameter)
|
||||
argument
|
||||
else
|
||||
irCastIfNeeded(argument, targetParam.type.upperBound)
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
}.unwrapBlock(), bridge.returnType.upperBound)
|
||||
|
||||
private fun getStructure(function: IrSimpleFunction): List<MemoizedMultiFieldValueClassReplacements.RemappedParameter>? {
|
||||
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<MemoizedMultiFieldValueClassReplacements.RemappedParameter>?,
|
||||
bridgeStructure: List<MemoizedMultiFieldValueClassReplacements.RemappedParameter>?,
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
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(this)
|
||||
for (newArgument in newArguments) {
|
||||
irCall.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 bridgeParameter = bridgeExplicitParameters[bridgeIndex++]
|
||||
irCall.putArgument(targetParameter, irGetOrCast(bridge, bridgeParameter, targetParameter))
|
||||
}
|
||||
}
|
||||
targetIndex++
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
},
|
||||
bridge.returnType.upperBound
|
||||
)
|
||||
|
||||
private fun IrBuilderWithScope.irCastIfNeeded(expression: IrExpression, to: IrType): IrExpression =
|
||||
if (expression.type == to || to.isAny() || to.isNullableAny()) expression else irImplicitCast(expression, to)
|
||||
|
||||
+7
-47
@@ -12,11 +12,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.MultiFieldValueClassMapping
|
||||
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.RegularMapping
|
||||
import org.jetbrains.kotlin.backend.jvm.fullValueParameterList
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||
import org.jetbrains.kotlin.backend.jvm.makeBoxedExpression
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
@@ -95,7 +91,6 @@ 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(
|
||||
@@ -105,50 +100,15 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo
|
||||
}
|
||||
passTypeArgumentsFrom(irFunction, offset = superMethod.parentAsClass.typeParameters.size)
|
||||
|
||||
var offset = 0
|
||||
irFunction.dispatchReceiverParameter?.let {
|
||||
putValueArgument(0, irGet(it).reinterpretAsDispatchReceiverOfType(superClassType))
|
||||
}
|
||||
val mfvcOrOriginal = backendContext.inlineClassReplacements.originalFunctionForMethodReplacement[classOverride]
|
||||
?: classOverride
|
||||
val bindingNewFunctionToParameterTemplateStructure = backendContext.multiFieldValueClassReplacements
|
||||
.bindingNewFunctionToParameterTemplateStructure
|
||||
val structure = bindingNewFunctionToParameterTemplateStructure[mfvcOrOriginal]?.let { structure ->
|
||||
require(structure.sumOf { it.valueParameters.size } == classOverride.explicitParametersCount) {
|
||||
"Bad parameters structure: $structure"
|
||||
}
|
||||
if (defaultImplFun.explicitParametersCount == irFunction.explicitParametersCount) {
|
||||
null
|
||||
} else {
|
||||
require(structure.size == defaultImplFun.explicitParametersCount) { "Bad parameters structure: $structure" }
|
||||
structure
|
||||
}
|
||||
}
|
||||
require(structure == null || structure.first() is RegularMapping) {
|
||||
"Dispatch receiver for method replacement cannot be flattened"
|
||||
}
|
||||
val sourceFullValueParameterList = irFunction.fullValueParameterList
|
||||
if (structure == null) {
|
||||
for ((index, parameter) in sourceFullValueParameterList.withIndex()) {
|
||||
putValueArgument(1 + index, irGet(parameter))
|
||||
}
|
||||
} else {
|
||||
var flattenedIndex = 0
|
||||
for (i in 1 until structure.size) {
|
||||
when (val remappedParameter = structure[i]) {
|
||||
is MultiFieldValueClassMapping -> {
|
||||
val valueArguments = remappedParameter.valueParameters.indices.map {
|
||||
irGet(sourceFullValueParameterList[flattenedIndex++])
|
||||
}
|
||||
val boxedExpression = remappedParameter.rootMfvcNode.makeBoxedExpression(
|
||||
this@irBlockBody, remappedParameter.typeArguments, valueArguments
|
||||
)
|
||||
putValueArgument(i, boxedExpression)
|
||||
}
|
||||
|
||||
is RegularMapping -> putValueArgument(i, irGet(sourceFullValueParameterList[flattenedIndex++]))
|
||||
}
|
||||
}
|
||||
putValueArgument(
|
||||
offset++,
|
||||
irGet(it).reinterpretAsDispatchReceiverOfType(superClassType)
|
||||
)
|
||||
}
|
||||
irFunction.extensionReceiverParameter?.let { putValueArgument(offset++, irGet(it)) }
|
||||
irFunction.valueParameters.mapIndexed { i, parameter -> putValueArgument(i + offset, irGet(parameter)) }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ private class JvmDefaultConstructorLowering(val context: JvmBackendContext) : Cl
|
||||
if (DescriptorVisibilities.isPrivate(primaryConstructor.visibility))
|
||||
return
|
||||
|
||||
if (primaryConstructor.hasMangledParameters())
|
||||
if (primaryConstructor.hasMangledParameters)
|
||||
return
|
||||
|
||||
if (primaryConstructor.valueParameters.isEmpty() || !primaryConstructor.valueParameters.all { it.hasDefaultValue() })
|
||||
|
||||
+83
-70
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
@@ -22,7 +24,6 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.ir.types.isNullable
|
||||
import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
||||
|
||||
@@ -41,9 +43,7 @@ val jvmInlineClassPhase = makeIrFilePhase(
|
||||
// Standard library replacements are done on the unmangled names for UInt and ULong classes.
|
||||
// Collection stubs may require mangling by inline class rules.
|
||||
// SAM wrappers may require mangling for fun interfaces with inline class parameters
|
||||
prerequisite = setOf(
|
||||
forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering, singleAbstractMethodPhase, jvmMultiFieldValueClassPhase
|
||||
),
|
||||
prerequisite = setOf(forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering, singleAbstractMethodPhase),
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -58,15 +58,73 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
override val replacements: MemoizedValueClassAbstractReplacements
|
||||
get() = context.inlineClassReplacements
|
||||
|
||||
private val valueMap = mutableMapOf<IrValueSymbol, IrValueDeclaration>()
|
||||
override fun IrClass.isSpecificLoweringLogicApplicable(): Boolean = isSingleFieldValueClass
|
||||
|
||||
override fun addBindingsFor(original: IrFunction, replacement: IrFunction) {
|
||||
for ((param, newParam) in original.explicitParameters.zip(replacement.explicitParameters)) {
|
||||
valueMap[param.symbol] = newParam
|
||||
}
|
||||
override fun IrFunction.isSpecificFieldGetter(): Boolean = isInlineClassFieldGetter
|
||||
|
||||
override fun addJvmInlineAnnotation(valueClass: IrClass) {
|
||||
if (valueClass.hasAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME)) return
|
||||
val constructor = context.ir.symbols.jvmInlineAnnotation.constructors.first()
|
||||
valueClass.annotations = valueClass.annotations + IrConstructorCallImpl.fromSymbolOwner(
|
||||
constructor.owner.returnType,
|
||||
constructor
|
||||
)
|
||||
}
|
||||
|
||||
override fun createBridgeDeclaration(source: IrSimpleFunction, replacement: IrSimpleFunction, mangledName: Name): IrSimpleFunction =
|
||||
override fun transformSimpleFunctionFlat(function: IrSimpleFunction, replacement: IrSimpleFunction): List<IrDeclaration> {
|
||||
replacement.valueParameters.forEach {
|
||||
it.transformChildrenVoid()
|
||||
it.defaultValue?.patchDeclarationParents(replacement)
|
||||
}
|
||||
allScopes.push(createScope(function))
|
||||
replacement.body = function.body?.transform(this, null)?.patchDeclarationParents(replacement)
|
||||
allScopes.pop()
|
||||
replacement.copyAttributes(function)
|
||||
|
||||
// Don't create a wrapper for functions which are only used in an unboxed context
|
||||
if (function.overriddenSymbols.isEmpty() || replacement.dispatchReceiverParameter != null)
|
||||
return listOf(replacement)
|
||||
|
||||
val bridgeFunction = createBridgeDeclaration(
|
||||
function,
|
||||
when {
|
||||
// If the original function has signature which need mangling we still need to replace it with a mangled version.
|
||||
(!function.isFakeOverride || function.findInterfaceImplementation(context.state.jvmDefaultMode) != null) &&
|
||||
function.signatureRequiresMangling() ->
|
||||
replacement.name
|
||||
// Since we remove the corresponding property symbol from the bridge we need to resolve getter/setter
|
||||
// names at this point.
|
||||
replacement.isGetter ->
|
||||
Name.identifier(JvmAbi.getterName(replacement.correspondingPropertySymbol!!.owner.name.asString()))
|
||||
replacement.isSetter ->
|
||||
Name.identifier(JvmAbi.setterName(replacement.correspondingPropertySymbol!!.owner.name.asString()))
|
||||
else ->
|
||||
function.name
|
||||
}
|
||||
)
|
||||
|
||||
// Update the overridden symbols to point to their inline class replacements
|
||||
bridgeFunction.overriddenSymbols = replacement.overriddenSymbols
|
||||
|
||||
// Replace the function body with a wrapper
|
||||
if (bridgeFunction.isFakeOverride && bridgeFunction.parentAsClass.isSingleFieldValueClass) {
|
||||
// Fake overrides redirect from the replacement to the original function, which is in turn replaced during interfacePhase.
|
||||
createBridgeBody(replacement, bridgeFunction)
|
||||
} else {
|
||||
createBridgeBody(bridgeFunction, replacement)
|
||||
}
|
||||
|
||||
return listOf(replacement, bridgeFunction)
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.signatureRequiresMangling() =
|
||||
fullValueParameterList.any { it.type.requiresMangling } ||
|
||||
context.state.functionsWithInlineClassReturnTypesMangled && returnType.requiresMangling
|
||||
|
||||
// We may need to add a bridge method for inline class methods with static replacements. Ideally, we'd do this in BridgeLowering,
|
||||
// but unfortunately this is a special case in the old backend. The bridge method is not marked as such and does not follow the normal
|
||||
// visibility rules for bridge methods.
|
||||
private fun createBridgeDeclaration(source: IrSimpleFunction, mangledName: Name) =
|
||||
context.irFactory.buildFun {
|
||||
updateFrom(source)
|
||||
name = mangledName
|
||||
@@ -81,59 +139,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
copyAttributes(source)
|
||||
}
|
||||
|
||||
override fun IrClass.isSpecificLoweringLogicApplicable(): Boolean = isSingleFieldValueClass
|
||||
|
||||
override val specificMangle: SpecificMangle
|
||||
get() = SpecificMangle.Inline
|
||||
|
||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||
// The arguments to the primary constructor are in scope in the initializers of IrFields.
|
||||
|
||||
declaration.primaryConstructor?.let {
|
||||
replacements.getReplacementFunction(it)?.let { replacement -> addBindingsFor(it, replacement) }
|
||||
}
|
||||
|
||||
declaration.transformDeclarationsFlat { memberDeclaration ->
|
||||
if (memberDeclaration is IrFunction) {
|
||||
withinScope(memberDeclaration) {
|
||||
transformFunctionFlat(memberDeclaration)
|
||||
}
|
||||
} else {
|
||||
memberDeclaration.accept(this, null)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.isSpecificLoweringLogicApplicable()) {
|
||||
handleSpecificNewClass(declaration)
|
||||
}
|
||||
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun handleSpecificNewClass(declaration: IrClass) {
|
||||
val irConstructor = declaration.primaryConstructor!!
|
||||
// The field getter is used by reflection and cannot be removed here unless it is internal.
|
||||
declaration.declarations.removeIf {
|
||||
it == irConstructor || (it is IrFunction && it.isInlineClassFieldGetter && !it.visibility.isPublicAPI)
|
||||
}
|
||||
buildPrimaryInlineClassConstructor(declaration, irConstructor)
|
||||
buildBoxFunction(declaration)
|
||||
buildUnboxFunction(declaration)
|
||||
buildSpecializedEqualsMethod(declaration)
|
||||
addJvmInlineAnnotation(declaration)
|
||||
}
|
||||
|
||||
fun addJvmInlineAnnotation(valueClass: IrClass) {
|
||||
if (valueClass.hasAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME)) return
|
||||
val constructor = context.ir.symbols.jvmInlineAnnotation.constructors.first()
|
||||
valueClass.annotations = valueClass.annotations + IrConstructorCallImpl.fromSymbolOwner(
|
||||
constructor.owner.returnType,
|
||||
constructor
|
||||
)
|
||||
}
|
||||
|
||||
override fun createBridgeBody(source: IrSimpleFunction, target: IrSimpleFunction, original: IrFunction, inverted: Boolean) {
|
||||
private fun createBridgeBody(source: IrSimpleFunction, target: IrSimpleFunction) {
|
||||
source.body = context.createIrBuilder(source.symbol, source.startOffset, source.endOffset).run {
|
||||
irExprBody(irCall(target).apply {
|
||||
passTypeArgumentsFrom(source)
|
||||
@@ -147,7 +153,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
// Secondary constructors for boxed types get translated to static functions returning
|
||||
// unboxed arguments. We remove the original constructor.
|
||||
// Primary constructors' case is handled at the start of transformFunctionFlat
|
||||
override fun transformSecondaryConstructorFlat(constructor: IrConstructor, replacement: IrSimpleFunction): List<IrDeclaration> {
|
||||
override fun transformConstructorFlat(constructor: IrConstructor, replacement: IrSimpleFunction): List<IrDeclaration> {
|
||||
replacement.valueParameters.forEach { it.transformChildrenVoid() }
|
||||
replacement.body = context.createIrBuilder(replacement.symbol, replacement.startOffset, replacement.endOffset).irBlockBody(
|
||||
replacement
|
||||
@@ -205,6 +211,12 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
return listOf(replacement)
|
||||
}
|
||||
|
||||
private fun typedArgumentList(function: IrFunction, expression: IrMemberAccessExpression<*>) =
|
||||
listOfNotNull(
|
||||
function.dispatchReceiverParameter?.let { it to expression.dispatchReceiver },
|
||||
function.extensionReceiverParameter?.let { it to expression.extensionReceiver }
|
||||
) + function.valueParameters.map { it to expression.getValueArgument(it.index) }
|
||||
|
||||
private fun IrMemberAccessExpression<*>.buildReplacement(
|
||||
originalFunction: IrFunction,
|
||||
original: IrMemberAccessExpression<*>,
|
||||
@@ -275,8 +287,6 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
private fun IrExpression.coerceToUnboxed() =
|
||||
coerceInlineClasses(this, this.type, this.type.unboxInlineClass())
|
||||
|
||||
override fun keepOldFunctionInsteadOfNew(function: IrFunction): Boolean = false
|
||||
|
||||
// Precondition: left has an inline class type, but may not be unboxed
|
||||
private fun IrBuilderWithScope.specializeEqualsCall(left: IrExpression, right: IrExpression): IrExpression? {
|
||||
// There's already special handling for null-comparisons in the Equals intrinsic.
|
||||
@@ -353,7 +363,6 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
.specializeEqualsCall(expression.getValueArgument(0)!!, expression.getValueArgument(1)!!)
|
||||
?: expression
|
||||
}
|
||||
|
||||
else ->
|
||||
super.visitCall(expression)
|
||||
}
|
||||
@@ -411,7 +420,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
return super.visitSetValue(expression)
|
||||
}
|
||||
|
||||
fun buildPrimaryInlineClassConstructor(valueClass: IrClass, irConstructor: IrConstructor) {
|
||||
override fun buildPrimaryValueClassConstructor(valueClass: IrClass, irConstructor: IrConstructor) {
|
||||
// Add the default primary constructor
|
||||
valueClass.addConstructor {
|
||||
updateFrom(irConstructor)
|
||||
@@ -456,7 +465,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
valueClass.declarations += function
|
||||
}
|
||||
|
||||
fun buildBoxFunction(valueClass: IrClass) {
|
||||
override fun buildBoxFunction(valueClass: IrClass) {
|
||||
val function = context.inlineClassReplacements.getBoxFunction(valueClass)
|
||||
with(context.createIrBuilder(function.symbol)) {
|
||||
function.body = irExprBody(
|
||||
@@ -469,6 +478,10 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
valueClass.declarations += function
|
||||
}
|
||||
|
||||
override fun buildUnboxFunctions(valueClass: IrClass) {
|
||||
buildUnboxFunction(valueClass)
|
||||
}
|
||||
|
||||
private fun buildUnboxFunction(irClass: IrClass) {
|
||||
val function = context.inlineClassReplacements.getUnboxFunction(irClass)
|
||||
val field = getInlineClassBackingField(irClass)
|
||||
@@ -481,7 +494,7 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass
|
||||
irClass.declarations += function
|
||||
}
|
||||
|
||||
fun buildSpecializedEqualsMethod(valueClass: IrClass) {
|
||||
override fun buildSpecializedEqualsMethod(valueClass: IrClass) {
|
||||
val function = context.inlineClassReplacements.getSpecializedEqualsMethod(valueClass, context.irBuiltIns)
|
||||
val left = function.valueParameters[0]
|
||||
val right = function.valueParameters[1]
|
||||
|
||||
+31
-1280
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -10,10 +10,10 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.getRequiresMangling
|
||||
import org.jetbrains.kotlin.backend.jvm.hasMangledReturnType
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.eraseTypeParameters
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.needsAccessor
|
||||
import org.jetbrains.kotlin.backend.jvm.requiresMangling
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
@@ -222,7 +222,7 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
||||
val getter = property.getter
|
||||
if (getter != null) {
|
||||
val needsMangling =
|
||||
getter.extensionReceiverParameter?.type?.getRequiresMangling(includeInline = true, includeMFVC = false) == true ||
|
||||
getter.extensionReceiverParameter?.type?.requiresMangling == true ||
|
||||
(state.functionsWithInlineClassReturnTypesMangled && getter.hasMangledReturnType)
|
||||
val mangled = if (needsMangling) inlineClassReplacements.getReplacementFunction(getter) else null
|
||||
defaultMethodSignatureMapper.mapFunctionName(mangled ?: getter)
|
||||
|
||||
+55
-115
@@ -8,32 +8,70 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
import org.jetbrains.kotlin.backend.jvm.InlineClassAbi
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.MemoizedValueClassAbstractReplacements
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendContext) : FileLoweringPass,
|
||||
IrElementTransformerVoidWithContext() {
|
||||
abstract val replacements: MemoizedValueClassAbstractReplacements
|
||||
|
||||
protected val valueMap = mutableMapOf<IrValueSymbol, IrValueDeclaration>()
|
||||
|
||||
private fun addBindingsFor(original: IrFunction, replacement: IrFunction) {
|
||||
for ((param, newParam) in original.explicitParameters.zip(replacement.explicitParameters)) {
|
||||
valueMap[param.symbol] = newParam
|
||||
}
|
||||
}
|
||||
|
||||
final override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid()
|
||||
}
|
||||
|
||||
abstract fun IrClass.isSpecificLoweringLogicApplicable(): Boolean
|
||||
|
||||
abstract override fun visitClassNew(declaration: IrClass): IrStatement
|
||||
abstract fun IrFunction.isSpecificFieldGetter(): Boolean
|
||||
|
||||
abstract fun handleSpecificNewClass(declaration: IrClass)
|
||||
final override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||
// The arguments to the primary constructor are in scope in the initializers of IrFields.
|
||||
declaration.primaryConstructor?.let {
|
||||
replacements.getReplacementFunction(it)?.let { replacement -> addBindingsFor(it, replacement) }
|
||||
}
|
||||
|
||||
declaration.transformDeclarationsFlat { memberDeclaration ->
|
||||
if (memberDeclaration is IrFunction) {
|
||||
withinScope(memberDeclaration) {
|
||||
transformFunctionFlat(memberDeclaration)
|
||||
}
|
||||
} else {
|
||||
memberDeclaration.accept(this, null)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.isSpecificLoweringLogicApplicable()) {
|
||||
val irConstructor = declaration.primaryConstructor!!
|
||||
// The field getter is used by reflection and cannot be removed here unless it is internal.
|
||||
declaration.declarations.removeIf {
|
||||
it == irConstructor || (it is IrFunction && it.isSpecificFieldGetter() && !it.visibility.isPublicAPI)
|
||||
}
|
||||
buildPrimaryValueClassConstructor(declaration, irConstructor)
|
||||
buildBoxFunction(declaration)
|
||||
buildUnboxFunctions(declaration)
|
||||
buildSpecializedEqualsMethod(declaration)
|
||||
addJvmInlineAnnotation(declaration)
|
||||
}
|
||||
|
||||
return declaration
|
||||
}
|
||||
|
||||
protected fun transformFunctionFlat(function: IrFunction): List<IrDeclaration>? {
|
||||
if (function is IrConstructor && function.isPrimary && function.constructedClass.isSpecificLoweringLogicApplicable()) {
|
||||
@@ -41,21 +79,7 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
}
|
||||
|
||||
val replacement = replacements.getReplacementFunction(function)
|
||||
|
||||
if (keepOldFunctionInsteadOfNew(function)) {
|
||||
function.transformChildrenVoid()
|
||||
addBindingsFor(function, replacement!!)
|
||||
return null
|
||||
}
|
||||
|
||||
if (replacement == null) {
|
||||
if (function is IrConstructor) {
|
||||
val constructorReplacement = replacements.getReplacementForRegularClassConstructor(function)
|
||||
if (constructorReplacement != null) {
|
||||
addBindingsFor(function, constructorReplacement)
|
||||
return transformFlattenedConstructor(function, constructorReplacement)
|
||||
}
|
||||
}
|
||||
function.transformChildrenVoid()
|
||||
// Non-mangled functions can override mangled functions under some conditions, e.g., a function
|
||||
// `fun f(): Nothing` can override a function `fun f(): UInt`. The former is not mangled, while
|
||||
@@ -82,50 +106,30 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
addBindingsFor(function, replacement)
|
||||
return when (function) {
|
||||
is IrSimpleFunction -> transformSimpleFunctionFlat(function, replacement)
|
||||
is IrConstructor -> transformSecondaryConstructorFlat(function, replacement)
|
||||
is IrConstructor -> transformConstructorFlat(function, replacement)
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformFlattenedConstructor(function: IrConstructor, replacement: IrConstructor): List<IrDeclaration>? {
|
||||
replacement.valueParameters.forEach {
|
||||
it.transformChildrenVoid()
|
||||
it.defaultValue?.patchDeclarationParents(replacement)
|
||||
}
|
||||
allScopes.push(createScope(function))
|
||||
replacement.body = function.body?.transform(this, null)?.patchDeclarationParents(replacement)
|
||||
allScopes.pop()
|
||||
return listOf(replacement)
|
||||
}
|
||||
|
||||
private fun IrFunction.hashSuffix(): String? = InlineClassAbi.hashSuffix(
|
||||
this,
|
||||
context.state.functionsWithInlineClassReturnTypesMangled,
|
||||
context.state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures
|
||||
)
|
||||
|
||||
protected abstract fun transformSecondaryConstructorFlat(constructor: IrConstructor, replacement: IrSimpleFunction): List<IrDeclaration>
|
||||
protected abstract fun transformConstructorFlat(constructor: IrConstructor, replacement: IrSimpleFunction): List<IrDeclaration>
|
||||
|
||||
private fun transformSimpleFunctionFlat(function: IrSimpleFunction, replacement: IrSimpleFunction): List<IrDeclaration> {
|
||||
replacement.valueParameters.forEach {
|
||||
it.transformChildrenVoid()
|
||||
it.defaultValue?.patchDeclarationParents(replacement)
|
||||
}
|
||||
allScopes.push(createScope(replacement))
|
||||
replacement.body = function.body?.transform(this, null)?.patchDeclarationParents(replacement)
|
||||
allScopes.pop()
|
||||
replacement.copyAttributes(function)
|
||||
protected abstract fun transformSimpleFunctionFlat(function: IrSimpleFunction, replacement: IrSimpleFunction): List<IrDeclaration>
|
||||
|
||||
// Don't create a wrapper for functions which are only used in an unboxed context
|
||||
if (function.overriddenSymbols.isEmpty() || replacement.dispatchReceiverParameter != null)
|
||||
return listOf(replacement)
|
||||
protected abstract fun buildPrimaryValueClassConstructor(valueClass: IrClass, irConstructor: IrConstructor)
|
||||
|
||||
val bridgeFunction = createBridgeFunction(function, replacement)
|
||||
protected abstract fun buildBoxFunction(valueClass: IrClass)
|
||||
|
||||
return listOf(replacement, bridgeFunction)
|
||||
}
|
||||
protected abstract fun buildUnboxFunctions(valueClass: IrClass)
|
||||
|
||||
abstract fun keepOldFunctionInsteadOfNew(function: IrFunction): Boolean
|
||||
protected abstract fun buildSpecializedEqualsMethod(valueClass: IrClass) // todo hashCode
|
||||
|
||||
protected abstract fun addJvmInlineAnnotation(valueClass: IrClass)
|
||||
|
||||
final override fun visitReturn(expression: IrReturn): IrExpression {
|
||||
expression.returnTargetSymbol.owner.safeAs<IrFunction>()?.let { target ->
|
||||
@@ -133,10 +137,7 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
if (suffix != null && target.name.asString().endsWith(suffix))
|
||||
return super.visitReturn(expression)
|
||||
|
||||
replacements.run {
|
||||
if (keepOldFunctionInsteadOfNew(target)) return@run null
|
||||
getReplacementFunction(target) ?: if (target is IrConstructor) getReplacementForRegularClassConstructor(target) else null
|
||||
}?.let {
|
||||
replacements.getReplacementFunction(target)?.let {
|
||||
return context.createIrBuilder(it.symbol, expression.startOffset, expression.endOffset).irReturn(
|
||||
expression.value.transform(this, null)
|
||||
)
|
||||
@@ -171,65 +172,4 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
else
|
||||
super.visitAnonymousInitializerNew(declaration)
|
||||
|
||||
protected abstract fun addBindingsFor(original: IrFunction, replacement: IrFunction)
|
||||
|
||||
protected enum class SpecificMangle { Inline, MultiField }
|
||||
|
||||
protected abstract val specificMangle: SpecificMangle
|
||||
private fun createBridgeFunction(
|
||||
function: IrSimpleFunction,
|
||||
replacement: IrSimpleFunction
|
||||
): IrSimpleFunction {
|
||||
val bridgeFunction = createBridgeDeclaration(
|
||||
function,
|
||||
replacement,
|
||||
when {
|
||||
// If the original function has signature which need mangling we still need to replace it with a mangled version.
|
||||
(!function.isFakeOverride || function.findInterfaceImplementation(context.state.jvmDefaultMode) != null) && when (specificMangle) {
|
||||
SpecificMangle.Inline -> function.signatureRequiresMangling(includeInline = true, includeMFVC = false)
|
||||
SpecificMangle.MultiField -> function.signatureRequiresMangling(includeInline = false, includeMFVC = true)
|
||||
} -> replacement.name
|
||||
// Since we remove the corresponding property symbol from the bridge we need to resolve getter/setter
|
||||
// names at this point.
|
||||
replacement.isGetter ->
|
||||
Name.identifier(JvmAbi.getterName(replacement.correspondingPropertySymbol!!.owner.name.asString()))
|
||||
|
||||
replacement.isSetter ->
|
||||
Name.identifier(JvmAbi.setterName(replacement.correspondingPropertySymbol!!.owner.name.asString()))
|
||||
|
||||
else ->
|
||||
function.name
|
||||
}
|
||||
)
|
||||
|
||||
// Update the overridden symbols to point to their inline class replacements
|
||||
bridgeFunction.overriddenSymbols = replacement.overriddenSymbols
|
||||
|
||||
// Replace the function body with a wrapper
|
||||
if (bridgeFunction.isFakeOverride && bridgeFunction.parentAsClass.isSpecificLoweringLogicApplicable()) {
|
||||
// Fake overrides redirect from the replacement to the original function, which is in turn replaced during interfacePhase.
|
||||
createBridgeBody(replacement, bridgeFunction, function, true)
|
||||
} else {
|
||||
createBridgeBody(bridgeFunction, replacement, function, false)
|
||||
}
|
||||
return bridgeFunction
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.signatureRequiresMangling(includeInline: Boolean = true, includeMFVC: Boolean = true) =
|
||||
fullValueParameterList.any { it.type.getRequiresMangling(includeInline, includeMFVC) } ||
|
||||
context.state.functionsWithInlineClassReturnTypesMangled &&
|
||||
returnType.getRequiresMangling(includeInline = includeInline, includeMFVC = false)
|
||||
|
||||
protected fun typedArgumentList(function: IrFunction, expression: IrMemberAccessExpression<*>) = listOfNotNull(
|
||||
function.dispatchReceiverParameter?.let { it to expression.dispatchReceiver },
|
||||
function.extensionReceiverParameter?.let { it to expression.extensionReceiver }
|
||||
) + function.valueParameters.map { it to expression.getValueArgument(it.index) }
|
||||
|
||||
|
||||
// We may need to add a bridge method for inline class methods with static replacements. Ideally, we'd do this in BridgeLowering,
|
||||
// but unfortunately this is a special case in the old backend. The bridge method is not marked as such and does not follow the normal
|
||||
// visibility rules for bridge methods.
|
||||
abstract fun createBridgeDeclaration(source: IrSimpleFunction, replacement: IrSimpleFunction, mangledName: Name): IrSimpleFunction
|
||||
|
||||
protected abstract fun createBridgeBody(source: IrSimpleFunction, target: IrSimpleFunction, original: IrFunction, inverted: Boolean)
|
||||
}
|
||||
+1
-1
@@ -370,7 +370,7 @@ private class SyntheticAccessorTransformer(
|
||||
|
||||
val constructedClass = constructedClass
|
||||
|
||||
if (!DescriptorVisibilities.isPrivate(visibility) && !constructedClass.isValue && hasMangledParameters() &&
|
||||
if (!DescriptorVisibilities.isPrivate(visibility) && !constructedClass.isSingleFieldValueClass && hasMangledParameters &&
|
||||
!constructedClass.isAnonymousObject
|
||||
) return true
|
||||
|
||||
|
||||
@@ -60,14 +60,14 @@ object InlineClassAbi {
|
||||
fun mangledNameFor(irFunction: IrFunction, mangleReturnTypes: Boolean, useOldMangleRules: Boolean): Name {
|
||||
if (irFunction is IrConstructor) {
|
||||
// Note that we might drop this convention and use standard mangling for constructors too, see KT-37186.
|
||||
assert(irFunction.constructedClass.isValue) {
|
||||
assert(irFunction.constructedClass.isSingleFieldValueClass) {
|
||||
"Should not mangle names of non-inline class constructors: ${irFunction.render()}"
|
||||
}
|
||||
return Name.identifier("constructor-impl")
|
||||
}
|
||||
|
||||
val suffix = hashSuffix(irFunction, mangleReturnTypes, useOldMangleRules)
|
||||
if (suffix == null && ((irFunction.parent as? IrClass)?.isValue != true || irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB)) {
|
||||
if (suffix == null && ((irFunction.parent as? IrClass)?.isSingleFieldValueClass != true || irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB)) {
|
||||
return irFunction.name
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ object InlineClassAbi {
|
||||
): String? =
|
||||
collectFunctionSignatureForManglingSuffix(
|
||||
useOldMangleRules,
|
||||
valueParameters.any { it.getRequiresMangling() },
|
||||
valueParameters.any { it.requiresMangling },
|
||||
// The JVM backend computes mangled names after creating suspend function views, but before default argument
|
||||
// stub insertion. It would be nice if this part of the continuation lowering happened earlier in the pipeline.
|
||||
// TODO: Move suspend function view creation before JvmInlineClassLowering.
|
||||
@@ -124,28 +124,19 @@ object InlineClassAbi {
|
||||
get() = (this as IrSimpleFunction).correspondingPropertySymbol!!.owner.name
|
||||
}
|
||||
|
||||
fun IrType.getRequiresMangling(includeInline: Boolean = true, includeMFVC: Boolean = true): Boolean {
|
||||
val irClass = erasedUpperBound
|
||||
return irClass.fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME && when {
|
||||
irClass.isSingleFieldValueClass -> includeInline
|
||||
irClass.isMultiFieldValueClass -> includeMFVC
|
||||
else -> false
|
||||
val IrType.requiresMangling: Boolean
|
||||
get() {
|
||||
val irClass = erasedUpperBound
|
||||
return irClass.isSingleFieldValueClass && irClass.fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME
|
||||
}
|
||||
}
|
||||
|
||||
val IrFunction.fullValueParameterList: List<IrValueParameter>
|
||||
get() = listOfNotNull(extensionReceiverParameter) + valueParameters
|
||||
|
||||
fun IrFunction.hasMangledParameters(includeInline: Boolean = true, includeMFVC: Boolean = true): Boolean =
|
||||
(dispatchReceiverParameter != null && when {
|
||||
parentAsClass.isSingleFieldValueClass -> includeInline
|
||||
parentAsClass.isMultiFieldValueClass -> includeMFVC
|
||||
else -> false
|
||||
}) || fullValueParameterList.any { it.type.getRequiresMangling(includeInline, includeMFVC) } || (this is IrConstructor && when {
|
||||
constructedClass.isSingleFieldValueClass -> includeInline
|
||||
constructedClass.isMultiFieldValueClass -> includeMFVC
|
||||
else -> false
|
||||
})
|
||||
val IrFunction.hasMangledParameters: Boolean
|
||||
get() = dispatchReceiverParameter != null && parentAsClass.isSingleFieldValueClass ||
|
||||
fullValueParameterList.any { it.type.requiresMangling } ||
|
||||
(this is IrConstructor && constructedClass.isSingleFieldValueClass)
|
||||
|
||||
val IrFunction.hasMangledReturnType: Boolean
|
||||
get() = returnType.isInlineClassType() && parentClassOrNull?.isFileClass != true
|
||||
@@ -155,12 +146,10 @@ 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()}")
|
||||
|
||||
@@ -143,8 +143,7 @@ class JvmBackendContext(
|
||||
|
||||
val inlineClassReplacements = MemoizedInlineClassReplacements(state.functionsWithInlineClassReturnTypesMangled, irFactory, this)
|
||||
|
||||
val multiFieldValueClassReplacements =
|
||||
MemoizedMultiFieldValueClassReplacements(irFactory, this)
|
||||
val multiFieldValueClassReplacements = MemoizedMultiFieldValueClassReplacements(irFactory, this)
|
||||
|
||||
val continuationClassesVarsCountByType: MutableMap<IrAttributeContainer, Map<Type, Int>> = hashMapOf()
|
||||
|
||||
@@ -198,20 +197,6 @@ class JvmBackendContext(
|
||||
multifileFacade.setValue(newPartClasses.toMutableList())
|
||||
}
|
||||
|
||||
for ((staticReplacement, original) in multiFieldValueClassReplacements.originalFunctionForStaticReplacement) {
|
||||
if (staticReplacement !is IrSimpleFunction) continue
|
||||
val newOriginal = functionSymbolMap[original.symbol]?.owner ?: continue
|
||||
val newStaticReplacement = multiFieldValueClassReplacements.getReplacementFunction(newOriginal) ?: continue
|
||||
functionSymbolMap[staticReplacement.symbol] = newStaticReplacement.symbol
|
||||
}
|
||||
|
||||
for ((methodReplacement, original) in multiFieldValueClassReplacements.originalFunctionForMethodReplacement) {
|
||||
if (methodReplacement !is IrSimpleFunction) continue
|
||||
val newOriginal = functionSymbolMap[original.symbol]?.owner ?: continue
|
||||
val newMethodReplacement = multiFieldValueClassReplacements.getReplacementFunction(newOriginal) ?: continue
|
||||
functionSymbolMap[methodReplacement.symbol] = newMethodReplacement.symbol
|
||||
}
|
||||
|
||||
for ((staticReplacement, original) in inlineClassReplacements.originalFunctionForStaticReplacement) {
|
||||
if (staticReplacement !is IrSimpleFunction) continue
|
||||
val newOriginal = functionSymbolMap[original.symbol]?.owner ?: continue
|
||||
|
||||
+1
-4
@@ -251,8 +251,7 @@ class JvmCachedDeclarations(
|
||||
defaultImplsRedirections.getOrPut(fakeOverride) {
|
||||
assert(fakeOverride.isFakeOverride)
|
||||
val irClass = fakeOverride.parentAsClass
|
||||
val mfvcReplacementStructure = context.multiFieldValueClassReplacements.bindingNewFunctionToParameterTemplateStructure
|
||||
val redirectFunction = context.irFactory.buildFun {
|
||||
context.irFactory.buildFun {
|
||||
origin = JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE
|
||||
name = fakeOverride.name
|
||||
visibility = fakeOverride.visibility
|
||||
@@ -276,8 +275,6 @@ class JvmCachedDeclarations(
|
||||
annotations = fakeOverride.annotations
|
||||
copyCorrespondingPropertyFrom(fakeOverride)
|
||||
}
|
||||
mfvcReplacementStructure[fakeOverride]?.let { mfvcReplacementStructure[redirectFunction] = it }
|
||||
redirectFunction
|
||||
}
|
||||
|
||||
fun getRepeatedAnnotationSyntheticContainer(annotationClass: IrClass): IrClass =
|
||||
|
||||
-5
@@ -29,14 +29,9 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object ENUM_MAPPINGS_FOR_WHEN : IrDeclarationOriginImpl("ENUM_MAPPINGS_FOR_WHEN", isSynthetic = true)
|
||||
object ENUM_MAPPINGS_FOR_ENTRIES : IrDeclarationOriginImpl("ENUM_MAPPINGS_FOR_ENTRIES", isSynthetic = true)
|
||||
object SYNTHETIC_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("SYNTHETIC_INLINE_CLASS_MEMBER", isSynthetic = true)
|
||||
object SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER :
|
||||
IrDeclarationOriginImpl("SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER", isSynthetic = true)
|
||||
object INLINE_CLASS_GENERATED_IMPL_METHOD : IrDeclarationOriginImpl("INLINE_CLASS_GENERATED_IMPL_METHOD")
|
||||
object MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD : IrDeclarationOriginImpl("MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD")
|
||||
object STATIC_INLINE_CLASS_REPLACEMENT : IrDeclarationOriginImpl("STATIC_INLINE_CLASS_REPLACEMENT")
|
||||
object STATIC_MULTI_FIELD_VALUE_CLASS_REPLACEMENT : IrDeclarationOriginImpl("STATIC_MULTI_FIELD_VALUE_CLASS_REPLACEMENT")
|
||||
object STATIC_INLINE_CLASS_CONSTRUCTOR : IrDeclarationOriginImpl("STATIC_INLINE_CLASS_CONSTRUCTOR")
|
||||
object STATIC_MULTI_FIELD_VALUE_CLASS_CONSTRUCTOR : IrDeclarationOriginImpl("STATIC_MULTI_FIELD_VALUE_CLASS_CONSTRUCTOR")
|
||||
object GENERATED_ASSERTION_ENABLED_FIELD : IrDeclarationOriginImpl("GENERATED_ASSERTION_ENABLED_FIELD", isSynthetic = true)
|
||||
object GENERATED_EXTENDED_MAIN : IrDeclarationOriginImpl("GENERATED_EXTENDED_MAIN", isSynthetic = true)
|
||||
object SUSPEND_IMPL_STATIC_FUNCTION : IrDeclarationOriginImpl("SUSPEND_IMPL_STATIC_FUNCTION", isSynthetic = true)
|
||||
|
||||
+87
-29
@@ -5,26 +5,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.classFileContainsMethod
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.extensionReceiverName
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isStaticValueClassReplacement
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.parentClassId
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.isInt
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.alwaysNull
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/**
|
||||
@@ -36,9 +35,10 @@ class MemoizedInlineClassReplacements(
|
||||
context: JvmBackendContext
|
||||
) : MemoizedValueClassAbstractReplacements(irFactory, context) {
|
||||
private val storageManager = LockBasedStorageManager("inline-class-replacements")
|
||||
private val propertyMap = ConcurrentHashMap<IrPropertySymbol, IrProperty>()
|
||||
|
||||
val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
val originalFunctionForMethodReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
override val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
internal val originalFunctionForMethodReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
|
||||
/**
|
||||
* Get a replacement for a function or a constructor.
|
||||
@@ -49,9 +49,7 @@ class MemoizedInlineClassReplacements(
|
||||
// Don't mangle anonymous or synthetic functions, except for generated SAM wrapper methods
|
||||
(it.isLocal && it is IrSimpleFunction && it.overriddenSymbols.isEmpty()) ||
|
||||
(it.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR && it.visibility == DescriptorVisibilities.LOCAL) ||
|
||||
it.isStaticValueClassReplacement ||
|
||||
it in context.multiFieldValueClassReplacements.bindingNewFunctionToParameterTemplateStructure ||
|
||||
it.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
it.isStaticInlineClassReplacement ||
|
||||
it.origin.isSynthetic && it.origin != IrDeclarationOrigin.SYNTHETIC_GENERATED_SAM_IMPLEMENTATION ->
|
||||
null
|
||||
|
||||
@@ -66,7 +64,7 @@ class MemoizedInlineClassReplacements(
|
||||
when {
|
||||
it.isRemoveAtSpecialBuiltinStub() ->
|
||||
null
|
||||
it.isValueClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod() ||
|
||||
it.isInlineClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod() ||
|
||||
it.origin == IrDeclarationOrigin.IR_BUILTINS_STUB ->
|
||||
createMethodReplacement(it)
|
||||
else ->
|
||||
@@ -74,8 +72,7 @@ class MemoizedInlineClassReplacements(
|
||||
}
|
||||
|
||||
// Otherwise, mangle functions with mangled parameters, ignoring constructors
|
||||
it is IrSimpleFunction && !it.isFromJava() &&
|
||||
(it.hasMangledParameters(includeMFVC = false) || mangleReturnTypes && it.hasMangledReturnType) ->
|
||||
it is IrSimpleFunction && !it.isFromJava() && (it.hasMangledParameters || mangleReturnTypes && it.hasMangledReturnType) ->
|
||||
createMethodReplacement(it)
|
||||
|
||||
else ->
|
||||
@@ -83,6 +80,29 @@ class MemoizedInlineClassReplacements(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrFunction.isRemoveAtSpecialBuiltinStub() =
|
||||
origin == IrDeclarationOrigin.IR_BUILTINS_STUB &&
|
||||
name.asString() == "remove" &&
|
||||
valueParameters.size == 1 &&
|
||||
valueParameters[0].type.isInt()
|
||||
|
||||
private fun IrFunction.isInlineClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod(): Boolean {
|
||||
if (this !is IrSimpleFunction) return false
|
||||
if (!this.isFakeOverride) return false
|
||||
val parentClass = parentClassOrNull ?: return false
|
||||
if (!parentClass.isSingleFieldValueClass) return false
|
||||
|
||||
val overridden = resolveFakeOverride() ?: return false
|
||||
if (!overridden.parentAsClass.isJvmInterface) return false
|
||||
if (overridden.modality == Modality.ABSTRACT) return false
|
||||
|
||||
// We have a non-abstract interface member.
|
||||
// It is a JVM default interface method if one of the following conditions are true:
|
||||
// - it is a Java method,
|
||||
// - it is a Kotlin function compiled to JVM default interface method.
|
||||
return overridden.isFromJava() || overridden.isCompiledToJvmDefault(context.state.jvmDefaultMode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the box function for an inline class. Concretely, this is a synthetic
|
||||
* static function named "box-impl" which takes an unboxed value and returns
|
||||
@@ -128,7 +148,7 @@ class MemoizedInlineClassReplacements(
|
||||
return specializedEqualsCache.computeIfAbsent(irClass) {
|
||||
irFactory.buildFun {
|
||||
name = InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME
|
||||
// TODO: Revisit this once we allow user defined equals methods in inline/multi-field value classes.
|
||||
// TODO: Revisit this once we allow user defined equals methods in inline classes.
|
||||
origin = JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD
|
||||
returnType = irBuiltIns.booleanType
|
||||
}.apply {
|
||||
@@ -148,7 +168,7 @@ class MemoizedInlineClassReplacements(
|
||||
}
|
||||
}
|
||||
|
||||
override fun createMethodReplacement(function: IrFunction): IrSimpleFunction =
|
||||
private fun createMethodReplacement(function: IrFunction): IrSimpleFunction =
|
||||
buildReplacement(function, function.origin) {
|
||||
originalFunctionForMethodReplacement[this] = function
|
||||
dispatchReceiverParameter = function.dispatchReceiverParameter?.copyTo(this, index = -1)
|
||||
@@ -164,14 +184,9 @@ class MemoizedInlineClassReplacements(
|
||||
it.defaultValue = parameter.defaultValue?.patchDeclarationParents(this)
|
||||
}
|
||||
}
|
||||
context.multiFieldValueClassReplacements.run {
|
||||
bindingNewFunctionToParameterTemplateStructure[function]?.also {
|
||||
bindingNewFunctionToParameterTemplateStructure[this@buildReplacement] = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createStaticReplacement(function: IrFunction): IrSimpleFunction =
|
||||
private fun createStaticReplacement(function: IrFunction): IrSimpleFunction =
|
||||
buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT, noFakeOverride = true) {
|
||||
originalFunctionForStaticReplacement[this] = function
|
||||
|
||||
@@ -204,11 +219,6 @@ class MemoizedInlineClassReplacements(
|
||||
}
|
||||
}
|
||||
valueParameters = newValueParameters
|
||||
context.multiFieldValueClassReplacements.run {
|
||||
bindingNewFunctionToParameterTemplateStructure[function]?.also {
|
||||
bindingNewFunctionToParameterTemplateStructure[this@buildReplacement] = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildReplacement(
|
||||
@@ -236,7 +246,8 @@ class MemoizedInlineClassReplacements(
|
||||
noFakeOverride: Boolean,
|
||||
useOldManglingScheme: Boolean,
|
||||
body: IrFunction.() -> Unit,
|
||||
): IrSimpleFunction = commonBuildReplacementInner(function, noFakeOverride, body) {
|
||||
): IrSimpleFunction = irFactory.buildFun {
|
||||
updateFrom(function)
|
||||
if (function is IrConstructor) {
|
||||
// The [updateFrom] call will set the modality to FINAL for constructors, while the JVM backend would use OPEN here.
|
||||
modality = Modality.OPEN
|
||||
@@ -249,10 +260,52 @@ class MemoizedInlineClassReplacements(
|
||||
else ->
|
||||
replacementOrigin
|
||||
}
|
||||
if (noFakeOverride) {
|
||||
isFakeOverride = false
|
||||
}
|
||||
name = InlineClassAbi.mangledNameFor(function, mangleReturnTypes, useOldManglingScheme)
|
||||
}
|
||||
returnType = function.returnType
|
||||
}.apply {
|
||||
parent = function.parent
|
||||
annotations = function.annotations
|
||||
copyTypeParameters(function.allTypeParameters)
|
||||
if (function.metadata != null) {
|
||||
metadata = function.metadata
|
||||
function.metadata = null
|
||||
}
|
||||
copyAttributes(function as? IrAttributeContainer)
|
||||
|
||||
override val getReplacementForRegularClassConstructor: (IrConstructor) -> IrConstructor? = alwaysNull()
|
||||
if (function is IrSimpleFunction) {
|
||||
val propertySymbol = function.correspondingPropertySymbol
|
||||
if (propertySymbol != null) {
|
||||
val property = propertyMap.getOrPut(propertySymbol) {
|
||||
irFactory.buildProperty {
|
||||
name = propertySymbol.owner.name
|
||||
updateFrom(propertySymbol.owner)
|
||||
}.apply {
|
||||
parent = propertySymbol.owner.parent
|
||||
copyAttributes(propertySymbol.owner)
|
||||
annotations = propertySymbol.owner.annotations
|
||||
// In case this property is declared in an object in another file which is not yet lowered, its backing field will
|
||||
// be made static later. We have to handle it here though, because this new property will be saved to the cache
|
||||
// and reused when lowering the same call in all subsequent files, which would be incorrect if it was unlowered.
|
||||
backingField = context.cachedDeclarations.getStaticBackingField(propertySymbol.owner)
|
||||
?: propertySymbol.owner.backingField
|
||||
}
|
||||
}
|
||||
correspondingPropertySymbol = property.symbol
|
||||
when (function) {
|
||||
propertySymbol.owner.getter -> property.getter = this
|
||||
propertySymbol.owner.setter -> property.setter = this
|
||||
else -> error("Orphaned property getter/setter: ${function.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
overriddenSymbols = replaceOverriddenSymbols(function)
|
||||
}
|
||||
|
||||
body()
|
||||
}
|
||||
|
||||
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> =
|
||||
storageManager.createMemoizedFunction { irSimpleFunction ->
|
||||
@@ -260,4 +313,9 @@ class MemoizedInlineClassReplacements(
|
||||
computeOverrideReplacement(it.owner).symbol
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeOverrideReplacement(function: IrSimpleFunction): IrSimpleFunction =
|
||||
getReplacementFunction(function) ?: function.also {
|
||||
function.overriddenSymbols = replaceOverriddenSymbols(function)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-287
@@ -5,24 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.MultiFieldValueClassMapping
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.extensionReceiverName
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.findSuperDeclaration
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isStaticValueClassReplacement
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/**
|
||||
@@ -34,281 +21,17 @@ class MemoizedMultiFieldValueClassReplacements(
|
||||
) : MemoizedValueClassAbstractReplacements(irFactory, context) {
|
||||
private val storageManager = LockBasedStorageManager("multi-field-value-class-replacements")
|
||||
|
||||
val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
val originalFunctionForMethodReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
private val originalConstructorForConstructorReplacement: MutableMap<IrConstructor, IrConstructor> = ConcurrentHashMap()
|
||||
|
||||
private fun IrValueParameter.grouped(
|
||||
name: String?,
|
||||
substitutionMap: Map<IrTypeParameterSymbol, IrType>,
|
||||
targetFunction: IrFunction,
|
||||
originWhenFlattened: IrDeclarationOrigin,
|
||||
): RemappedParameter {
|
||||
if (!type.needsMfvcFlattening()) return RemappedParameter.RegularMapping(
|
||||
targetFunction.addValueParameter {
|
||||
updateFrom(this@grouped)
|
||||
this.name = this@grouped.name
|
||||
index = targetFunction.valueParameters.size
|
||||
}.apply {
|
||||
copyAnnotationsFrom(this@grouped)
|
||||
}
|
||||
)
|
||||
val rootMfvcNode = this@MemoizedMultiFieldValueClassReplacements.getRootMfvcNode(type.erasedUpperBound)!!
|
||||
require(!hasDefaultValue()) { "Default parameters values are not supported for multi-field value classes" }
|
||||
val newType = type.substitute(substitutionMap) as IrSimpleType
|
||||
val localSubstitutionMap = makeTypeArgumentsFromType(newType)
|
||||
val valueParameters = rootMfvcNode.mapLeaves { leaf ->
|
||||
targetFunction.addValueParameter {
|
||||
updateFrom(this@grouped)
|
||||
this.name = Name.identifier("${name ?: this@grouped.name}-${leaf.fullFieldName}")
|
||||
type = leaf.type.substitute(localSubstitutionMap)
|
||||
origin = originWhenFlattened
|
||||
index = targetFunction.valueParameters.size
|
||||
}.apply {
|
||||
defaultValue = null
|
||||
copyAnnotationsFrom(this@grouped)
|
||||
}
|
||||
}
|
||||
return MultiFieldValueClassMapping(rootMfvcNode, newType, valueParameters)
|
||||
}
|
||||
|
||||
private fun List<IrValueParameter>.grouped(
|
||||
name: String?,
|
||||
substitutionMap: Map<IrTypeParameterSymbol, IrType>,
|
||||
targetFunction: IrFunction,
|
||||
originWhenFlattened: IrDeclarationOrigin,
|
||||
): List<RemappedParameter> = map { it.grouped(name, substitutionMap, targetFunction, originWhenFlattened) }
|
||||
|
||||
private fun buildReplacement(
|
||||
function: IrFunction,
|
||||
replacementOrigin: IrDeclarationOrigin,
|
||||
noFakeOverride: Boolean = false,
|
||||
body: IrFunction.() -> Unit,
|
||||
): IrSimpleFunction = commonBuildReplacementInner(function, noFakeOverride, body) {
|
||||
origin = when {
|
||||
function.origin == IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER ->
|
||||
JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD
|
||||
|
||||
function is IrConstructor && function.constructedClass.isMultiFieldValueClass ->
|
||||
JvmLoweredDeclarationOrigin.STATIC_MULTI_FIELD_VALUE_CLASS_CONSTRUCTOR
|
||||
|
||||
else -> replacementOrigin
|
||||
}
|
||||
name = InlineClassAbi.mangledNameFor(function, mangleReturnTypes = false, useOldMangleRules = false)
|
||||
}
|
||||
|
||||
private fun makeAndAddGroupedValueParametersFrom(
|
||||
sourceFunction: IrFunction,
|
||||
includeDispatcherReceiver: Boolean,
|
||||
substitutionMap: Map<IrTypeParameterSymbol, IrType>,
|
||||
targetFunction: IrFunction,
|
||||
): List<RemappedParameter> {
|
||||
val newFlattenedParameters = mutableListOf<RemappedParameter>()
|
||||
if (sourceFunction.dispatchReceiverParameter != null && includeDispatcherReceiver) {
|
||||
newFlattenedParameters.add(
|
||||
sourceFunction.parentAsClass.thisReceiver!!.grouped(
|
||||
"\$dispatchReceiver",
|
||||
substitutionMap,
|
||||
targetFunction,
|
||||
IrDeclarationOrigin.MOVED_DISPATCH_RECEIVER,
|
||||
)
|
||||
)
|
||||
}
|
||||
val contextReceivers = sourceFunction.valueParameters.take(sourceFunction.contextReceiverParametersCount)
|
||||
.mapIndexed { index: Int, valueParameter: IrValueParameter ->
|
||||
valueParameter.grouped(
|
||||
"contextReceiver$index",
|
||||
substitutionMap,
|
||||
targetFunction,
|
||||
IrDeclarationOrigin.MOVED_CONTEXT_RECEIVER,
|
||||
)
|
||||
}
|
||||
newFlattenedParameters.addAll(contextReceivers)
|
||||
sourceFunction.extensionReceiverParameter?.let {
|
||||
val newParameters = it.grouped(
|
||||
sourceFunction.extensionReceiverName(context.state),
|
||||
substitutionMap,
|
||||
targetFunction,
|
||||
IrDeclarationOrigin.MOVED_EXTENSION_RECEIVER,
|
||||
)
|
||||
newFlattenedParameters.add(newParameters)
|
||||
}
|
||||
newFlattenedParameters += sourceFunction.valueParameters.drop(sourceFunction.contextReceiverParametersCount)
|
||||
.grouped(name = null, substitutionMap, targetFunction, IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_PARAMETER)
|
||||
return newFlattenedParameters
|
||||
}
|
||||
|
||||
sealed class RemappedParameter {
|
||||
|
||||
abstract val valueParameters: List<IrValueParameter>
|
||||
|
||||
data class RegularMapping(val valueParameter: IrValueParameter) : RemappedParameter() {
|
||||
override val valueParameters: List<IrValueParameter> = listOf(valueParameter)
|
||||
}
|
||||
|
||||
data class MultiFieldValueClassMapping(
|
||||
val rootMfvcNode: RootMfvcNode,
|
||||
val typeArguments: TypeArguments,
|
||||
override val valueParameters: List<IrValueParameter>,
|
||||
) : RemappedParameter() {
|
||||
init {
|
||||
require(valueParameters.size > 1) { "MFVC must have > 1 fields" }
|
||||
}
|
||||
|
||||
constructor(rootMfvcNode: RootMfvcNode, type: IrSimpleType, valueParameters: List<IrValueParameter>) :
|
||||
this(rootMfvcNode, makeTypeArgumentsFromType(type), valueParameters)
|
||||
|
||||
val boxedType: IrSimpleType = rootMfvcNode.type.substitute(typeArguments) as IrSimpleType
|
||||
}
|
||||
}
|
||||
|
||||
val bindingOldFunctionToParameterTemplateStructure: MutableMap<IrFunction, List<RemappedParameter>> = ConcurrentHashMap()
|
||||
val bindingNewFunctionToParameterTemplateStructure: MutableMap<IrFunction, List<RemappedParameter>> =
|
||||
object : ConcurrentHashMap<IrFunction, List<RemappedParameter>>() {
|
||||
override fun put(key: IrFunction, value: List<RemappedParameter>): List<RemappedParameter>? {
|
||||
require(key.explicitParametersCount == value.sumOf { it.valueParameters.size }) {
|
||||
"Illegal structure $value for function ${key.dump()}"
|
||||
}
|
||||
return super.put(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createStaticReplacement(function: IrFunction): IrSimpleFunction =
|
||||
buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_MULTI_FIELD_VALUE_CLASS_REPLACEMENT, noFakeOverride = true) {
|
||||
originalFunctionForStaticReplacement[this] = function
|
||||
typeParameters = listOf()
|
||||
copyTypeParametersFrom(function.parentAsClass)
|
||||
val substitutionMap = function.parentAsClass.typeParameters.map { it.symbol }.zip(typeParameters.map { it.defaultType }).toMap()
|
||||
copyTypeParametersFrom(function, parameterMap = (function.parentAsClass.typeParameters zip typeParameters).toMap())
|
||||
val newFlattenedParameters =
|
||||
makeAndAddGroupedValueParametersFrom(function, includeDispatcherReceiver = true, substitutionMap, this)
|
||||
bindingOldFunctionToParameterTemplateStructure[function] = newFlattenedParameters
|
||||
bindingNewFunctionToParameterTemplateStructure[this] = newFlattenedParameters
|
||||
}
|
||||
|
||||
override fun createMethodReplacement(function: IrFunction): IrSimpleFunction = buildReplacement(function, function.origin) {
|
||||
originalFunctionForMethodReplacement[this] = function
|
||||
dispatchReceiverParameter = function.dispatchReceiverParameter?.copyTo(this, index = -1)
|
||||
val newFlattenedParameters = makeAndAddGroupedValueParametersFrom(function, includeDispatcherReceiver = false, mapOf(), this)
|
||||
val receiver = dispatchReceiverParameter
|
||||
val remappedParameters =
|
||||
if (receiver != null) listOf(RemappedParameter.RegularMapping(receiver)) + newFlattenedParameters else newFlattenedParameters
|
||||
bindingOldFunctionToParameterTemplateStructure[function] = remappedParameters
|
||||
bindingNewFunctionToParameterTemplateStructure[this] = remappedParameters
|
||||
}
|
||||
|
||||
private fun createConstructorReplacement(constructor: IrConstructor): IrConstructor {
|
||||
val newConstructor = irFactory.buildConstructor {
|
||||
updateFrom(constructor)
|
||||
returnType = constructor.returnType
|
||||
}.apply {
|
||||
val newFlattenedParameters = makeAndAddGroupedValueParametersFrom(constructor, includeDispatcherReceiver = false, mapOf(), this)
|
||||
bindingOldFunctionToParameterTemplateStructure[constructor] = newFlattenedParameters
|
||||
parent = constructor.parent
|
||||
copyTypeParametersFrom(constructor)
|
||||
annotations = constructor.annotations
|
||||
originalConstructorForConstructorReplacement[this] = constructor
|
||||
bindingNewFunctionToParameterTemplateStructure[this] = newFlattenedParameters
|
||||
}
|
||||
return newConstructor
|
||||
}
|
||||
override val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
internal val originalFunctionForMethodReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
|
||||
|
||||
/**
|
||||
* Get a function replacement for a function or a constructor.
|
||||
* Get a replacement for a function or a constructor.
|
||||
*/
|
||||
override val getReplacementFunction: (IrFunction) -> IrSimpleFunction? =
|
||||
storageManager.createMemoizedFunctionWithNullableValues { function ->
|
||||
when {
|
||||
(function.isLocal && function is IrSimpleFunction && function.overriddenSymbols.isEmpty()) ||
|
||||
(function.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR && function.visibility == DescriptorVisibilities.LOCAL) ||
|
||||
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
|
||||
|
||||
// Do not check for overridden symbols because it makes previously overriding function not overriding would break a code.
|
||||
function.isMultiFieldValueClassFieldGetter -> makeMultiFieldValueClassFieldGetterReplacement(function)
|
||||
function.parent.safeAs<IrClass>()?.isMultiFieldValueClass == true -> when {
|
||||
function.isRemoveAtSpecialBuiltinStub() ->
|
||||
null
|
||||
|
||||
function.isValueClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod() ||
|
||||
function.origin == IrDeclarationOrigin.IR_BUILTINS_STUB ->
|
||||
createMethodReplacement(function)
|
||||
|
||||
else ->
|
||||
createStaticReplacement(function)
|
||||
}
|
||||
|
||||
function is IrSimpleFunction && !function.isFromJava() &&
|
||||
function.fullValueParameterList.any { it.type.needsMfvcFlattening() } &&
|
||||
(!function.isFakeOverride ||
|
||||
findSuperDeclaration(function, false, context.state.jvmDefaultMode)
|
||||
in bindingOldFunctionToParameterTemplateStructure) ->
|
||||
createMethodReplacement(function)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeMultiFieldValueClassFieldGetterReplacement(function: IrFunction): IrSimpleFunction {
|
||||
require(function is IrSimpleFunction && function.isMultiFieldValueClassFieldGetter) { "Illegal function:\n${function.dump()}" }
|
||||
val replacement = getMfvcPropertyNode(function.correspondingPropertySymbol!!.owner)!!.unboxMethod
|
||||
originalFunctionForMethodReplacement[replacement] = function
|
||||
val templateParameters = listOf(RemappedParameter.RegularMapping(replacement.dispatchReceiverParameter!!))
|
||||
bindingNewFunctionToParameterTemplateStructure[replacement] = templateParameters
|
||||
bindingOldFunctionToParameterTemplateStructure[function] = templateParameters
|
||||
return replacement
|
||||
override val getReplacementFunction: (IrFunction) -> IrSimpleFunction? = storageManager.createMemoizedFunctionWithNullableValues {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override val getReplacementForRegularClassConstructor: (IrConstructor) -> IrConstructor? =
|
||||
storageManager.createMemoizedFunctionWithNullableValues { constructor ->
|
||||
when {
|
||||
constructor.constructedClass.isMultiFieldValueClass -> null
|
||||
constructor.isFromJava() -> null
|
||||
constructor.fullValueParameterList.any { it.type.needsMfvcFlattening() } ->
|
||||
createConstructorReplacement(constructor)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> =
|
||||
storageManager.createMemoizedFunction { irSimpleFunction ->
|
||||
irSimpleFunction.overriddenSymbols.map {
|
||||
computeOverrideReplacement(it.owner).symbol
|
||||
}
|
||||
}
|
||||
|
||||
val getRootMfvcNode: (IrClass) -> RootMfvcNode? = storageManager.createMemoizedFunctionWithNullableValues {
|
||||
if (it.defaultType.needsMfvcFlattening()) getRootNode(context, it) else null
|
||||
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> = storageManager.createMemoizedFunction {
|
||||
TODO()
|
||||
}
|
||||
|
||||
val getRegularClassMfvcPropertyNode: (IrProperty) -> IntermediateMfvcNode? =
|
||||
storageManager.createMemoizedFunctionWithNullableValues { property: IrProperty ->
|
||||
val parent = property.parent
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
fun getMfvcPropertyNode(property: IrProperty): NameableMfvcNode? {
|
||||
val parent = property.parent
|
||||
return when {
|
||||
parent !is IrClass -> null
|
||||
useRootNode(parent, property) -> getRootMfvcNode(parent)!![property.name]
|
||||
else -> getRegularClassMfvcPropertyNode(property)
|
||||
}
|
||||
}
|
||||
|
||||
private fun useRootNode(
|
||||
parent: IrClass,
|
||||
property: IrProperty
|
||||
) = parent.isMultiFieldValueClass && (property.getter?.isStatic ?: property.backingField?.isStatic) == false
|
||||
}
|
||||
|
||||
+4
-99
@@ -5,113 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.IrFunctionBuilder
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.isInt
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: IrFactory, protected val context: JvmBackendContext) {
|
||||
private val propertyMap = ConcurrentHashMap<IrPropertySymbol, IrProperty>()
|
||||
|
||||
/**
|
||||
* Get a replacement for a function or a constructor.
|
||||
*/
|
||||
abstract val getReplacementFunction: (IrFunction) -> IrSimpleFunction?
|
||||
|
||||
protected fun IrFunction.isRemoveAtSpecialBuiltinStub() =
|
||||
origin == IrDeclarationOrigin.IR_BUILTINS_STUB &&
|
||||
name.asString() == "remove" &&
|
||||
valueParameters.size == 1 &&
|
||||
valueParameters[0].type.isInt()
|
||||
|
||||
protected fun IrFunction.isValueClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod(): Boolean {
|
||||
if (this !is IrSimpleFunction) return false
|
||||
if (!this.isFakeOverride) return false
|
||||
val parentClass = parentClassOrNull ?: return false
|
||||
require(parentClass.isValue)
|
||||
|
||||
val overridden = resolveFakeOverride() ?: return false
|
||||
if (!overridden.parentAsClass.isJvmInterface) return false
|
||||
if (overridden.modality == Modality.ABSTRACT) return false
|
||||
|
||||
// We have a non-abstract interface member.
|
||||
// It is a JVM default interface method if one of the following conditions are true:
|
||||
// - it is a Java method,
|
||||
// - it is a Kotlin function compiled to JVM default interface method.
|
||||
return overridden.isFromJava() || overridden.isCompiledToJvmDefault(context.state.jvmDefaultMode)
|
||||
}
|
||||
|
||||
protected abstract fun createStaticReplacement(function: IrFunction): IrSimpleFunction
|
||||
protected abstract fun createMethodReplacement(function: IrFunction): IrSimpleFunction
|
||||
|
||||
protected fun commonBuildReplacementInner(
|
||||
function: IrFunction,
|
||||
noFakeOverride: Boolean,
|
||||
body: IrFunction.() -> Unit,
|
||||
builderBody: IrFunctionBuilder.() -> Unit,
|
||||
): IrSimpleFunction = irFactory.buildFun {
|
||||
updateFrom(function)
|
||||
builderBody()
|
||||
if (noFakeOverride) {
|
||||
isFakeOverride = false
|
||||
}
|
||||
returnType = function.returnType
|
||||
}.apply {
|
||||
parent = function.parent
|
||||
annotations = function.annotations
|
||||
copyTypeParameters(function.allTypeParameters)
|
||||
if (function.metadata != null) {
|
||||
metadata = function.metadata
|
||||
function.metadata = null
|
||||
}
|
||||
copyAttributes(function as? IrAttributeContainer)
|
||||
|
||||
if (function is IrSimpleFunction) {
|
||||
val propertySymbol = function.correspondingPropertySymbol
|
||||
if (propertySymbol != null) {
|
||||
val property = propertyMap.getOrPut(propertySymbol) {
|
||||
irFactory.buildProperty {
|
||||
name = propertySymbol.owner.name
|
||||
updateFrom(propertySymbol.owner)
|
||||
}.apply {
|
||||
parent = propertySymbol.owner.parent
|
||||
copyAttributes(propertySymbol.owner)
|
||||
annotations = propertySymbol.owner.annotations
|
||||
// In case this property is declared in an object in another file which is not yet lowered, its backing field will
|
||||
// be made static later. We have to handle it here though, because this new property will be saved to the cache
|
||||
// and reused when lowering the same call in all subsequent files, which would be incorrect if it was unlowered.
|
||||
backingField = context.cachedDeclarations.getStaticBackingField(propertySymbol.owner)
|
||||
?: propertySymbol.owner.backingField
|
||||
}
|
||||
}
|
||||
correspondingPropertySymbol = property.symbol
|
||||
when (function) {
|
||||
propertySymbol.owner.getter -> property.getter = this
|
||||
propertySymbol.owner.setter -> property.setter = this
|
||||
else -> error("Orphaned property getter/setter: ${function.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
overriddenSymbols = replaceOverriddenSymbols(function)
|
||||
}
|
||||
|
||||
body()
|
||||
}
|
||||
abstract val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction>
|
||||
|
||||
abstract val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol>
|
||||
|
||||
abstract val getReplacementForRegularClassConstructor: (IrConstructor) -> IrConstructor?
|
||||
|
||||
protected fun computeOverrideReplacement(function: IrSimpleFunction): IrSimpleFunction =
|
||||
getReplacementFunction(function) ?: function.also {
|
||||
function.overriddenSymbols = replaceOverriddenSymbols(function)
|
||||
}
|
||||
}
|
||||
@@ -1,457 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isMultiFieldValueClassType
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.ir.builders.IrBlockBuilder
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetField
|
||||
import org.jetbrains.kotlin.ir.expressions.IrReturn
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
typealias TypeArguments = Map<IrTypeParameterSymbol, IrType>
|
||||
|
||||
sealed interface MfvcNode {
|
||||
val type: IrType
|
||||
val leavesCount: Int
|
||||
|
||||
fun createInstanceFromBox(
|
||||
scope: IrBlockBuilder,
|
||||
typeArguments: TypeArguments,
|
||||
receiver: IrExpression?,
|
||||
accessType: AccessType,
|
||||
saveVariable: (IrVariable) -> Unit,
|
||||
): ReceiverBasedMfvcNodeInstance
|
||||
}
|
||||
|
||||
fun MfvcNode.createInstanceFromBox(
|
||||
scope: IrBlockBuilder,
|
||||
receiver: IrExpression,
|
||||
accessType: AccessType,
|
||||
saveVariable: (IrVariable) -> Unit
|
||||
) =
|
||||
createInstanceFromBox(scope, makeTypeArgumentsFromType(receiver.type as IrSimpleType), receiver, accessType, saveVariable)
|
||||
|
||||
fun MfvcNode.createInstanceFromValueDeclarationsAndBoxType(
|
||||
scope: IrBuilderWithScope, type: IrSimpleType, name: Name, saveVariable: (IrVariable) -> Unit,
|
||||
): ValueDeclarationMfvcNodeInstance = createInstanceFromValueDeclarations(scope, makeTypeArgumentsFromType(type), name, saveVariable)
|
||||
|
||||
fun MfvcNode.createInstanceFromValueDeclarations(
|
||||
scope: IrBuilderWithScope, typeArguments: TypeArguments, name: Name, saveVariable: (IrVariable) -> Unit,
|
||||
): ValueDeclarationMfvcNodeInstance {
|
||||
val valueDeclarations = mapLeaves {
|
||||
scope.savableStandaloneVariable(
|
||||
type = it.type,
|
||||
name = listOf(name, it.fullFieldName).joinToString("-"),
|
||||
origin = IrDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_REPRESENTATION_VARIABLE,
|
||||
saveVariable = saveVariable
|
||||
)
|
||||
}
|
||||
return ValueDeclarationMfvcNodeInstance(this, typeArguments, valueDeclarations)
|
||||
}
|
||||
|
||||
fun MfvcNode.createInstanceFromValueDeclarationsAndBoxType(
|
||||
type: IrSimpleType, fieldValues: List<IrValueDeclaration>
|
||||
): ValueDeclarationMfvcNodeInstance =
|
||||
ValueDeclarationMfvcNodeInstance(this, makeTypeArgumentsFromType(type), fieldValues)
|
||||
|
||||
fun makeTypeArgumentsFromType(type: IrSimpleType): TypeArguments {
|
||||
if (type.classifierOrNull !is IrClassSymbol) return mapOf()
|
||||
val parameters = type.erasedUpperBound.typeParameters
|
||||
val arguments = type.arguments
|
||||
require(parameters.size == arguments.size) {
|
||||
"Number of type parameters (${parameters.joinToString { it.render() }}) is not equal to number of type arguments (${arguments.joinToString { it.render() }})."
|
||||
}
|
||||
return parameters.zip(arguments) { parameter, argument -> parameter.symbol to (argument.typeOrNull ?: parameter.defaultType) }.toMap()
|
||||
|
||||
}
|
||||
|
||||
sealed interface NameableMfvcNode : MfvcNode {
|
||||
val namedNodeImpl: NameableMfvcNodeImpl
|
||||
}
|
||||
|
||||
val NameableMfvcNode.nameParts: List<IndexedNamePart>
|
||||
get() = namedNodeImpl.nameParts
|
||||
val NameableMfvcNode.name: Name
|
||||
get() = nameParts.last().name
|
||||
val NameableMfvcNode.index: Int
|
||||
get() = nameParts.last().index
|
||||
val NameableMfvcNode.unboxMethod: IrSimpleFunction
|
||||
get() = namedNodeImpl.unboxMethod
|
||||
val NameableMfvcNode.fullMethodName: Name
|
||||
get() = namedNodeImpl.fullMethodName
|
||||
val NameableMfvcNode.fullFieldName: Name
|
||||
get() = namedNodeImpl.fullFieldName
|
||||
val NameableMfvcNode.hasPureUnboxMethod: Boolean
|
||||
get() = namedNodeImpl.hasPureUnboxMethod
|
||||
|
||||
|
||||
data class IndexedNamePart(val index: Int, val name: Name)
|
||||
|
||||
class NameableMfvcNodeImpl(
|
||||
rootPropertyName: String?,
|
||||
val nameParts: List<IndexedNamePart>,
|
||||
val unboxMethod: IrSimpleFunction,
|
||||
val hasPureUnboxMethod: Boolean,
|
||||
) {
|
||||
val fullMethodName = makeFullMethodName(rootPropertyName, nameParts)
|
||||
val fullFieldName = makeFullFieldName(rootPropertyName, nameParts)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun makeFullMethodName(rootPropertyName: String?, nameParts: List<IndexedNamePart>): Name = if (rootPropertyName == null) {
|
||||
val restJoined = nameParts.joinToString("-") { it.index.toString() }
|
||||
Name.identifier("${KotlinTypeMapper.UNBOX_JVM_METHOD_NAME}-$restJoined")
|
||||
} else {
|
||||
val wholeName = (listOf(JvmAbi.getterName(rootPropertyName)) + nameParts.map { it.index.toString() }).joinToString("-")
|
||||
Name.identifier(wholeName)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun makeFullFieldName(rootPropertyName: String?, nameParts: List<IndexedNamePart>): Name {
|
||||
val joined = (listOf(rootPropertyName ?: "field") + nameParts.map { it.index.toString() }).joinToString("-")
|
||||
return Name.identifier(joined)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun MfvcNode.getSubnodeAndIndices(name: Name): Pair<NameableMfvcNode, IntRange>? {
|
||||
val node = (this as? MfvcNodeWithSubnodes)?.get(name) ?: return null
|
||||
val indices = subnodeIndices[node] ?: error("existing node without indices")
|
||||
return node to indices
|
||||
}
|
||||
|
||||
sealed interface MfvcNodeWithSubnodes : MfvcNode {
|
||||
abstract override val type: IrSimpleType
|
||||
val boxMethod: IrSimpleFunction
|
||||
val leavesUnboxMethods: List<IrSimpleFunction>?
|
||||
val subnodesImpl: MfvcNodeWithSubnodesImpl
|
||||
}
|
||||
|
||||
fun MfvcNodeWithSubnodes.makeBoxedExpression(
|
||||
scope: IrBuilderWithScope, typeArguments: TypeArguments, valueArguments: List<IrExpression>
|
||||
): IrExpression = scope.irCall(boxMethod).apply {
|
||||
val resultType = type.substitute(typeArguments) as IrSimpleType
|
||||
require(resultType.erasedUpperBound == type.erasedUpperBound) { "Substitution of $type led to $resultType" }
|
||||
for ((index, typeArgument) in resultType.arguments.withIndex()) {
|
||||
putTypeArgument(index, typeArgument.typeOrNull ?: resultType.erasedUpperBound.typeParameters[index].defaultType)
|
||||
}
|
||||
for ((index, valueArgument) in valueArguments.withIndex()) {
|
||||
putValueArgument(index, valueArgument)
|
||||
}
|
||||
}
|
||||
|
||||
operator fun MfvcNodeWithSubnodes.get(names: List<Name>): MfvcNode? {
|
||||
var cur: MfvcNode = this
|
||||
for (name in names) {
|
||||
cur = (cur as? MfvcNodeWithSubnodes)?.get(name) ?: return null
|
||||
}
|
||||
return cur
|
||||
}
|
||||
|
||||
private fun List<Any>.allEqual() = all { it == first() }
|
||||
|
||||
class MfvcNodeWithSubnodesImpl(val subnodes: List<NameableMfvcNode>, unboxMethod: IrSimpleFunction?) {
|
||||
init {
|
||||
require(subnodes.isNotEmpty())
|
||||
require(subnodes.map { it.nameParts.dropLast(1) }.allEqual())
|
||||
require(subnodes.map { it.index } == subnodes.indices.toList())
|
||||
}
|
||||
|
||||
private val mapping = subnodes.associateBy { it.name }.also { mapping ->
|
||||
require(mapping.size == subnodes.size) {
|
||||
subnodes
|
||||
.groupBy { it.name }
|
||||
.filterValues { it.size > 1 }
|
||||
.entries.joinToString(prefix = "Repeating node names found: ") { (name, nodes) -> "${nodes.size} nodes with name '$name'" }
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(name: Name): NameableMfvcNode? = mapping[name]
|
||||
val leaves: List<LeafMfvcNode> = mapLeaves { it }
|
||||
val fields: List<IrField>? = mapLeaves { it.field }.run {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
when {
|
||||
all { it == null } -> null
|
||||
all { it != null } -> this as List<IrField>
|
||||
else -> error("IrFields can either exist all or none for MFVC property")
|
||||
}
|
||||
}
|
||||
|
||||
val allInnerUnboxMethods: List<IrSimpleFunction> = subnodes.flatMap { subnode ->
|
||||
when (subnode) {
|
||||
is MfvcNodeWithSubnodes -> subnode.allUnboxMethods
|
||||
is LeafMfvcNode -> listOf(subnode.unboxMethod)
|
||||
}
|
||||
}
|
||||
|
||||
val allUnboxMethods = allInnerUnboxMethods + listOfNotNull(unboxMethod)
|
||||
|
||||
val indices: IntRange = leaves.indices
|
||||
|
||||
val subnodeIndices: Map<NameableMfvcNode, IntRange> = buildMap {
|
||||
var offset = 0
|
||||
for (node in subnodes) {
|
||||
when (node) {
|
||||
is IntermediateMfvcNode -> {
|
||||
val nodeSize = node.leavesCount
|
||||
put(node, offset until offset + nodeSize)
|
||||
putAll(node.subnodeIndices.mapValues { (_, v) -> (v.first + offset)..(v.last + offset) })
|
||||
offset += nodeSize
|
||||
}
|
||||
|
||||
is LeafMfvcNode -> {
|
||||
put(node, offset..offset)
|
||||
offset++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val MfvcNodeWithSubnodes.subnodes: List<NameableMfvcNode>
|
||||
get() = subnodesImpl.subnodes
|
||||
|
||||
operator fun MfvcNodeWithSubnodes.get(name: Name): NameableMfvcNode? = subnodesImpl[name]
|
||||
val MfvcNodeWithSubnodes.leaves: List<LeafMfvcNode>
|
||||
get() = subnodesImpl.leaves
|
||||
val MfvcNodeWithSubnodes.fields: List<IrField>?
|
||||
get() = subnodesImpl.fields
|
||||
val RootMfvcNode.fields: List<IrField>
|
||||
get() = subnodesImpl.fields!!
|
||||
val MfvcNodeWithSubnodes.indices: IntRange
|
||||
get() = subnodesImpl.indices
|
||||
val MfvcNodeWithSubnodes.subnodeIndices: Map<NameableMfvcNode, IntRange>
|
||||
get() = subnodesImpl.subnodeIndices
|
||||
val MfvcNodeWithSubnodes.allUnboxMethods: List<IrSimpleFunction>
|
||||
get() = subnodesImpl.allUnboxMethods
|
||||
val MfvcNodeWithSubnodes.allInnerUnboxMethods: List<IrSimpleFunction>
|
||||
get() = subnodesImpl.allInnerUnboxMethods
|
||||
|
||||
inline fun <R> MfvcNode.mapLeaves(crossinline f: (LeafMfvcNode) -> R): List<R> = flatMapLeaves { listOf(f(it)) }
|
||||
|
||||
fun <R> MfvcNode.flatMapLeaves(f: (LeafMfvcNode) -> List<R>): List<R> = when (this) {
|
||||
is MfvcNodeWithSubnodes -> subnodes.flatMap { it.flatMapLeaves(f) }
|
||||
is LeafMfvcNode -> f(this)
|
||||
}
|
||||
|
||||
inline fun <R> MfvcNodeWithSubnodesImpl.mapLeaves(crossinline f: (LeafMfvcNode) -> R): List<R> = subnodes.flatMap { it.mapLeaves(f) }
|
||||
|
||||
|
||||
private fun requireSameClasses(vararg classes: IrClass?) {
|
||||
val notNulls = classes.filterNotNull()
|
||||
require(notNulls.zipWithNext { a, b -> a == b }.all { it }) {
|
||||
"Found different classes: ${notNulls.joinToString("\n") { it.render() }}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun requireSameSizes(vararg sizes: Int) {
|
||||
require(sizes.asList().zipWithNext { a, b -> a == b }.all { it }) {
|
||||
"Found different sizes: ${sizes.joinToString()}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateGettingAccessorParameters(function: IrSimpleFunction) {
|
||||
require(function.valueParameters.isEmpty()) { "Value parameters are not expected for ${function.render()}" }
|
||||
require(function.extensionReceiverParameter == null) { "Extension receiver is not expected for ${function.render()}" }
|
||||
require(function.contextReceiverParametersCount == 0) { "Context receivers is not expected for ${function.render()}" }
|
||||
require(function.typeParameters.isEmpty()) { "Type parameters are not expected for ${function.render()}" }
|
||||
}
|
||||
|
||||
class LeafMfvcNode(
|
||||
override val type: IrType,
|
||||
rootPropertyName: String?,
|
||||
nameParts: List<IndexedNamePart>,
|
||||
val field: IrField?,
|
||||
unboxMethod: IrSimpleFunction,
|
||||
hasPureUnboxMethod: Boolean,
|
||||
) : NameableMfvcNode {
|
||||
override val namedNodeImpl: NameableMfvcNodeImpl = NameableMfvcNodeImpl(rootPropertyName, nameParts, unboxMethod, hasPureUnboxMethod)
|
||||
|
||||
override val leavesCount: Int
|
||||
get() = 1
|
||||
|
||||
init {
|
||||
requireSameClasses(
|
||||
field?.parentAsClass?.takeUnless { unboxMethod.parentAsClass.isCompanion },
|
||||
unboxMethod.parentAsClass,
|
||||
(unboxMethod.dispatchReceiverParameter?.type as? IrSimpleType)?.erasedUpperBound,
|
||||
)
|
||||
validateGettingAccessorParameters(unboxMethod)
|
||||
}
|
||||
|
||||
override fun createInstanceFromBox(
|
||||
scope: IrBlockBuilder,
|
||||
typeArguments: TypeArguments,
|
||||
receiver: IrExpression?,
|
||||
accessType: AccessType,
|
||||
saveVariable: (IrVariable) -> Unit,
|
||||
) = ReceiverBasedMfvcNodeInstance(
|
||||
scope, this, typeArguments, receiver, field?.let(::listOf), unboxMethod, accessType, saveVariable
|
||||
)
|
||||
|
||||
override fun toString(): String = "$fullFieldName: ${type.render()}"
|
||||
}
|
||||
|
||||
val MfvcNode.fields
|
||||
get() = when (this) {
|
||||
is MfvcNodeWithSubnodes -> this.fields
|
||||
is LeafMfvcNode -> field?.let(::listOf)
|
||||
}
|
||||
|
||||
class IntermediateMfvcNode(
|
||||
override val type: IrSimpleType,
|
||||
rootPropertyName: String?,
|
||||
nameParts: List<IndexedNamePart>,
|
||||
subnodes: List<NameableMfvcNode>,
|
||||
unboxMethod: IrSimpleFunction,
|
||||
hasPureUnboxMethod: Boolean,
|
||||
val rootNode: RootMfvcNode, // root node corresponding type of the node
|
||||
) : NameableMfvcNode, MfvcNodeWithSubnodes {
|
||||
override val namedNodeImpl: NameableMfvcNodeImpl = NameableMfvcNodeImpl(rootPropertyName, nameParts, unboxMethod, hasPureUnboxMethod)
|
||||
override val subnodesImpl: MfvcNodeWithSubnodesImpl = MfvcNodeWithSubnodesImpl(subnodes, unboxMethod)
|
||||
override val leavesCount
|
||||
get() = leaves.size
|
||||
|
||||
init {
|
||||
require(type.needsMfvcFlattening()) { "MFVC type expected but got% ${type.render()}" }
|
||||
require(type.erasedUpperBound == rootNode.mfvc) {
|
||||
"Root node must point at the RootNode of class ${type.erasedUpperBound.render()} but points at ${rootNode.mfvc.render()}"
|
||||
}
|
||||
requireSameClasses(
|
||||
unboxMethod.parentAsClass,
|
||||
(unboxMethod.dispatchReceiverParameter?.type as IrSimpleType?)?.erasedUpperBound,
|
||||
)
|
||||
validateGettingAccessorParameters(unboxMethod)
|
||||
}
|
||||
|
||||
override val boxMethod: IrSimpleFunction
|
||||
get() = rootNode.boxMethod
|
||||
|
||||
override val leavesUnboxMethods: List<IrSimpleFunction> = collectLeavesUnboxMethods()
|
||||
|
||||
override fun createInstanceFromBox(
|
||||
scope: IrBlockBuilder,
|
||||
typeArguments: TypeArguments,
|
||||
receiver: IrExpression?,
|
||||
accessType: AccessType,
|
||||
saveVariable: (IrVariable) -> Unit,
|
||||
) = ReceiverBasedMfvcNodeInstance(
|
||||
scope, this, typeArguments, receiver, fields, unboxMethod, accessType, saveVariable
|
||||
)
|
||||
|
||||
override fun toString(): String =
|
||||
"$fullFieldName: ${type.render()}\n${subnodes.joinToString("\n").prependIndent(" ")}"
|
||||
}
|
||||
|
||||
private fun MfvcNodeWithSubnodes.collectLeavesUnboxMethods() = mapLeaves { it.unboxMethod }
|
||||
|
||||
fun IrSimpleFunction.isDefaultGetter(expectedField: IrField? = null): Boolean {
|
||||
if (!isGetter) return false
|
||||
if (expectedField != null && correspondingPropertySymbol?.owner?.backingField != expectedField) return false
|
||||
val statement = (body?.statements?.singleOrNull() as? IrReturn)?.value as? IrGetField ?: return false
|
||||
val actualField = statement.symbol.owner
|
||||
return expectedField == null || actualField == expectedField || parentAsClass.isCompanion && actualField.correspondingPropertySymbol == correspondingPropertySymbol
|
||||
}
|
||||
|
||||
fun IrSimpleFunction.getGetterField(): IrField? {
|
||||
if (!isGetter) return null
|
||||
val statement = (body?.statements?.singleOrNull() as? IrReturn)?.value as? IrGetField ?: return null
|
||||
return statement.symbol.owner
|
||||
}
|
||||
|
||||
class RootMfvcNode internal constructor(
|
||||
val mfvc: IrClass,
|
||||
subnodes: List<NameableMfvcNode>,
|
||||
val oldPrimaryConstructor: IrConstructor,
|
||||
val newPrimaryConstructor: IrConstructor,
|
||||
val primaryConstructorImpl: IrSimpleFunction,
|
||||
override val boxMethod: IrSimpleFunction,
|
||||
val specializedEqualsMethod: IrSimpleFunction,
|
||||
) : MfvcNodeWithSubnodes {
|
||||
override val subnodesImpl: MfvcNodeWithSubnodesImpl = MfvcNodeWithSubnodesImpl(subnodes, null)
|
||||
override val type: IrSimpleType = mfvc.defaultType
|
||||
|
||||
override val leavesCount: Int
|
||||
get() = leaves.size
|
||||
|
||||
override val leavesUnboxMethods: List<IrSimpleFunction> = collectLeavesUnboxMethods()
|
||||
|
||||
init {
|
||||
require(type.needsMfvcFlattening()) { "MFVC type expected but got% ${type.render()}" }
|
||||
for (constructor in listOf(oldPrimaryConstructor, newPrimaryConstructor)) {
|
||||
require(constructor.isPrimary) { "Expected a primary constructor but got:\n${constructor.dump()}" }
|
||||
}
|
||||
requireSameClasses(
|
||||
mfvc,
|
||||
oldPrimaryConstructor.parentAsClass,
|
||||
newPrimaryConstructor.parentAsClass,
|
||||
primaryConstructorImpl.parentAsClass,
|
||||
boxMethod.parentAsClass,
|
||||
specializedEqualsMethod.parentAsClass,
|
||||
oldPrimaryConstructor.constructedClass,
|
||||
newPrimaryConstructor.constructedClass,
|
||||
boxMethod.returnType.erasedUpperBound,
|
||||
)
|
||||
require(primaryConstructorImpl.returnType.isUnit()) {
|
||||
"Constructor-impl must return Unit but returns ${primaryConstructorImpl.returnType.render()}"
|
||||
}
|
||||
require(specializedEqualsMethod.returnType.isBoolean()) {
|
||||
"Specialized equals method must return Boolean but returns ${primaryConstructorImpl.returnType.render()}"
|
||||
}
|
||||
require(oldPrimaryConstructor.typeParameters.isEmpty() && newPrimaryConstructor.typeParameters.isEmpty()) {
|
||||
"Constructors do not support type parameters yet"
|
||||
}
|
||||
requireSameSizes(
|
||||
mfvc.typeParameters.size,
|
||||
boxMethod.typeParameters.size,
|
||||
primaryConstructorImpl.typeParameters.size,
|
||||
)
|
||||
require(specializedEqualsMethod.typeParameters.size == 2 * mfvc.typeParameters.size) {
|
||||
"Specialized equals method must contain twice more type parameters than corresponding MFVC ${mfvc.typeParameters.map { it.defaultType.render() }} but has ${specializedEqualsMethod.typeParameters.map { it.defaultType.render() }}"
|
||||
}
|
||||
requireSameSizes(oldPrimaryConstructor.valueParameters.size, subnodes.size)
|
||||
requireSameSizes(
|
||||
leavesCount,
|
||||
newPrimaryConstructor.valueParameters.size,
|
||||
primaryConstructorImpl.valueParameters.size,
|
||||
boxMethod.valueParameters.size,
|
||||
)
|
||||
require(specializedEqualsMethod.valueParameters.size == 2 * leavesCount) {
|
||||
"Specialized equals method must contain twice more value parameters than corresponding primary constructor of the MFVC ${mfvc.typeParameters.map { it.defaultType.render() }} but has ${specializedEqualsMethod.typeParameters.map { it.defaultType.render() }}"
|
||||
}
|
||||
for (function in listOf(oldPrimaryConstructor, newPrimaryConstructor, primaryConstructorImpl, boxMethod, specializedEqualsMethod)) {
|
||||
require(function.extensionReceiverParameter == null) { "Extension receiver is not expected for ${function.render()}" }
|
||||
require(function.contextReceiverParametersCount == 0) { "Context receivers are not expected for ${function.render()}" }
|
||||
}
|
||||
}
|
||||
|
||||
override fun createInstanceFromBox(
|
||||
scope: IrBlockBuilder,
|
||||
typeArguments: TypeArguments,
|
||||
receiver: IrExpression?,
|
||||
accessType: AccessType,
|
||||
saveVariable: (IrVariable) -> Unit,
|
||||
) = ReceiverBasedMfvcNodeInstance(scope, this, typeArguments, receiver, fields, null, accessType, saveVariable)
|
||||
|
||||
override fun toString(): String =
|
||||
"${type.render()}\n${subnodes.joinToString("\n").prependIndent(" ")}"
|
||||
}
|
||||
|
||||
fun IrType.needsMfvcFlattening(): Boolean = isMultiFieldValueClassType() && !isNullable() ||
|
||||
classifierOrNull.let { classifier ->
|
||||
classifier is IrTypeParameterSymbol && classifier.owner.superTypes.any { it.needsMfvcFlattening() }
|
||||
} // add not is annotated as @UseBox etc
|
||||
@@ -1,487 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.MultiFieldValueClassRepresentation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||
|
||||
fun createLeafMfvcNode(
|
||||
parent: IrDeclarationContainer,
|
||||
context: JvmBackendContext,
|
||||
type: IrType,
|
||||
rootPropertyName: String?,
|
||||
nameParts: List<IndexedNamePart>,
|
||||
fieldAnnotations: List<IrConstructorCall>,
|
||||
static: Boolean,
|
||||
overriddenNode: LeafMfvcNode?,
|
||||
defaultMethodsImplementationSourceNode: Pair<IrSimpleFunction?, LeafMfvcNode>?, // used if the getter was custom and need to call it.
|
||||
oldGetter: IrSimpleFunction?,
|
||||
modality: Modality,
|
||||
oldPropertyBackingField: IrField?,
|
||||
): LeafMfvcNode {
|
||||
require(!type.needsMfvcFlattening()) { "${type.render()} requires flattening" }
|
||||
|
||||
val fullMethodName = NameableMfvcNodeImpl.makeFullMethodName(rootPropertyName, nameParts)
|
||||
val fullFieldName = NameableMfvcNodeImpl.makeFullFieldName(rootPropertyName, nameParts)
|
||||
|
||||
val field = oldPropertyBackingField?.let { oldBackingField ->
|
||||
context.irFactory.buildField {
|
||||
updateFrom(oldBackingField)
|
||||
this.name = fullFieldName
|
||||
this.type = type
|
||||
this.visibility = DescriptorVisibilities.PRIVATE
|
||||
this.metadata = null
|
||||
}.apply {
|
||||
this.parent = oldBackingField.parent
|
||||
this.annotations = fieldAnnotations.map { it.deepCopyWithVariables() }
|
||||
}
|
||||
}
|
||||
|
||||
val unboxMethod = makeUnboxMethod(
|
||||
context,
|
||||
fullMethodName,
|
||||
type,
|
||||
parent,
|
||||
overriddenNode,
|
||||
static,
|
||||
defaultMethodsImplementationSourceNode,
|
||||
oldGetter,
|
||||
modality,
|
||||
) { receiver -> irGetField(if (field!!.isStatic) null else irGet(receiver!!), field) }
|
||||
|
||||
return LeafMfvcNode(type, rootPropertyName, nameParts, field, unboxMethod, defaultMethodsImplementationSourceNode.isPure())
|
||||
}
|
||||
|
||||
private fun Pair<IrSimpleFunction?, NameableMfvcNode>?.isPure(): Boolean {
|
||||
val (outer, inner) = this ?: return true
|
||||
return outer == null && inner.hasPureUnboxMethod
|
||||
}
|
||||
|
||||
private fun makeUnboxMethod(
|
||||
context: JvmBackendContext,
|
||||
fullMethodName: Name,
|
||||
type: IrType,
|
||||
parent: IrDeclarationParent,
|
||||
overriddenNode: NameableMfvcNode?,
|
||||
static: Boolean,
|
||||
defaultMethodsImplementationSourceNode: Pair<IrSimpleFunction?, NameableMfvcNode>?,
|
||||
oldGetter: IrSimpleFunction?,
|
||||
modality: Modality,
|
||||
makeOptimizedExpression: IrBuilderWithScope.(receiver: IrValueDeclaration?) -> IrExpression,
|
||||
): IrSimpleFunction {
|
||||
val res = oldGetter ?: context.irFactory.buildFun {
|
||||
this.name = fullMethodName
|
||||
this.origin = JvmLoweredDeclarationOrigin.SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER
|
||||
this.returnType = type
|
||||
this.modality = modality
|
||||
}.apply {
|
||||
this.parent = parent
|
||||
overriddenSymbols = overriddenNode?.let { it.unboxMethod.overriddenSymbols + it.unboxMethod.symbol } ?: listOf()
|
||||
if (!static) {
|
||||
createDispatchReceiverParameter()
|
||||
}
|
||||
}
|
||||
|
||||
return res.apply {
|
||||
body = with(context.createJvmIrBuilder(this.symbol)) {
|
||||
val receiver = dispatchReceiverParameter
|
||||
if (defaultMethodsImplementationSourceNode == null) {
|
||||
irExprBody(makeOptimizedExpression(receiver))
|
||||
} else {
|
||||
val (outer, inner) = defaultMethodsImplementationSourceNode
|
||||
val receiverExpression = receiver?.let { irGet(it) }
|
||||
val outerCall = if (outer == null) receiverExpression else irCall(outer).apply { dispatchReceiver = receiverExpression }
|
||||
val innerCall = irCall(inner.unboxMethod).apply { dispatchReceiver = outerCall }
|
||||
irExprBody(innerCall)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createNameableMfvcNodes(
|
||||
parent: IrDeclarationContainer,
|
||||
context: JvmBackendContext,
|
||||
type: IrSimpleType,
|
||||
typeArguments: TypeArguments,
|
||||
rootPropertyName: String?,
|
||||
nameParts: List<IndexedNamePart>,
|
||||
fieldAnnotations: List<IrConstructorCall>,
|
||||
static: Boolean,
|
||||
overriddenNode: NameableMfvcNode?,
|
||||
defaultMethodsImplementationSourceNode: Pair<IrSimpleFunction?, NameableMfvcNode>?, // used if the getter was custom and need to call it.
|
||||
oldGetter: IrSimpleFunction?,
|
||||
modality: Modality,
|
||||
oldPropertyBackingField: IrField?,
|
||||
): NameableMfvcNode = if (type.needsMfvcFlattening()) createIntermediateMfvcNode(
|
||||
parent,
|
||||
context,
|
||||
type,
|
||||
typeArguments,
|
||||
rootPropertyName,
|
||||
nameParts,
|
||||
fieldAnnotations,
|
||||
static,
|
||||
overriddenNode as IntermediateMfvcNode?,
|
||||
defaultMethodsImplementationSourceNode?.let { (outer, inner) -> outer to (inner as IntermediateMfvcNode) },
|
||||
oldGetter,
|
||||
modality,
|
||||
oldPropertyBackingField,
|
||||
) else createLeafMfvcNode(
|
||||
parent,
|
||||
context,
|
||||
type,
|
||||
rootPropertyName,
|
||||
nameParts,
|
||||
fieldAnnotations,
|
||||
static,
|
||||
overriddenNode as LeafMfvcNode?,
|
||||
defaultMethodsImplementationSourceNode?.let { (outer, inner) -> outer to (inner as LeafMfvcNode) },
|
||||
oldGetter,
|
||||
modality,
|
||||
oldPropertyBackingField
|
||||
)
|
||||
|
||||
fun createIntermediateMfvcNode(
|
||||
parent: IrDeclarationContainer,
|
||||
context: JvmBackendContext,
|
||||
type: IrSimpleType,
|
||||
typeArguments: TypeArguments,
|
||||
rootPropertyName: String?,
|
||||
nameParts: List<IndexedNamePart>,
|
||||
fieldAnnotations: List<IrConstructorCall>,
|
||||
static: Boolean,
|
||||
overriddenNode: IntermediateMfvcNode?,
|
||||
defaultMethodsImplementationSourceNode: Pair<IrSimpleFunction?, IntermediateMfvcNode>?, // used if the getter was custom and need to call it.
|
||||
oldGetter: IrSimpleFunction?,
|
||||
modality: Modality,
|
||||
oldPropertyBackingField: IrField?,
|
||||
): IntermediateMfvcNode {
|
||||
require(type.needsMfvcFlattening()) { "${type.render()} does not require flattening" }
|
||||
val valueClass = type.erasedUpperBound
|
||||
val representation = valueClass.multiFieldValueClassRepresentation!!
|
||||
|
||||
val replacements = context.multiFieldValueClassReplacements
|
||||
val rootNode = replacements.getRootMfvcNode(valueClass)!!
|
||||
|
||||
val oldField = oldGetter?.correspondingPropertySymbol?.owner?.backingField
|
||||
|
||||
val shadowBackingFieldProperty = if (oldField == null) oldGetter?.getGetterField()?.correspondingPropertySymbol?.owner else null
|
||||
val useOldGetter = oldGetter != null && (oldField == null || !oldGetter.isDefaultGetter(oldField))
|
||||
|
||||
val subnodes = representation.underlyingPropertyNamesToTypes.mapIndexed { index, (name, type) ->
|
||||
val newType = type.substitute(typeArguments) as IrSimpleType
|
||||
val newTypeArguments = typeArguments.toMutableMap().apply { putAll(makeTypeArgumentsFromType(newType)) }
|
||||
val newDefaultMethodsImplementationSourceNode = when {
|
||||
defaultMethodsImplementationSourceNode != null -> {
|
||||
val (outer, inner) = defaultMethodsImplementationSourceNode
|
||||
require(!useOldGetter) { "Multiple non-default getters:\n\n${outer?.dump()}\n\n${oldGetter?.dump()}" }
|
||||
outer to inner[name]!!
|
||||
}
|
||||
|
||||
shadowBackingFieldProperty != null -> null to replacements.getMfvcPropertyNode(shadowBackingFieldProperty)!!
|
||||
useOldGetter -> oldGetter!! to rootNode[name]!!
|
||||
else -> null
|
||||
}
|
||||
createNameableMfvcNodes(
|
||||
parent,
|
||||
context,
|
||||
newType,
|
||||
newTypeArguments,
|
||||
rootPropertyName,
|
||||
nameParts + IndexedNamePart(index, name),
|
||||
fieldAnnotations,
|
||||
static,
|
||||
overriddenNode?.let { it[name]!! },
|
||||
newDefaultMethodsImplementationSourceNode,
|
||||
null,
|
||||
modality,
|
||||
oldPropertyBackingField,
|
||||
)
|
||||
}
|
||||
|
||||
val fullMethodName = NameableMfvcNodeImpl.makeFullMethodName(rootPropertyName, nameParts)
|
||||
|
||||
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) }
|
||||
rootNode.makeBoxedExpression(this, typeArguments, valueArguments)
|
||||
}
|
||||
|
||||
val hasPureUnboxMethod = defaultMethodsImplementationSourceNode.isPure() && subnodes.all { it.hasPureUnboxMethod }
|
||||
return IntermediateMfvcNode(
|
||||
type, rootPropertyName, nameParts, subnodes, unboxMethod, hasPureUnboxMethod, rootNode
|
||||
)
|
||||
}
|
||||
|
||||
fun collectPropertiesAfterLowering(irClass: IrClass) = LinkedHashSet<IrProperty>().apply {
|
||||
for (element in irClass.declarations) {
|
||||
if (element is IrField) {
|
||||
element.correspondingPropertySymbol?.owner?.let { add(it) }
|
||||
} else if (element is IrSimpleFunction && element.extensionReceiverParameter == null && element.contextReceiverParametersCount == 0) {
|
||||
element.correspondingPropertySymbol?.owner?.let { add(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrProperty.isStatic(currentContainer: IrDeclarationContainer) =
|
||||
getterIfDeclared(currentContainer)?.isStatic ?: backingField?.isStatic ?: error("Property without both getter and backing field")
|
||||
|
||||
fun getRootNode(context: JvmBackendContext, mfvc: IrClass): RootMfvcNode {
|
||||
require(mfvc.isMultiFieldValueClass) { "${mfvc.defaultType.render()} does not require flattening" }
|
||||
val oldPrimaryConstructor = mfvc.primaryConstructor!!
|
||||
val representation = mfvc.multiFieldValueClassRepresentation!!
|
||||
val properties = collectPropertiesAfterLowering(mfvc).associateBy { it.isStatic(mfvc) to it.name }
|
||||
|
||||
val subnodes = makeRootMfvcNodeSubnodes(representation, properties, context, mfvc)
|
||||
|
||||
val mfvcNodeWithSubnodesImpl = MfvcNodeWithSubnodesImpl(subnodes, null)
|
||||
val leaves = mfvcNodeWithSubnodesImpl.leaves
|
||||
val fields = mfvcNodeWithSubnodesImpl.fields!!
|
||||
|
||||
val newPrimaryConstructor = makeMfvcPrimaryConstructor(context, oldPrimaryConstructor, mfvc, leaves, fields)
|
||||
val primaryConstructorImpl = makePrimaryConstructorImpl(context, oldPrimaryConstructor, mfvc, leaves)
|
||||
val boxMethod = makeBoxMethod(context, mfvc, leaves, newPrimaryConstructor)
|
||||
val specializedEqualsMethod = makeSpecializedEqualsMethod(context, mfvc, leaves)
|
||||
|
||||
return RootMfvcNode(
|
||||
mfvc, subnodes, oldPrimaryConstructor, newPrimaryConstructor, primaryConstructorImpl, boxMethod, specializedEqualsMethod
|
||||
)
|
||||
}
|
||||
|
||||
private fun makeSpecializedEqualsMethod(
|
||||
context: JvmBackendContext,
|
||||
mfvc: IrClass,
|
||||
leaves: List<LeafMfvcNode>
|
||||
) = context.irFactory.buildFun {
|
||||
name = InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME
|
||||
// TODO: Revisit this once we allow user defined equals methods in value classes.
|
||||
origin = JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD
|
||||
returnType = context.irBuiltIns.booleanType
|
||||
}.apply {
|
||||
parent = mfvc
|
||||
copyTypeParametersFrom(mfvc)
|
||||
val typeParametersHalf1 = typeParameters.apply {
|
||||
for (it in this) {
|
||||
it.name = Name.guessByFirstCharacter("${it.name.asString()}1")
|
||||
}
|
||||
}
|
||||
|
||||
copyTypeParametersFrom(mfvc)
|
||||
val typeParametersHalf2 = typeParameters.drop(typeParametersHalf1.size).apply {
|
||||
for (it in this) {
|
||||
it.name = Name.guessByFirstCharacter("${it.name.asString()}2")
|
||||
}
|
||||
}
|
||||
|
||||
val valueParametersHalf1 = leaves.map { leaf ->
|
||||
addValueParameter {
|
||||
this.name = Name.guessByFirstCharacter(
|
||||
"${InlineClassDescriptorResolver.SPECIALIZED_EQUALS_FIRST_PARAMETER_NAME}$${leaf.fullFieldName}"
|
||||
)
|
||||
this.type = leaf.type.substitute(mfvc.typeParameters, typeParametersHalf1.map { it.defaultType })
|
||||
}
|
||||
}
|
||||
|
||||
val valueParametersHalf2 = leaves.map { leaf ->
|
||||
addValueParameter {
|
||||
this.name = Name.guessByFirstCharacter(
|
||||
"${InlineClassDescriptorResolver.SPECIALIZED_EQUALS_SECOND_PARAMETER_NAME}$${leaf.fullFieldName}"
|
||||
)
|
||||
this.type = leaf.type.substitute(mfvc.typeParameters, typeParametersHalf2.map { it.defaultType })
|
||||
}
|
||||
}
|
||||
|
||||
body = with(context.createJvmIrBuilder(this.symbol)) {
|
||||
val conjunctions = valueParametersHalf1.zip(valueParametersHalf2) { f1, f2 -> irEquals(irGet(f1), irGet(f2)) }
|
||||
irExprBody(conjunctions.reduce { acc, current ->
|
||||
irCall(context.irBuiltIns.andandSymbol).apply {
|
||||
putValueArgument(0, acc)
|
||||
putValueArgument(1, current)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeBoxMethod(
|
||||
context: JvmBackendContext,
|
||||
mfvc: IrClass,
|
||||
leaves: List<LeafMfvcNode>,
|
||||
newPrimaryConstructor: IrConstructor
|
||||
) = context.irFactory.buildFun {
|
||||
name = Name.identifier(KotlinTypeMapper.BOX_JVM_METHOD_NAME)
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER
|
||||
returnType = mfvc.defaultType
|
||||
}.apply {
|
||||
parent = mfvc
|
||||
copyTypeParametersFrom(mfvc)
|
||||
val mapping = mfvc.typeParameters.zip(typeParameters) { classTypeParameter, functionTypeParameter ->
|
||||
classTypeParameter.symbol to functionTypeParameter.defaultType
|
||||
}.toMap()
|
||||
returnType = returnType.substitute(mapping)
|
||||
val parameters = leaves.map { leaf -> addValueParameter(leaf.fullFieldName, leaf.type.substitute(mapping)) }
|
||||
body = with(context.createJvmIrBuilder(this.symbol)) {
|
||||
irExprBody(irCall(newPrimaryConstructor).apply {
|
||||
for ((index, parameter) in parameters.withIndex()) {
|
||||
putValueArgument(index, irGet(parameter))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun makePrimaryConstructorImpl(
|
||||
context: JvmBackendContext,
|
||||
oldPrimaryConstructor: IrConstructor,
|
||||
mfvc: IrClass,
|
||||
leaves: List<LeafMfvcNode>
|
||||
) = context.irFactory.buildFun {
|
||||
name = InlineClassAbi.mangledNameFor(oldPrimaryConstructor, false, false)
|
||||
visibility = oldPrimaryConstructor.visibility
|
||||
origin = JvmLoweredDeclarationOrigin.STATIC_MULTI_FIELD_VALUE_CLASS_CONSTRUCTOR
|
||||
returnType = context.irBuiltIns.unitType
|
||||
modality = Modality.FINAL
|
||||
}.apply {
|
||||
parent = mfvc
|
||||
copyTypeParametersFrom(mfvc)
|
||||
for (leaf in leaves) {
|
||||
addValueParameter(leaf.fullFieldName, leaf.type.substitute(mfvc.typeParameters, typeParameters.map { it.defaultType }))
|
||||
}
|
||||
// body is added in the Lowering file as it needs to be lowered
|
||||
}
|
||||
|
||||
private fun makeMfvcPrimaryConstructor(
|
||||
context: JvmBackendContext,
|
||||
oldPrimaryConstructor: IrConstructor,
|
||||
mfvc: IrClass,
|
||||
leaves: List<LeafMfvcNode>,
|
||||
fields: List<IrField>
|
||||
) = context.irFactory.buildConstructor {
|
||||
updateFrom(oldPrimaryConstructor)
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_MULTI_FIELD_VALUE_CLASS_MEMBER
|
||||
returnType = oldPrimaryConstructor.returnType
|
||||
}.apply {
|
||||
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
|
||||
body = context.createIrBuilder(irConstructor.symbol).irBlockBody(irConstructor) {
|
||||
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
|
||||
for ((field, parameter) in fields zip parameters) {
|
||||
+irSetField(irGet(mfvc.thisReceiver!!), field, irGet(parameter))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeRootMfvcNodeSubnodes(
|
||||
representation: MultiFieldValueClassRepresentation<IrSimpleType>,
|
||||
properties: Map<Pair<Boolean, Name>, IrProperty>,
|
||||
context: JvmBackendContext,
|
||||
mfvc: IrClass
|
||||
) = representation.underlyingPropertyNamesToTypes.mapIndexed { index, (name, type) ->
|
||||
val typeArguments = makeTypeArgumentsFromType(type)
|
||||
val oldProperty = properties[false to name]!!
|
||||
val oldBackingField = oldProperty.backingField
|
||||
val oldGetter = oldProperty.getterIfDeclared(mfvc)
|
||||
val overriddenNode = oldGetter?.let { getOverriddenNode(context.multiFieldValueClassReplacements, it) as IntermediateMfvcNode? }
|
||||
val static = oldProperty.isStatic(mfvc)
|
||||
createNameableMfvcNodes(
|
||||
mfvc,
|
||||
context,
|
||||
type,
|
||||
typeArguments,
|
||||
null,
|
||||
listOf(IndexedNamePart(index, name)),
|
||||
oldBackingField?.annotations ?: listOf(),
|
||||
static,
|
||||
overriddenNode,
|
||||
null,
|
||||
oldGetter.takeIf { static },
|
||||
Modality.FINAL,
|
||||
oldBackingField,
|
||||
).also {
|
||||
updateAnnotationsAndPropertyFromOldProperty(oldProperty)
|
||||
it.unboxMethod.overriddenSymbols = listOf() // the getter is saved so it overrides itself
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAnnotationsAndPropertyFromOldProperty(
|
||||
oldProperty: IrProperty
|
||||
) {
|
||||
oldProperty.setter?.apply {
|
||||
name = Name.identifier(JvmAbi.setterName(oldProperty.name.asString()))
|
||||
correspondingPropertySymbol = null
|
||||
origin = IrDeclarationOrigin.DEFINED
|
||||
}
|
||||
oldProperty.setter = null
|
||||
oldProperty.backingField = null
|
||||
}
|
||||
|
||||
fun createIntermediateNodeForMfvcPropertyOfRegularClass(
|
||||
parent: IrDeclarationContainer,
|
||||
context: JvmBackendContext,
|
||||
oldProperty: IrProperty,
|
||||
): IntermediateMfvcNode {
|
||||
val oldGetter = oldProperty.getterIfDeclared(parent)
|
||||
val oldField = oldProperty.backingField
|
||||
val type = oldProperty.getter?.returnType ?: oldField?.type ?: error("Either getter or field must exist")
|
||||
require(type is IrSimpleType && type.needsMfvcFlattening()) { "Expected MFVC but got ${type.render()}" }
|
||||
val fieldAnnotations = oldField?.annotations ?: listOf()
|
||||
val static = oldProperty.isStatic(parent)
|
||||
val overriddenNode = oldGetter?.let { getOverriddenNode(context.multiFieldValueClassReplacements, it) as IntermediateMfvcNode? }
|
||||
val modality = if (oldGetter == null || oldGetter.modality == Modality.FINAL) Modality.FINAL else oldGetter.modality
|
||||
return createIntermediateMfvcNode(
|
||||
parent, context, type, makeTypeArgumentsFromType(type), oldProperty.name.asString(), listOf(),
|
||||
fieldAnnotations, static, overriddenNode, null, oldGetter, modality, oldField
|
||||
).also {
|
||||
updateAnnotationsAndPropertyFromOldProperty(oldProperty)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOverriddenNode(replacements: MemoizedMultiFieldValueClassReplacements, getter: IrSimpleFunction): NameableMfvcNode? =
|
||||
getter.overriddenSymbols
|
||||
.firstOrNull { !it.owner.isFakeOverride }
|
||||
?.let { replacements.getMfvcPropertyNode(it.owner.correspondingPropertySymbol!!.owner) }
|
||||
|
||||
fun getOptimizedPublicAccess(currentElement: IrElement?, parent: IrClass): AccessType {
|
||||
val declaration = currentElement as? IrDeclaration ?: return AccessType.AlwaysPublic
|
||||
for (cur in declaration.parents.filterIsInstance<IrClass>()) {
|
||||
return when {
|
||||
cur == parent -> AccessType.PrivateWhenNoBox
|
||||
cur.isInner -> continue
|
||||
cur.isCompanion -> continue
|
||||
else -> AccessType.AlwaysPublic
|
||||
}
|
||||
}
|
||||
return AccessType.AlwaysPublic
|
||||
}
|
||||
|
||||
private fun IrProperty.getterIfDeclared(parent: IrDeclarationContainer): IrSimpleFunction? = getter?.takeIf { it in parent.declarations }
|
||||
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.util.substitute
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
interface MfvcNodeInstance {
|
||||
val node: MfvcNode
|
||||
val typeArguments: TypeArguments
|
||||
val type: IrSimpleType
|
||||
|
||||
fun makeFlattenedGetterExpressions(scope: IrBlockBuilder): List<IrExpression>
|
||||
fun makeGetterExpression(scope: IrBuilderWithScope): IrExpression
|
||||
operator fun get(name: Name): MfvcNodeInstance?
|
||||
fun makeStatements(scope: IrBuilderWithScope, values: List<IrExpression>): List<IrStatement>
|
||||
}
|
||||
|
||||
private fun makeTypeFromMfvcNodeAndTypeArguments(node: MfvcNode, typeArguments: TypeArguments) =
|
||||
node.type.substitute(typeArguments) as IrSimpleType
|
||||
|
||||
fun MfvcNodeInstance.addSetterStatements(scope: IrBlockBuilder, values: List<IrExpression>) = with(scope) {
|
||||
for (statement in makeStatements(this, values)) {
|
||||
+statement
|
||||
}
|
||||
}
|
||||
|
||||
fun MfvcNodeInstance.makeSetterExpressions(scope: IrBuilderWithScope, values: List<IrExpression>): IrExpression = scope.irBlock {
|
||||
addSetterStatements(this, values)
|
||||
}
|
||||
|
||||
private fun MfvcNodeInstance.checkValuesCount(values: List<IrExpression>) {
|
||||
require(values.size == node.leavesCount) { "Node $node requires ${node.leavesCount} values but got ${values.map { it.render() }}" }
|
||||
}
|
||||
|
||||
class ValueDeclarationMfvcNodeInstance(
|
||||
override val node: MfvcNode,
|
||||
override val typeArguments: TypeArguments,
|
||||
val valueDeclarations: List<IrValueDeclaration>,
|
||||
) : MfvcNodeInstance {
|
||||
init {
|
||||
require(valueDeclarations.size == size) { "Expected value declarations list of size $size but got of size ${valueDeclarations.size}" }
|
||||
}
|
||||
|
||||
override val type: IrSimpleType = makeTypeFromMfvcNodeAndTypeArguments(node, typeArguments)
|
||||
|
||||
override fun makeFlattenedGetterExpressions(scope: IrBlockBuilder): List<IrExpression> =
|
||||
makeFlattenedGetterExpressions(scope as IrBuilderWithScope)
|
||||
private fun makeFlattenedGetterExpressions(scope: IrBuilderWithScope): List<IrExpression> = valueDeclarations.map { scope.irGet(it) }
|
||||
|
||||
override fun makeGetterExpression(scope: IrBuilderWithScope): IrExpression = when (node) {
|
||||
is LeafMfvcNode -> makeFlattenedGetterExpressions(scope).single()
|
||||
is MfvcNodeWithSubnodes -> node.makeBoxedExpression(scope, typeArguments, makeFlattenedGetterExpressions(scope))
|
||||
}
|
||||
|
||||
override fun get(name: Name): ValueDeclarationMfvcNodeInstance? {
|
||||
val (newNode, indices) = node.getSubnodeAndIndices(name) ?: return null
|
||||
return ValueDeclarationMfvcNodeInstance(newNode, typeArguments, valueDeclarations.slice(indices))
|
||||
}
|
||||
|
||||
override fun makeStatements(scope: IrBuilderWithScope, values: List<IrExpression>): List<IrStatement> {
|
||||
checkValuesCount(values)
|
||||
return valueDeclarations.zip(values) { declaration, value -> scope.irSet(declaration, value) }
|
||||
}
|
||||
}
|
||||
|
||||
internal class ExpressionCopierImpl(
|
||||
expression: IrExpression?,
|
||||
private val scope: IrBlockBuilder,
|
||||
private val saveVariable: (IrVariable) -> Unit,
|
||||
) {
|
||||
private sealed interface CopyableExpression {
|
||||
fun makeExpression(scope: IrBuilderWithScope): IrExpression
|
||||
}
|
||||
|
||||
private class SavedToVariable(val variable: IrVariable) : CopyableExpression {
|
||||
override fun makeExpression(scope: IrBuilderWithScope): IrExpression = scope.irGet(variable)
|
||||
}
|
||||
|
||||
private class PureExpression(val expression: IrExpression) : CopyableExpression {
|
||||
override fun makeExpression(scope: IrBuilderWithScope): IrExpression = expression.deepCopyWithSymbols()
|
||||
}
|
||||
|
||||
private fun IrExpression.orSavedToVariable(): CopyableExpression =
|
||||
if (isRepeatableGetter()) {
|
||||
PureExpression(this)
|
||||
} else SavedToVariable(
|
||||
scope.savableStandaloneVariableWithSetter(
|
||||
this@orSavedToVariable,
|
||||
origin = IrDeclarationOrigin.TEMPORARY_MULTI_FIELD_VALUE_CLASS_VARIABLE,
|
||||
saveVariable = saveVariable,
|
||||
isTemporary = true,
|
||||
)
|
||||
)
|
||||
|
||||
private val copyableExpression = expression?.orSavedToVariable()
|
||||
|
||||
fun makeCopy() = copyableExpression?.makeExpression(scope)
|
||||
}
|
||||
|
||||
fun IrExpression?.isRepeatableGetter(): Boolean = when (this) {
|
||||
null -> true
|
||||
is IrConst<*> -> true
|
||||
is IrGetValue -> true
|
||||
is IrGetField -> receiver.isRepeatableGetter()
|
||||
is IrTypeOperatorCallImpl -> this.argument.isRepeatableGetter()
|
||||
is IrContainerExpression -> statements.all { it is IrExpression && it.isRepeatableGetter() || it is IrVariable }
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun IrExpression?.isRepeatableSetter(): Boolean = when (this) {
|
||||
null -> true
|
||||
is IrConst<*> -> true
|
||||
is IrSetValue -> value.isRepeatableGetter()
|
||||
is IrSetField -> receiver.isRepeatableGetter() && value.isRepeatableGetter()
|
||||
is IrTypeOperatorCallImpl -> this.argument.isRepeatableSetter()
|
||||
is IrContainerExpression -> statements.dropLast(1).all { it is IrExpression && it.isRepeatableGetter() || it is IrVariable } &&
|
||||
statements.lastOrNull().let { it is IrExpression? && it.isRepeatableSetter() }
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun IrExpression?.isRepeatableAccessor(): Boolean = isRepeatableGetter() || isRepeatableSetter()
|
||||
|
||||
enum class AccessType { AlwaysPublic, PrivateWhenNoBox, AlwaysPrivate }
|
||||
|
||||
class ReceiverBasedMfvcNodeInstance(
|
||||
private val scope: IrBlockBuilder,
|
||||
override val node: MfvcNode,
|
||||
override val typeArguments: TypeArguments,
|
||||
receiver: IrExpression?,
|
||||
val fields: List<IrField>?,
|
||||
val unboxMethod: IrSimpleFunction?,
|
||||
val accessType: AccessType,
|
||||
private val saveVariable: (IrVariable) -> Unit,
|
||||
) : MfvcNodeInstance {
|
||||
override val type: IrSimpleType = makeTypeFromMfvcNodeAndTypeArguments(node, typeArguments)
|
||||
|
||||
private val receiverCopier = ExpressionCopierImpl(receiver, scope, saveVariable)
|
||||
|
||||
private fun makeReceiverCopy() = receiverCopier.makeCopy()
|
||||
|
||||
init {
|
||||
require(fields == null || fields.isNotEmpty()) { "Empty list of fields" }
|
||||
require(node is RootMfvcNode == (unboxMethod == null)) { "Only root node has node getter" }
|
||||
}
|
||||
|
||||
override fun makeFlattenedGetterExpressions(scope: IrBlockBuilder): List<IrExpression> = when (node) {
|
||||
is LeafMfvcNode -> listOf(makeGetterExpression(scope))
|
||||
is MfvcNodeWithSubnodes -> when {
|
||||
node is IntermediateMfvcNode && canUsePrivateAccessFor(node) && fields != null ->
|
||||
fields.map { scope.irGetField(makeReceiverCopy(), it) }
|
||||
|
||||
node is IntermediateMfvcNode && !node.hasPureUnboxMethod -> {
|
||||
val value = makeGetterExpression(scope)
|
||||
val asVariable = scope.savableStandaloneVariableWithSetter(
|
||||
value,
|
||||
origin = IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_PARAMETER,
|
||||
saveVariable = saveVariable,
|
||||
isTemporary = true,
|
||||
)
|
||||
val root = node.rootNode
|
||||
val variableInstance =
|
||||
root.createInstanceFromBox(scope, typeArguments, scope.irGet(asVariable), accessType, saveVariable)
|
||||
variableInstance.makeFlattenedGetterExpressions(scope)
|
||||
}
|
||||
|
||||
else -> node.subnodes.flatMap { get(it.name)!!.makeFlattenedGetterExpressions(scope) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeGetterExpression(scope: IrBuilderWithScope): 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) })
|
||||
|
||||
unboxMethod != null -> irCall(unboxMethod).apply {
|
||||
val dispatchReceiverParameter = unboxMethod.dispatchReceiverParameter
|
||||
if (dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = makeReceiverCopy() ?: run {
|
||||
val erasedUpperBound = dispatchReceiverParameter.type.erasedUpperBound
|
||||
require(erasedUpperBound.isCompanion) { "Expected a dispatch receiver for:\n${unboxMethod.dump()}" }
|
||||
irGetObject(erasedUpperBound.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node is RootMfvcNode -> makeReceiverCopy()!!
|
||||
else -> error("Unbox method must exist for $node")
|
||||
}
|
||||
}
|
||||
|
||||
private fun canUsePrivateAccessFor(node: NameableMfvcNode) =
|
||||
node.hasPureUnboxMethod && accessType == AccessType.PrivateWhenNoBox || accessType == AccessType.AlwaysPrivate
|
||||
|
||||
override fun get(name: Name): ReceiverBasedMfvcNodeInstance? {
|
||||
val (newNode, _) = node.getSubnodeAndIndices(name) ?: return null
|
||||
return newNode.createInstanceFromBox(scope, typeArguments, makeReceiverCopy(), accessType, saveVariable)
|
||||
}
|
||||
|
||||
override fun makeStatements(scope: IrBuilderWithScope, values: List<IrExpression>): List<IrStatement> {
|
||||
checkValuesCount(values)
|
||||
require(fields != null) { "$node is immutable as it has custom getter and so no backing fields" }
|
||||
return fields.zip(values) { field, expr -> scope.irSetField(makeReceiverCopy(), field, expr) }
|
||||
}
|
||||
}
|
||||
|
||||
val MfvcNodeInstance.size: Int
|
||||
get() = node.leavesCount
|
||||
|
||||
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.
|
||||
*
|
||||
* It may be used when the variable will be used outside the current container so the declaration is added later when all usages are known.
|
||||
*/
|
||||
fun IrBuilderWithScope.savableStandaloneVariable(
|
||||
type: IrType,
|
||||
name: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin,
|
||||
isTemporary: Boolean = origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
saveVariable: (IrVariable) -> Unit,
|
||||
): IrVariable {
|
||||
val variable = if (isTemporary || name == null) scope.createTemporaryVariableDeclaration(
|
||||
type, name, isMutable,
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
) else IrVariableImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
symbol = IrVariableSymbolImpl(),
|
||||
name = Name.identifier(name),
|
||||
type = type,
|
||||
isVar = isMutable,
|
||||
isConst = false,
|
||||
isLateinit = false
|
||||
).apply {
|
||||
parent = this@savableStandaloneVariable.scope.getLocalDeclarationParent()
|
||||
}
|
||||
saveVariable(variable)
|
||||
return variable
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a variable and doesn't add it to a container. It saves the variable with given saveVariable. It adds irSet-based initialization.
|
||||
*
|
||||
* It may be used when the variable will be used outside the current container so the declaration is added later when all usages are known.
|
||||
*/
|
||||
fun <T : IrElement> IrStatementsBuilder<T>.savableStandaloneVariableWithSetter(
|
||||
expression: IrExpression,
|
||||
name: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin,
|
||||
isTemporary: Boolean = origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
saveVariable: (IrVariable) -> Unit,
|
||||
) = savableStandaloneVariable(expression.type, name, isMutable, origin, isTemporary, saveVariable).also {
|
||||
+irSet(it, expression)
|
||||
}
|
||||
@@ -117,11 +117,8 @@ fun IrType.defaultValue(startOffset: Int, endOffset: Int, context: JvmBackendCon
|
||||
}
|
||||
}
|
||||
|
||||
fun IrType.isInlineClassType(): Boolean = erasedUpperBound.isSingleFieldValueClass
|
||||
|
||||
fun IrType.isMultiFieldValueClassType(): Boolean = erasedUpperBound.isMultiFieldValueClass
|
||||
|
||||
fun IrType.isValueClassType(): Boolean = erasedUpperBound.isValue
|
||||
fun IrType.isInlineClassType(): Boolean =
|
||||
erasedUpperBound.isSingleFieldValueClass
|
||||
|
||||
val IrType.upperBound: IrType
|
||||
get() = erasedUpperBound.symbol.starProjectedType
|
||||
|
||||
@@ -8,7 +8,10 @@ package org.jetbrains.kotlin.backend.jvm.ir
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.lower.at
|
||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
import org.jetbrains.kotlin.backend.jvm.CachedFieldsForObjectInstances
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.ASSERTIONS_DISABLED_FIELD_NAME
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
@@ -243,9 +246,6 @@ fun IrSimpleFunction.copyCorrespondingPropertyFrom(source: IrSimpleFunction) {
|
||||
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.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
|
||||
@@ -256,13 +256,6 @@ val IrDeclaration.isStaticInlineClassReplacement: Boolean
|
||||
get() = origin == JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT
|
||||
|| origin == JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_CONSTRUCTOR
|
||||
|
||||
val IrDeclaration.isStaticMultiFieldValueClassReplacement: Boolean
|
||||
get() = origin == JvmLoweredDeclarationOrigin.STATIC_MULTI_FIELD_VALUE_CLASS_REPLACEMENT
|
||||
|| origin == JvmLoweredDeclarationOrigin.STATIC_MULTI_FIELD_VALUE_CLASS_CONSTRUCTOR
|
||||
|
||||
val IrDeclaration.isStaticValueClassReplacement: Boolean
|
||||
get() = isStaticMultiFieldValueClassReplacement || isStaticInlineClassReplacement
|
||||
|
||||
// On the IR backend we represent raw types as star projected types with a special synthetic annotation.
|
||||
// See `TypeTranslator.translateTypeAnnotations`.
|
||||
private fun JvmBackendContext.makeRawTypeAnnotation() =
|
||||
@@ -312,7 +305,7 @@ val IrClass.isSyntheticSingleton: Boolean
|
||||
|
||||
fun IrSimpleFunction.suspendFunctionOriginal(): IrSimpleFunction =
|
||||
if (isSuspend &&
|
||||
!isStaticValueClassReplacement &&
|
||||
!isStaticInlineClassReplacement &&
|
||||
!isOrOverridesDefaultParameterStub() &&
|
||||
parentAsClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS
|
||||
)
|
||||
|
||||
+1
-1
@@ -422,7 +422,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext, private val
|
||||
// TODO: get rid of this (probably via some special lowering)
|
||||
private fun mapOverriddenSpecialBuiltinIfNeeded(callee: IrFunction, superCall: Boolean): JvmMethodSignature? {
|
||||
// Do not remap calls to static replacements of inline class methods, since they have completely different signatures.
|
||||
if (callee.isStaticValueClassReplacement) return null
|
||||
if (callee.isStaticInlineClassReplacement) return null
|
||||
val overriddenSpecialBuiltinFunction =
|
||||
(callee.toIrBasedDescriptor().getOverriddenBuiltinReflectingJvmDescriptor() as IrBasedSimpleFunctionDescriptor?)?.owner
|
||||
if (overriddenSpecialBuiltinFunction != null && !superCall) {
|
||||
|
||||
@@ -53,13 +53,11 @@ fun <T : IrElement> IrStatementsBuilder<T>.irTemporary(
|
||||
nameHint: String? = null,
|
||||
irType: IrType = value?.type!!, // either value or irType should be supplied at callsite
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
): IrVariable {
|
||||
val temporary = scope.createTemporaryVariableDeclaration(
|
||||
irType, nameHint, isMutable,
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
endOffset = endOffset
|
||||
)
|
||||
value?.let { temporary.initializer = it }
|
||||
+temporary
|
||||
|
||||
@@ -43,9 +43,6 @@ interface IrDeclarationOrigin {
|
||||
object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER")
|
||||
object GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER")
|
||||
object GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER")
|
||||
object GENERATED_MULTI_FIELD_VALUE_CLASS_PARAMETER : IrDeclarationOriginImpl("GENERATED_MULTI_FIELD_VALUE_CLASS_PARAMETER")
|
||||
object TEMPORARY_MULTI_FIELD_VALUE_CLASS_VARIABLE : IrDeclarationOriginImpl("TEMPORARY_MULTI_FIELD_VALUE_CLASS_VARIABLE")
|
||||
object MULTI_FIELD_VALUE_CLASS_REPRESENTATION_VARIABLE : IrDeclarationOriginImpl("MULTI_FIELD_VALUE_CLASS_REPRESENTATION_VARIABLE")
|
||||
object LOCAL_FUNCTION : IrDeclarationOriginImpl("LOCAL_FUNCTION")
|
||||
object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA")
|
||||
object CATCH_PARAMETER : IrDeclarationOriginImpl("CATCH_PARAMETER")
|
||||
|
||||
@@ -128,7 +128,7 @@ abstract class DataClassMembersGenerator(
|
||||
fun generateEqualsMethodBody(properties: List<IrProperty>) {
|
||||
val irType = irClass.defaultType
|
||||
|
||||
if (!irClass.isValue) {
|
||||
if (!irClass.isSingleFieldValueClass) {
|
||||
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
|
||||
}
|
||||
+irIfThenReturnFalse(irNotIs(irOther(), irType))
|
||||
|
||||
+6
-143
@@ -1,9 +1,7 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses +ContextReceivers
|
||||
// CHECK_BYTECODE_LISTING
|
||||
// LANGUAGE: +ValueClasses
|
||||
|
||||
@JvmInline
|
||||
value class IC(val x: UInt)
|
||||
@@ -11,148 +9,13 @@ 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) {
|
||||
companion object {
|
||||
val SimpleMfvc.a1: SimpleMfvc
|
||||
get() = this
|
||||
value class SimpleMFVC(val x: UInt, val y: IC, val z: String)
|
||||
|
||||
@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
|
||||
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")
|
||||
require(smfvc(IC(4U), o2, 5U) == 12U)
|
||||
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"
|
||||
}
|
||||
fun box() = "OK" // todo real test
|
||||
@@ -1,175 +0,0 @@
|
||||
@kotlin.Metadata
|
||||
public final class ClassFlatteningKt {
|
||||
// source: 'classFlattening.kt'
|
||||
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 <init>(): void
|
||||
public synthetic method <init>(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 <clinit>(): void
|
||||
public method <init>(): 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 <init>(): void
|
||||
public synthetic method <init>(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 <clinit>(): void
|
||||
public method <init>(): 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 {
|
||||
// source: 'classFlattening.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-0-2: java.lang.String
|
||||
private final field field-1: int
|
||||
private final field field-2-0: int
|
||||
private final field field-2-1: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-2-2: java.lang.String
|
||||
private synthetic method <init>(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 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 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-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-0(): int
|
||||
public synthetic final method unbox-impl-2-1(): int
|
||||
public synthetic final method unbox-impl-2-2(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class IC {
|
||||
// source: 'classFlattening.kt'
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): IC
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX-pVg5ArA(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class SimpleMfvc$Companion {
|
||||
// source: 'classFlattening.kt'
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(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 {
|
||||
// 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 <clinit>(): void
|
||||
private synthetic method <init>(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 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 @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 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
|
||||
public static method toString-impl(p0: int, p1: int, p2: java.lang.String): java.lang.String
|
||||
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
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// https://youtrack.jetbrains.com/issue/KT-52236/Different-modality-in-psi-and-fir
|
||||
// CHECK_BYTECODE_LISTING
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: ANDROID, ANDROID_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
|
||||
@JvmInline
|
||||
value class A<T : Any>(val x: List<T>)
|
||||
|
||||
@JvmInline
|
||||
value class B(val x: UInt)
|
||||
|
||||
@JvmInline
|
||||
value class C(val x: Int, val y: B, val z: String = "3")
|
||||
|
||||
@JvmInline
|
||||
value class D(val x: C) {
|
||||
constructor(x: Int, y: UInt, z: Int) : this(C(x, B(y), z.toString()))
|
||||
|
||||
init {
|
||||
supply(x.x)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun inlined(x: Int, y: UInt, z: Int): D {
|
||||
return D(C(x, B(y), z.toString()))
|
||||
}
|
||||
|
||||
fun notInlined(x: Int, y: UInt, z: Int) = D(C(x, B(y), z.toString()))
|
||||
|
||||
@JvmInline
|
||||
value class E(val x: D) {
|
||||
var withNonTrivialSetters: D
|
||||
get() = TODO()
|
||||
set(_) = TODO()
|
||||
}
|
||||
|
||||
interface Base3 {
|
||||
val z: E
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class R<T : Any>(val x: Int, val y: UInt, override val z: E, val t: A<T>) : Base1, Base3
|
||||
|
||||
fun <T : List<Int>> f(r: R<T>) {
|
||||
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) {
|
||||
supply(e)
|
||||
}
|
||||
|
||||
fun <T : List<Int>> h(r: R<T>) {
|
||||
g(r.z)
|
||||
f(r)
|
||||
r
|
||||
C(2, B(3U), "")
|
||||
D(C(2, B(3U), ""))
|
||||
val x = D(C(2, B(3U), ""))
|
||||
var y = D(C(4, B(5U), "1"))
|
||||
supply(y)
|
||||
y = D(C(6, B(7U), "2"))
|
||||
y = D(6, 7U, 2)
|
||||
y = inlined(6, 7U, 2)
|
||||
y = notInlined(6, 7U, 2)
|
||||
supply(y)
|
||||
}
|
||||
|
||||
fun h1() {
|
||||
var y = inlined(1, 2U, 3) // todo fix box
|
||||
supply(y)
|
||||
y = inlined(4, 5U, 6)
|
||||
supply(y)
|
||||
}
|
||||
|
||||
interface Base1 {
|
||||
val fakeOverrideMFVC: R<List<Int>>
|
||||
get() = TODO()
|
||||
val fakeOverrideRegular: Int
|
||||
get() = TODO()
|
||||
}
|
||||
|
||||
interface Base2 {
|
||||
var l: R<List<Int>>
|
||||
}
|
||||
|
||||
interface Base4<T> {
|
||||
var l: T
|
||||
}
|
||||
|
||||
class NotInlined(override var l: R<List<Int>>, var y: Int) : Base1, Base2, Base4<R<List<Int>>> {
|
||||
override fun toString(): String = l.toString() + l.z.x.x.z
|
||||
|
||||
init {
|
||||
l = l
|
||||
}
|
||||
|
||||
fun trySetter() {
|
||||
l = l
|
||||
}
|
||||
|
||||
var withNonTrivialSetters: R<List<Int>>
|
||||
get() = TODO()
|
||||
set(_) = TODO()
|
||||
|
||||
var withNonTrivialSettersWithBF: R<List<Int>> = l
|
||||
get() {
|
||||
supply("1")
|
||||
field
|
||||
field.t
|
||||
field == field
|
||||
return field
|
||||
}
|
||||
set(value) {
|
||||
supply("3")
|
||||
field = value
|
||||
field = field
|
||||
supply("4")
|
||||
}
|
||||
|
||||
val withNonTrivialGettersWithBF: R<List<Int>> = l
|
||||
get() {
|
||||
supply("1")
|
||||
field
|
||||
field.t
|
||||
field == field
|
||||
return field
|
||||
}
|
||||
}
|
||||
|
||||
fun testVars(x: NotInlined) {
|
||||
x.l.toString()
|
||||
var y = x.l
|
||||
y.toString()
|
||||
y = x.l
|
||||
supply(y)
|
||||
x.l = x.l
|
||||
x.l = R<List<Int>>(x.l.x, x.l.y, x.l.z, x.l.t)
|
||||
}
|
||||
|
||||
fun reuseBoxed(list: MutableList<R<List<Int>>>) {
|
||||
list.add(list.last())
|
||||
}
|
||||
|
||||
val lines = mutableListOf<String>()
|
||||
|
||||
fun supply(x: Any) {
|
||||
lines.add(x.toString())
|
||||
}
|
||||
|
||||
fun equalsChecks1(x: A<List<Int>>) {}
|
||||
fun equalsChecks(left: R<List<Int>>, right: R<List<Int>>) {
|
||||
supply(left == right)
|
||||
supply(left as Any == right)
|
||||
supply(left == right as Any)
|
||||
supply(left as Any == right as Any)
|
||||
supply(null == right)
|
||||
supply(left == null)
|
||||
supply(null as Any? == right)
|
||||
supply(null as R<List<Int>>? == right)
|
||||
supply(left == null as Any?)
|
||||
supply(left == null as R<List<Int>>?)
|
||||
supply(left as R<List<Int>>? == right)
|
||||
supply(left == right as R<List<Int>>?)
|
||||
}
|
||||
|
||||
// todo add default parameters
|
||||
|
||||
fun box(): String {
|
||||
supply("#1")
|
||||
require(inlined(1, 2U, 3) == D(C(1, B(2U), "3")))
|
||||
supply("#2")
|
||||
require(notInlined(1, 2U, 3) == D(C(1, B(2U), "3")))
|
||||
supply("#3")
|
||||
val e = E(D(3, 4U, 5))
|
||||
supply("#4")
|
||||
val r = R(1, 2U, e, A(listOf(listOf(6))))
|
||||
supply("#5")
|
||||
f(r)
|
||||
supply("#6")
|
||||
g(e)
|
||||
supply("#7")
|
||||
h(r)
|
||||
supply("#8")
|
||||
h1()
|
||||
supply("#9")
|
||||
val ni = NotInlined(r, 7)
|
||||
supply("#10")
|
||||
ni.withNonTrivialGettersWithBF
|
||||
supply("#11")
|
||||
ni.withNonTrivialSettersWithBF = ni.withNonTrivialSettersWithBF
|
||||
supply("#12")
|
||||
supply(ni.toString())
|
||||
supply("#13")
|
||||
testVars(ni)
|
||||
supply("#14")
|
||||
reuseBoxed(mutableListOf(r))
|
||||
supply("#15")
|
||||
equalsChecks(r, r)
|
||||
supply("#16")
|
||||
equalsChecks1(A(listOf(listOf())))
|
||||
supply("#17")
|
||||
|
||||
val log = lines.joinToString("\n")
|
||||
val expectedLog =
|
||||
"""
|
||||
#1
|
||||
1
|
||||
1
|
||||
#2
|
||||
1
|
||||
1
|
||||
#3
|
||||
3
|
||||
#4
|
||||
#5
|
||||
R(x=1, y=2, z=E(x=D(x=C(x=3, y=B(x=4), z=5))), t=A(x=[[6]]))
|
||||
1
|
||||
2
|
||||
E(x=D(x=C(x=3, y=B(x=4), z=5)))
|
||||
A(x=[[6]])
|
||||
[[6]]
|
||||
D(x=C(x=3, y=B(x=4), z=5))
|
||||
C(x=3, y=B(x=4), z=5)
|
||||
3
|
||||
B(x=4)
|
||||
5
|
||||
4
|
||||
#6
|
||||
E(x=D(x=C(x=3, y=B(x=4), z=5)))
|
||||
#7
|
||||
E(x=D(x=C(x=3, y=B(x=4), z=5)))
|
||||
R(x=1, y=2, z=E(x=D(x=C(x=3, y=B(x=4), z=5))), t=A(x=[[6]]))
|
||||
1
|
||||
2
|
||||
E(x=D(x=C(x=3, y=B(x=4), z=5)))
|
||||
A(x=[[6]])
|
||||
[[6]]
|
||||
D(x=C(x=3, y=B(x=4), z=5))
|
||||
C(x=3, y=B(x=4), z=5)
|
||||
3
|
||||
B(x=4)
|
||||
5
|
||||
4
|
||||
2
|
||||
2
|
||||
4
|
||||
D(x=C(x=4, y=B(x=5), z=1))
|
||||
6
|
||||
6
|
||||
6
|
||||
6
|
||||
D(x=C(x=6, y=B(x=7), z=2))
|
||||
#8
|
||||
1
|
||||
D(x=C(x=1, y=B(x=2), z=3))
|
||||
4
|
||||
D(x=C(x=4, y=B(x=5), z=6))
|
||||
#9
|
||||
#10
|
||||
1
|
||||
#11
|
||||
1
|
||||
3
|
||||
4
|
||||
#12
|
||||
R(x=1, y=2, z=E(x=D(x=C(x=3, y=B(x=4), z=5))), t=A(x=[[6]]))5
|
||||
#13
|
||||
R(x=1, y=2, z=E(x=D(x=C(x=3, y=B(x=4), z=5))), t=A(x=[[6]]))
|
||||
#14
|
||||
#15
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
true
|
||||
true
|
||||
#16
|
||||
#17
|
||||
""".trimIndent()
|
||||
require(log == expectedLog) { log }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,317 +0,0 @@
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class A {
|
||||
// source: 'complex.kt'
|
||||
private final @org.jetbrains.annotations.NotNull field x: java.util.List
|
||||
private synthetic method <init>(p0: java.util.List): void
|
||||
public synthetic final static method box-impl(p0: java.util.List): A
|
||||
public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: java.util.List): java.util.List
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: java.util.List, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: java.util.List, p1: java.util.List): boolean
|
||||
public final @org.jetbrains.annotations.NotNull method getX(): java.util.List
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: java.util.List): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: java.util.List): java.lang.String
|
||||
public synthetic final method unbox-impl(): java.util.List
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class B {
|
||||
// source: 'complex.kt'
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): B
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX-pVg5ArA(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Base1$DefaultImpls {
|
||||
// source: 'complex.kt'
|
||||
public static @org.jetbrains.annotations.NotNull method getFakeOverrideMFVC(@org.jetbrains.annotations.NotNull p0: Base1): R
|
||||
public synthetic static method getFakeOverrideMFVC-0(p0: Base1): int
|
||||
public synthetic static method getFakeOverrideMFVC-1(p0: Base1): int
|
||||
public synthetic static method getFakeOverrideMFVC-2(p0: Base1): E
|
||||
public synthetic static method getFakeOverrideMFVC-2-0(p0: Base1): D
|
||||
public synthetic static method getFakeOverrideMFVC-2-0-0(p0: Base1): C
|
||||
public synthetic static method getFakeOverrideMFVC-2-0-0-0(p0: Base1): int
|
||||
public synthetic static method getFakeOverrideMFVC-2-0-0-1(p0: Base1): int
|
||||
public synthetic static method getFakeOverrideMFVC-2-0-0-2(p0: Base1): java.lang.String
|
||||
public synthetic static method getFakeOverrideMFVC-3(p0: Base1): java.util.List
|
||||
public static method getFakeOverrideRegular(@org.jetbrains.annotations.NotNull p0: Base1): int
|
||||
public final inner class Base1$DefaultImpls
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface Base1 {
|
||||
// source: 'complex.kt'
|
||||
public abstract @org.jetbrains.annotations.NotNull method getFakeOverrideMFVC(): R
|
||||
public synthetic abstract method getFakeOverrideMFVC-0(): int
|
||||
public synthetic abstract method getFakeOverrideMFVC-1(): int
|
||||
public synthetic abstract method getFakeOverrideMFVC-2(): E
|
||||
public synthetic abstract method getFakeOverrideMFVC-2-0(): D
|
||||
public synthetic abstract method getFakeOverrideMFVC-2-0-0(): C
|
||||
public synthetic abstract method getFakeOverrideMFVC-2-0-0-0(): int
|
||||
public synthetic abstract method getFakeOverrideMFVC-2-0-0-1(): int
|
||||
public synthetic abstract method getFakeOverrideMFVC-2-0-0-2(): java.lang.String
|
||||
public synthetic abstract method getFakeOverrideMFVC-3(): java.util.List
|
||||
public abstract method getFakeOverrideRegular(): int
|
||||
public final inner class Base1$DefaultImpls
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface Base2 {
|
||||
// source: 'complex.kt'
|
||||
public abstract @org.jetbrains.annotations.NotNull method getL(): R
|
||||
public synthetic abstract method getL-0(): int
|
||||
public synthetic abstract method getL-1(): int
|
||||
public synthetic abstract method getL-2(): E
|
||||
public synthetic abstract method getL-2-0(): D
|
||||
public synthetic abstract method getL-2-0-0(): C
|
||||
public synthetic abstract method getL-2-0-0-0(): int
|
||||
public synthetic abstract method getL-2-0-0-1(): int
|
||||
public synthetic abstract method getL-2-0-0-2(): java.lang.String
|
||||
public synthetic abstract method getL-3(): java.util.List
|
||||
public abstract method setL-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface Base3 {
|
||||
// source: 'complex.kt'
|
||||
public abstract @org.jetbrains.annotations.NotNull method getZ(): E
|
||||
public synthetic abstract method getZ-0(): D
|
||||
public synthetic abstract method getZ-0-0(): C
|
||||
public synthetic abstract method getZ-0-0-0(): int
|
||||
public synthetic abstract method getZ-0-0-1(): int
|
||||
public synthetic abstract method getZ-0-0-2(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface Base4 {
|
||||
// source: 'complex.kt'
|
||||
public abstract method getL(): java.lang.Object
|
||||
public abstract method setL(p0: java.lang.Object): void
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class C {
|
||||
// source: 'complex.kt'
|
||||
private final field field-0: int
|
||||
private final field field-1: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-2: java.lang.String
|
||||
private synthetic method <init>(p0: int, p1: int, p2: java.lang.String): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int, p2: java.lang.String): C
|
||||
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 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
|
||||
public static method toString-impl(p0: int, p1: int, p2: java.lang.String): java.lang.String
|
||||
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
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ComplexKt {
|
||||
// source: 'complex.kt'
|
||||
private final static @org.jetbrains.annotations.NotNull field lines: java.util.List
|
||||
static method <clinit>(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method equalsChecks-GPBa7dw(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List, p6: int, p7: int, p8: int, p9: int, @org.jetbrains.annotations.NotNull p10: java.lang.String, @org.jetbrains.annotations.NotNull p11: java.util.List): void
|
||||
public final static method equalsChecks1-iUtXLc0(@org.jetbrains.annotations.NotNull p0: java.util.List): void
|
||||
public final static method f-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
|
||||
public final static method g-sUp7gFk(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): void
|
||||
public final static @org.jetbrains.annotations.NotNull method getLines(): java.util.List
|
||||
public final static method h-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
|
||||
public final static method h1(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method inlined-OsBMiQA(p0: int, p1: int, p2: int): D
|
||||
public final static @org.jetbrains.annotations.NotNull method notInlined-OsBMiQA(p0: int, p1: int, p2: int): D
|
||||
public final static method reuseBoxed(@org.jetbrains.annotations.NotNull p0: java.util.List): 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
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class D {
|
||||
// source: 'complex.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-0-2: java.lang.String
|
||||
private synthetic method <init>(p0: int, p1: int, p2: java.lang.String): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int, p2: java.lang.String): D
|
||||
public final static method constructor-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): void
|
||||
public final static @org.jetbrains.annotations.NotNull method constructor-impl(p0: int, p1: int, p2: int): 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 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
|
||||
public static method toString-impl(p0: int, p1: int, p2: java.lang.String): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): C
|
||||
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
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class E {
|
||||
// source: 'complex.kt'
|
||||
private final field field-0-0-0: int
|
||||
private final field field-0-0-1: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-0-0-2: java.lang.String
|
||||
private synthetic method <init>(p0: int, p1: int, p2: java.lang.String): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int, p2: java.lang.String): E
|
||||
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 @org.jetbrains.annotations.NotNull method getWithNonTrivialSetters-impl(p0: int, p1: int, @org.jetbrains.annotations.NotNull p2: java.lang.String): 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
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int, p2: java.lang.String): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): D
|
||||
public synthetic final method unbox-impl-0-0(): C
|
||||
public synthetic final method unbox-impl-0-0-0(): int
|
||||
public synthetic final method unbox-impl-0-0-1(): int
|
||||
public synthetic final method unbox-impl-0-0-2(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class NotInlined {
|
||||
// source: 'complex.kt'
|
||||
private field l-0: int
|
||||
private field l-1: int
|
||||
private field l-2-0-0-0: int
|
||||
private field l-2-0-0-1: int
|
||||
private @org.jetbrains.annotations.NotNull field l-2-0-0-2: java.lang.String
|
||||
private @org.jetbrains.annotations.NotNull field l-3: java.util.List
|
||||
private final field withNonTrivialGettersWithBF-0: int
|
||||
private final field withNonTrivialGettersWithBF-1: int
|
||||
private final field withNonTrivialGettersWithBF-2-0-0-0: int
|
||||
private final field withNonTrivialGettersWithBF-2-0-0-1: int
|
||||
private final @org.jetbrains.annotations.NotNull field withNonTrivialGettersWithBF-2-0-0-2: java.lang.String
|
||||
private final @org.jetbrains.annotations.NotNull field withNonTrivialGettersWithBF-3: java.util.List
|
||||
private field withNonTrivialSettersWithBF-0: int
|
||||
private field withNonTrivialSettersWithBF-1: int
|
||||
private field withNonTrivialSettersWithBF-2-0-0-0: int
|
||||
private field withNonTrivialSettersWithBF-2-0-0-1: int
|
||||
private @org.jetbrains.annotations.NotNull field withNonTrivialSettersWithBF-2-0-0-2: java.lang.String
|
||||
private @org.jetbrains.annotations.NotNull field withNonTrivialSettersWithBF-3: java.util.List
|
||||
private field y: int
|
||||
private method <init>(p0: int, p1: int, p2: int, p3: int, p4: java.lang.String, p5: java.util.List, p6: int): void
|
||||
public synthetic method <init>(p0: int, p1: int, p2: int, p3: int, p4: java.lang.String, p5: java.util.List, p6: int, p7: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public @org.jetbrains.annotations.NotNull method getFakeOverrideMFVC(): R
|
||||
public method getFakeOverrideRegular(): int
|
||||
public @org.jetbrains.annotations.NotNull method getL(): R
|
||||
public synthetic bridge method getL(): java.lang.Object
|
||||
public synthetic method getL-0(): int
|
||||
public synthetic method getL-1(): int
|
||||
public synthetic method getL-2(): E
|
||||
public synthetic method getL-2-0(): D
|
||||
public synthetic method getL-2-0-0(): C
|
||||
public synthetic method getL-2-0-0-0(): int
|
||||
public synthetic method getL-2-0-0-1(): int
|
||||
public synthetic method getL-2-0-0-2(): java.lang.String
|
||||
public synthetic method getL-3(): java.util.List
|
||||
public final @org.jetbrains.annotations.NotNull method getWithNonTrivialGettersWithBF(): R
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-0(): int
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-1(): int
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-2(): E
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-2-0(): D
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-2-0-0(): C
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-2-0-0-0(): int
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-2-0-0-1(): int
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-2-0-0-2(): java.lang.String
|
||||
public synthetic final method getWithNonTrivialGettersWithBF-3(): java.util.List
|
||||
public final @org.jetbrains.annotations.NotNull method getWithNonTrivialSetters(): R
|
||||
public synthetic final method getWithNonTrivialSetters-0(): int
|
||||
public synthetic final method getWithNonTrivialSetters-1(): int
|
||||
public synthetic final method getWithNonTrivialSetters-2(): E
|
||||
public synthetic final method getWithNonTrivialSetters-2-0(): D
|
||||
public synthetic final method getWithNonTrivialSetters-2-0-0(): C
|
||||
public synthetic final method getWithNonTrivialSetters-2-0-0-0(): int
|
||||
public synthetic final method getWithNonTrivialSetters-2-0-0-1(): int
|
||||
public synthetic final method getWithNonTrivialSetters-2-0-0-2(): java.lang.String
|
||||
public synthetic final method getWithNonTrivialSetters-3(): java.util.List
|
||||
public final @org.jetbrains.annotations.NotNull method getWithNonTrivialSettersWithBF(): R
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-0(): int
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-1(): int
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-2(): E
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-2-0(): D
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-2-0-0(): C
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-2-0-0-0(): int
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-2-0-0-1(): int
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-2-0-0-2(): java.lang.String
|
||||
public synthetic final method getWithNonTrivialSettersWithBF-3(): java.util.List
|
||||
public final method getY(): int
|
||||
public synthetic bridge method setL(p0: java.lang.Object): void
|
||||
public method setL-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
|
||||
public final method setWithNonTrivialSetters-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
|
||||
public final method setWithNonTrivialSettersWithBF-sUp7gFk(p0: int, p1: int, p2: int, p3: int, @org.jetbrains.annotations.NotNull p4: java.lang.String, @org.jetbrains.annotations.NotNull p5: java.util.List): void
|
||||
public final method setY(p0: int): void
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public final method trySetter(): void
|
||||
public final inner class Base1$DefaultImpls
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class R {
|
||||
// source: 'complex.kt'
|
||||
private final field field-0: int
|
||||
private final field field-1: int
|
||||
private final field field-2-0-0-0: int
|
||||
private final field field-2-0-0-1: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-2-0-0-2: java.lang.String
|
||||
private final @org.jetbrains.annotations.NotNull field field-3: java.util.List
|
||||
private synthetic method <init>(p0: int, p1: int, p2: int, p3: int, p4: java.lang.String, p5: java.util.List): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int, p2: int, p3: int, p4: java.lang.String, p5: java.util.List): R
|
||||
public final static method constructor-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): void
|
||||
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: java.lang.String, p5: java.util.List, p6: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int, p4: java.lang.String, p5: java.util.List, p6: int, p7: int, p8: int, p9: int, p10: java.lang.String, p11: java.util.List): boolean
|
||||
public @org.jetbrains.annotations.NotNull method getFakeOverrideMFVC(): 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 @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 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
|
||||
public static method toString-impl(p0: int, p1: int, p2: int, p3: int, p4: java.lang.String, p5: java.util.List): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): int
|
||||
public synthetic final method unbox-impl-1(): int
|
||||
public synthetic final method unbox-impl-2(): E
|
||||
public synthetic final method unbox-impl-2-0(): D
|
||||
public synthetic final method unbox-impl-2-0-0(): C
|
||||
public synthetic final method unbox-impl-2-0-0-0(): int
|
||||
public synthetic final method unbox-impl-2-0-0-1(): int
|
||||
public synthetic final method unbox-impl-2-0-0-2(): java.lang.String
|
||||
public synthetic final method unbox-impl-3(): java.util.List
|
||||
public final inner class Base1$DefaultImpls
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
// 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) {
|
||||
init {
|
||||
counter++
|
||||
}
|
||||
companion object {
|
||||
@JvmStatic
|
||||
var counter: Int = 0
|
||||
}
|
||||
}
|
||||
|
||||
fun ifExpr() = if (DPoint(0.0, 1.0).x > 0.0) DPoint(2.0, 3.0) else DPoint(4.0, 5.0)
|
||||
|
||||
fun whenExpr() = when {
|
||||
DPoint(6.0, 7.0).x > 0.0 -> DPoint(8.0, 9.0)
|
||||
DPoint(10.0, 11.0).x > 0.0 -> DPoint(12.0, 13.0)
|
||||
else -> DPoint(14.0, 15.0)
|
||||
}
|
||||
|
||||
fun ifBody() {
|
||||
if (DPoint(0.0, 1.0).x > 0.0) DPoint(2.0, 3.0) else DPoint(4.0, 5.0)
|
||||
val x = if (DPoint(0.0, 1.0).x > 0.0) DPoint(2.0, 3.0) else DPoint(4.0, 5.0)
|
||||
require(x == DPoint(4.0, 5.0))
|
||||
}
|
||||
|
||||
fun whenBody() {
|
||||
when {
|
||||
DPoint(6.0, 7.0).x > 0.0 -> DPoint(8.0, 9.0)
|
||||
DPoint(10.0, 11.0).x > 0.0 -> DPoint(12.0, 13.0)
|
||||
else -> DPoint(14.0, 15.0)
|
||||
}
|
||||
val x = when {
|
||||
DPoint(6.0, 7.0).x > 0.0 -> DPoint(8.0, 9.0)
|
||||
DPoint(10.0, 11.0).x > 0.0 -> DPoint(12.0, 13.0)
|
||||
else -> DPoint(14.0, 15.0)
|
||||
}
|
||||
require(x == DPoint(8.0, 9.0))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
ifBody()
|
||||
whenBody()
|
||||
require(ifExpr() == DPoint(4.0, 5.0))
|
||||
require(whenExpr() == DPoint(8.0, 9.0))
|
||||
require(DPoint.counter == 5 + 5 + 2 + 1 + 2 + 1)
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
@kotlin.Metadata
|
||||
public final class ConditionalExpressionsKt {
|
||||
// source: 'conditionalExpressions.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method ifBody(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method ifExpr(): DPoint
|
||||
public final static method whenBody(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method whenExpr(): DPoint
|
||||
public final inner class DPoint$Companion
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class DPoint$Companion {
|
||||
// source: 'conditionalExpressions.kt'
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getCounter$annotations(): void
|
||||
public final method getCounter(): int
|
||||
public final method setCounter(p0: int): void
|
||||
public final inner class DPoint$Companion
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class DPoint {
|
||||
// source: 'conditionalExpressions.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull field Companion: DPoint$Companion
|
||||
private static field counter: int
|
||||
private final field field-0: double
|
||||
private final field field-1: double
|
||||
static method <clinit>(): void
|
||||
private synthetic method <init>(p0: double, p1: double): void
|
||||
public synthetic final static method access$getCounter$cp(): int
|
||||
public synthetic final static method access$setCounter$cp(p0: int): 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 static method getCounter(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: double, p1: double): int
|
||||
public final static method setCounter(p0: int): void
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: double, p1: double): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): double
|
||||
public synthetic final method unbox-impl-1(): double
|
||||
public final inner class DPoint$Companion
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// https://youtrack.jetbrains.com/issue/KT-52236/Different-modality-in-psi-and-fir
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
// CHECK_BYTECODE_LISTING
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class F1(val x: Int)
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class A {
|
||||
// source: 'equality.kt'
|
||||
private final field field-0: int
|
||||
private final field field-1: int
|
||||
private final field field-2-0: int
|
||||
private final field field-2-1: int
|
||||
private final field field-3: int
|
||||
private final field field-4: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-5: java.lang.String
|
||||
private final field field-6: int
|
||||
private final field field-7: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-8: java.lang.String
|
||||
private synthetic method <init>(p0: int, p1: int, p2: int, p3: int, p4: int, p5: int, p6: java.lang.String, p7: int, p8: int, p9: java.lang.String): void
|
||||
public synthetic final static method box-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): A
|
||||
public final static method constructor-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): void
|
||||
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 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
|
||||
public static method toString-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): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): int
|
||||
public synthetic final method unbox-impl-1(): int
|
||||
public synthetic final method unbox-impl-2(): F3
|
||||
public synthetic final method unbox-impl-2-0(): int
|
||||
public synthetic final method unbox-impl-2-1(): int
|
||||
public synthetic final method unbox-impl-3(): int
|
||||
public synthetic final method unbox-impl-4(): int
|
||||
public synthetic final method unbox-impl-5(): java.lang.String
|
||||
public synthetic final method unbox-impl-6(): int
|
||||
public synthetic final method unbox-impl-7(): int
|
||||
public synthetic final method unbox-impl-8(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class B {
|
||||
// source: 'equality.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private final field field-0-2-0: int
|
||||
private final field field-0-2-1: int
|
||||
private final field field-0-3: int
|
||||
private final field field-0-4: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-0-5: java.lang.String
|
||||
private final field field-0-6: int
|
||||
private final field field-0-7: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-0-8: java.lang.String
|
||||
private final field field-1-0: int
|
||||
private final field field-1-1: int
|
||||
private final field field-1-2-0: int
|
||||
private final field field-1-2-1: int
|
||||
private final field field-1-3: int
|
||||
private final field field-1-4: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-1-5: java.lang.String
|
||||
private final field field-1-6: int
|
||||
private final field field-1-7: int
|
||||
private final @org.jetbrains.annotations.NotNull field field-1-8: java.lang.String
|
||||
private synthetic method <init>(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): void
|
||||
public synthetic final static method box-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): B
|
||||
public final static method constructor-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): void
|
||||
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 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
|
||||
public static @org.jetbrains.annotations.NotNull method toString-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): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): A
|
||||
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(): F3
|
||||
public synthetic final method unbox-impl-0-2-0(): int
|
||||
public synthetic final method unbox-impl-0-2-1(): int
|
||||
public synthetic final method unbox-impl-0-3(): int
|
||||
public synthetic final method unbox-impl-0-4(): int
|
||||
public synthetic final method unbox-impl-0-5(): java.lang.String
|
||||
public synthetic final method unbox-impl-0-6(): int
|
||||
public synthetic final method unbox-impl-0-7(): int
|
||||
public synthetic final method unbox-impl-0-8(): java.lang.String
|
||||
public synthetic final method unbox-impl-1(): A
|
||||
public synthetic final method unbox-impl-1-0(): int
|
||||
public synthetic final method unbox-impl-1-1(): int
|
||||
public synthetic final method unbox-impl-1-2(): F3
|
||||
public synthetic final method unbox-impl-1-2-0(): int
|
||||
public synthetic final method unbox-impl-1-2-1(): int
|
||||
public synthetic final method unbox-impl-1-3(): int
|
||||
public synthetic final method unbox-impl-1-4(): int
|
||||
public synthetic final method unbox-impl-1-5(): java.lang.String
|
||||
public synthetic final method unbox-impl-1-6(): int
|
||||
public synthetic final method unbox-impl-1-7(): int
|
||||
public synthetic final method unbox-impl-1-8(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class EqualityKt {
|
||||
// source: 'equality.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class F1 {
|
||||
// source: 'equality.kt'
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): F1
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class F2 {
|
||||
// source: 'equality.kt'
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): F2
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX-pVg5ArA(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class F3 {
|
||||
// source: 'equality.kt'
|
||||
private final field field-0: int
|
||||
private final field field-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): F3
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): int
|
||||
public synthetic final method unbox-impl-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class F4 {
|
||||
// source: 'equality.kt'
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): F4
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class F5 {
|
||||
// source: 'equality.kt'
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): F5
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX-pVg5ArA(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class F6 {
|
||||
// source: 'equality.kt'
|
||||
private final @org.jetbrains.annotations.NotNull field x: java.lang.String
|
||||
private synthetic method <init>(p0: java.lang.String): void
|
||||
public synthetic final static method box-impl(p0: java.lang.String): F6
|
||||
public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: java.lang.String, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: java.lang.String, p1: java.lang.String): boolean
|
||||
public final @org.jetbrains.annotations.NotNull method getX(): java.lang.String
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: java.lang.String): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: java.lang.String): java.lang.String
|
||||
public synthetic final method unbox-impl(): java.lang.String
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// 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"
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
// CHECK_BYTECODE_LISTING
|
||||
|
||||
@JvmInline
|
||||
value class DPoint(val x: Double, val y: Double)
|
||||
|
||||
class A(var x: DPoint) {
|
||||
init { x = DPoint(2.0, 3.0) }
|
||||
}
|
||||
|
||||
class B() {
|
||||
var a = DPoint(4.0, 5.0)
|
||||
val b = a
|
||||
init { a = DPoint(6.0, 7.0) }
|
||||
val c = a
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
require(A(DPoint(0.0, 1.0)).x == DPoint(2.0, 3.0)) { "No init used" }
|
||||
require(B().a == DPoint(6.0, 7.0)) { "No init used" }
|
||||
require(B().b == DPoint(4.0, 5.0)) { "Wrong init order used" }
|
||||
require(B().c == DPoint(6.0, 7.0)) { "Wrong init order used" }
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
@kotlin.Metadata
|
||||
public final class A {
|
||||
// source: 'mfvcFieldInitializationOrder.kt'
|
||||
private field x-0: double
|
||||
private field x-1: double
|
||||
public method <init>(p0: double, p1: double): void
|
||||
public final @org.jetbrains.annotations.NotNull method getX(): DPoint
|
||||
public synthetic final method getX-0(): double
|
||||
public synthetic final method getX-1(): double
|
||||
public final method setX-sUp7gFk(p0: double, p1: double): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class B {
|
||||
// source: 'mfvcFieldInitializationOrder.kt'
|
||||
private field a-0: double
|
||||
private field a-1: double
|
||||
private final field b-0: double
|
||||
private final field b-1: double
|
||||
private final field c-0: double
|
||||
private final field c-1: double
|
||||
public method <init>(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getA(): DPoint
|
||||
public synthetic final method getA-0(): double
|
||||
public synthetic final method getA-1(): double
|
||||
public final @org.jetbrains.annotations.NotNull method getB(): DPoint
|
||||
public synthetic final method getB-0(): double
|
||||
public synthetic final method getB-1(): double
|
||||
public final @org.jetbrains.annotations.NotNull method getC(): DPoint
|
||||
public synthetic final method getC-0(): double
|
||||
public synthetic final method getC-1(): double
|
||||
public final method setA-sUp7gFk(p0: double, p1: double): void
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class DPoint {
|
||||
// source: 'mfvcFieldInitializationOrder.kt'
|
||||
private final field field-0: double
|
||||
private final field field-1: double
|
||||
private synthetic method <init>(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 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 MfvcFieldInitializationOrderKt {
|
||||
// source: 'mfvcFieldInitializationOrder.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
@@ -1,311 +0,0 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// https://youtrack.jetbrains.com/issue/KT-52236/Different-modality-in-psi-and-fir
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
// CHECK_BYTECODE_LISTING
|
||||
|
||||
interface AbstractPoint<T> {
|
||||
val x: T
|
||||
val y: T
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class DPoint(override val x: Double, override val y: Double): AbstractPoint<Double>
|
||||
|
||||
interface GenericMFVCHolder<T> {
|
||||
var p: T
|
||||
var p1: T
|
||||
}
|
||||
|
||||
interface GenericMFVCHolderWithMFVCUpperBound<T : DPoint> {
|
||||
var p: T
|
||||
var p1: T
|
||||
}
|
||||
|
||||
interface ReifiedMFVCHolder {
|
||||
var p: DPoint
|
||||
var p1: DPoint
|
||||
}
|
||||
|
||||
data class DataClassException(val value: Any?): Exception()
|
||||
|
||||
interface GenericMFVCHolderWithImpls<T> {
|
||||
var p: T
|
||||
get() = throw DataClassException(1)
|
||||
set(value) = throw DataClassException(2 to value)
|
||||
|
||||
var p1: T
|
||||
get() = throw DataClassException(3)
|
||||
set(value) = throw DataClassException(4 to value)
|
||||
}
|
||||
|
||||
interface GenericMFVCHolderWithMFVCUpperBoundWithImpls<T : DPoint> {
|
||||
var p: T
|
||||
get() = throw DataClassException(5)
|
||||
set(value) = throw DataClassException(6 to value)
|
||||
|
||||
var p1: T
|
||||
get() = throw DataClassException(7)
|
||||
set(value) = throw DataClassException(8 to value)
|
||||
}
|
||||
|
||||
interface ReifiedMFVCHolderWithImpls {
|
||||
var p: DPoint
|
||||
get() = throw DataClassException(9)
|
||||
set(value) = throw DataClassException(10 to value)
|
||||
|
||||
var p1: DPoint
|
||||
get() = throw DataClassException(11)
|
||||
set(value) = throw DataClassException(12 to value)
|
||||
}
|
||||
|
||||
class RealOverride(override var p: DPoint) : GenericMFVCHolder<DPoint>, ReifiedMFVCHolder, GenericMFVCHolderWithMFVCUpperBound<DPoint> {
|
||||
override var p1: DPoint
|
||||
get() = throw DataClassException(13)
|
||||
set(value) = throw DataClassException(14 to value)
|
||||
}
|
||||
|
||||
class GenericFakeOverride : GenericMFVCHolderWithImpls<DPoint>
|
||||
class ReifiedFakeOverride : ReifiedMFVCHolderWithImpls
|
||||
class GenericFakeOverrideWithMFVCUpperBound : GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>
|
||||
|
||||
|
||||
@JvmInline
|
||||
value class GenericFakeOverrideMFVC(val field1: Double, val field2: Double) : GenericMFVCHolderWithImpls<DPoint>
|
||||
@JvmInline
|
||||
value class ReifiedFakeOverrideMFVC(val field1: Double, val field2: Double) : ReifiedMFVCHolderWithImpls
|
||||
@JvmInline
|
||||
value class GenericFakeOverrideMFVCWithMFVCUpperBound(val field1: Double, val field2: Double) : GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>
|
||||
|
||||
|
||||
interface SomePointInterface<T> {
|
||||
var somethingRegular: Int
|
||||
|
||||
var somethingGeneric: T
|
||||
|
||||
var somethingMFVC: DPoint
|
||||
}
|
||||
|
||||
interface SomePointInterfaceWithMFVCBound<T : DPoint> {
|
||||
var somethingRegular: Int
|
||||
|
||||
var somethingGeneric: T
|
||||
|
||||
var somethingMFVC: DPoint
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class DPointWithInterface(val x: Double, val y: Double) : SomePointInterface<DPoint>, SomePointInterfaceWithMFVCBound<DPoint> {
|
||||
override var somethingGeneric: DPoint
|
||||
get() = throw DataClassException(15)
|
||||
set(value) = throw DataClassException(16 to value)
|
||||
|
||||
override var somethingMFVC: DPoint
|
||||
get() = throw DataClassException(17)
|
||||
set(value) = throw DataClassException(18 to value)
|
||||
|
||||
override var somethingRegular: Int
|
||||
get() = throw DataClassException(19)
|
||||
set(value) = throw DataClassException(20 to value)
|
||||
}
|
||||
|
||||
|
||||
interface AbstractSegment<T> {
|
||||
val p1: T
|
||||
val p2: T
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class DSegment(override val p1: DPoint, override val p2: DPoint): AbstractSegment<DPoint>
|
||||
|
||||
fun <T> equal(expected: () -> T, actual: () -> T) {
|
||||
val expectedResult = runCatching { expected() }
|
||||
val actualResult = runCatching { actual() }
|
||||
require(expectedResult == actualResult) { "Expected: $expectedResult\nActual: $actualResult" }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val dPoint = DPoint(1.0, 2.0)
|
||||
|
||||
val lam1: () -> DPoint = { throw DataClassException(1) }
|
||||
val lam2: () -> Unit = { throw DataClassException(2 to dPoint) }
|
||||
val lam3: () -> DPoint = { throw DataClassException(3) }
|
||||
val lam4: () -> Unit = { throw DataClassException(4 to dPoint) }
|
||||
val lam5: () -> DPoint = { throw DataClassException(5) }
|
||||
val lam6: () -> Unit = { throw DataClassException(6 to dPoint) }
|
||||
val lam7: () -> DPoint = { throw DataClassException(7) }
|
||||
val lam8: () -> Unit = { throw DataClassException(8 to dPoint) }
|
||||
val lam9: () -> DPoint = { throw DataClassException(9) }
|
||||
val lam10: () -> Unit = { throw DataClassException(10 to dPoint) }
|
||||
val lam11: () -> DPoint = { throw DataClassException(11) }
|
||||
val lam12: () -> Unit = { throw DataClassException(12 to dPoint) }
|
||||
val lam13: () -> DPoint = { throw DataClassException(13) }
|
||||
val lam14: () -> Unit = { throw DataClassException(14 to dPoint) }
|
||||
val lam15: () -> DPoint = { throw DataClassException(15) }
|
||||
val lam16: () -> Unit = { throw DataClassException(16 to dPoint) }
|
||||
val lam17: () -> DPoint = { throw DataClassException(17) }
|
||||
val lam18: () -> Unit = { throw DataClassException(18 to dPoint) }
|
||||
val lam19: () -> Int = { throw DataClassException(19) }
|
||||
val lam20: () -> Unit = { throw DataClassException(20 to 1) }
|
||||
val emptyLam = {}
|
||||
val dPointLam = { dPoint }
|
||||
val otherDPoint = DPoint(3.0, 4.0)
|
||||
val otherDPointLam = { otherDPoint }
|
||||
equal({ "DPoint(x=1.0, y=2.0)" }, { dPoint.toString() })
|
||||
equal({ "DPoint(x=1.0, y=2.0)" }, { (dPoint as Any).toString() })
|
||||
|
||||
equal({ true }, { dPoint.equals(dPoint) })
|
||||
equal({ true }, { dPoint.equals(dPoint as Any) })
|
||||
equal({ true }, { (dPoint as Any).equals(dPoint) })
|
||||
equal({ true }, { (dPoint as Any).equals(dPoint as Any) })
|
||||
|
||||
equal({ false }, { dPoint.equals(otherDPoint) })
|
||||
equal({ false }, { dPoint.equals(otherDPoint as Any) })
|
||||
equal({ false }, { (dPoint as Any).equals(otherDPoint) })
|
||||
equal({ false }, { (dPoint as Any).equals(otherDPoint as Any) })
|
||||
|
||||
equal({ dPoint.hashCode() }, { (dPoint as Any).hashCode() })
|
||||
|
||||
equal({ 1.0 }, { dPoint.x })
|
||||
equal({ 1.0 }, { (dPoint as AbstractPoint<Double>).x })
|
||||
equal({ 2.0 }, { dPoint.y })
|
||||
equal({ 2.0 }, { (dPoint as AbstractPoint<Double>).y })
|
||||
|
||||
|
||||
val realOverride = RealOverride(dPoint)
|
||||
|
||||
equal(dPointLam, { realOverride.p })
|
||||
equal(dPointLam, { (realOverride as GenericMFVCHolder<DPoint>).p })
|
||||
equal(lam13, { realOverride.p1 })
|
||||
equal(lam13, { (realOverride as GenericMFVCHolder<DPoint>).p1 })
|
||||
equal(dPointLam, { (realOverride as ReifiedMFVCHolder).p })
|
||||
equal(lam13, { realOverride.p1 })
|
||||
equal(lam13, { (realOverride as ReifiedMFVCHolder).p1 })
|
||||
equal(dPointLam, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p })
|
||||
equal(lam13, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p1 })
|
||||
|
||||
|
||||
equal(emptyLam, { realOverride.p = dPoint })
|
||||
equal(emptyLam, { (realOverride as GenericMFVCHolder<DPoint>).p = dPoint })
|
||||
equal(lam14, { realOverride.p1 = dPoint })
|
||||
equal(lam14, { (realOverride as GenericMFVCHolder<DPoint>).p1 = dPoint })
|
||||
equal(emptyLam, { (realOverride as ReifiedMFVCHolder).p = dPoint })
|
||||
equal(lam14, { (realOverride as ReifiedMFVCHolder).p1 = dPoint })
|
||||
equal(emptyLam, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p = dPoint })
|
||||
equal(lam14, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p1 = dPoint })
|
||||
|
||||
|
||||
val genericFakeOverride = GenericFakeOverride()
|
||||
|
||||
equal(lam1, { genericFakeOverride.p })
|
||||
equal(lam1, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p })
|
||||
equal(lam3, { genericFakeOverride.p1 })
|
||||
equal(lam3, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p1 })
|
||||
val reifiedFakeOverride = ReifiedFakeOverride()
|
||||
equal(lam9, { reifiedFakeOverride.p })
|
||||
equal(lam9, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p })
|
||||
equal(lam11, { reifiedFakeOverride.p1 })
|
||||
equal(lam11, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p1 })
|
||||
val genericFakeOverrideWithMFVCUpperBound = GenericFakeOverrideWithMFVCUpperBound()
|
||||
equal(lam5, { genericFakeOverrideWithMFVCUpperBound.p })
|
||||
equal(lam5, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p })
|
||||
equal(lam7, { genericFakeOverrideWithMFVCUpperBound.p1 })
|
||||
equal(lam7, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 })
|
||||
|
||||
equal(lam2, { genericFakeOverride.p = dPoint })
|
||||
equal(lam2, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam4, { genericFakeOverride.p1 = dPoint })
|
||||
equal(lam4, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p1 = dPoint })
|
||||
equal(lam10, { reifiedFakeOverride.p = dPoint })
|
||||
equal(lam10, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p = dPoint })
|
||||
equal(lam12, { reifiedFakeOverride.p1 = dPoint })
|
||||
equal(lam12, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p1 = dPoint })
|
||||
equal(lam6, { genericFakeOverrideWithMFVCUpperBound.p = dPoint })
|
||||
equal(lam6, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam8, { genericFakeOverrideWithMFVCUpperBound.p1 = dPoint })
|
||||
equal(lam8, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 = dPoint })
|
||||
|
||||
|
||||
val genericFakeOverrideMFVC = GenericFakeOverrideMFVC(1.0, 2.0)
|
||||
|
||||
equal(lam1, { genericFakeOverrideMFVC.p })
|
||||
equal(lam1, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p })
|
||||
equal(lam3, { genericFakeOverrideMFVC.p1 })
|
||||
equal(lam3, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p1 })
|
||||
|
||||
val reifiedFakeOverrideMFVC = ReifiedFakeOverrideMFVC(1.0, 2.0)
|
||||
equal(lam9, { reifiedFakeOverrideMFVC.p })
|
||||
equal(lam9, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p })
|
||||
equal(lam11, { reifiedFakeOverrideMFVC.p1 })
|
||||
equal(lam11, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p1 })
|
||||
|
||||
val genericFakeOverrideMFVCWithMFVCUpperBound = GenericFakeOverrideMFVCWithMFVCUpperBound(1.0, 2.0)
|
||||
equal(lam5, { genericFakeOverrideMFVCWithMFVCUpperBound.p })
|
||||
equal(lam5, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p })
|
||||
equal(lam7, { genericFakeOverrideMFVCWithMFVCUpperBound.p1 })
|
||||
equal(lam7, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 })
|
||||
|
||||
equal(lam2, { genericFakeOverrideMFVC.p = dPoint })
|
||||
equal(lam2, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam4, { genericFakeOverrideMFVC.p1 = dPoint })
|
||||
equal(lam4, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p1 = dPoint })
|
||||
|
||||
equal(lam10, { reifiedFakeOverrideMFVC.p = dPoint })
|
||||
equal(lam10, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p = dPoint })
|
||||
equal(lam12, { reifiedFakeOverrideMFVC.p1 = dPoint })
|
||||
equal(lam12, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p1 = dPoint })
|
||||
|
||||
equal(lam6, { genericFakeOverrideMFVCWithMFVCUpperBound.p = dPoint })
|
||||
equal(lam6, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam8, { genericFakeOverrideMFVCWithMFVCUpperBound.p1 = dPoint })
|
||||
equal(lam8, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 = dPoint })
|
||||
|
||||
|
||||
val dPointWithInterface = DPointWithInterface(1.0, 2.0)
|
||||
|
||||
equal(lam15, { dPointWithInterface.somethingGeneric })
|
||||
equal(lam15, { (dPointWithInterface as SomePointInterface<DPoint>).somethingGeneric })
|
||||
equal(lam19, { dPointWithInterface.somethingRegular })
|
||||
equal(lam19, { (dPointWithInterface as SomePointInterface<DPoint>).somethingRegular })
|
||||
equal(lam17, { dPointWithInterface.somethingMFVC })
|
||||
equal(lam17, { (dPointWithInterface as SomePointInterface<DPoint>).somethingMFVC })
|
||||
|
||||
equal(lam15, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingGeneric })
|
||||
equal(lam19, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingRegular })
|
||||
equal(lam17, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingMFVC })
|
||||
|
||||
equal(lam16, { dPointWithInterface.somethingGeneric = dPoint })
|
||||
equal(lam16, { (dPointWithInterface as SomePointInterface<DPoint>).somethingGeneric = dPoint })
|
||||
equal(lam20, { dPointWithInterface.somethingRegular = 1 })
|
||||
equal(lam20, { (dPointWithInterface as SomePointInterface<DPoint>).somethingRegular = 1 })
|
||||
equal(lam18, { dPointWithInterface.somethingMFVC = dPoint })
|
||||
equal(lam18, { (dPointWithInterface as SomePointInterface<DPoint>).somethingMFVC = dPoint })
|
||||
|
||||
equal(lam16, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingGeneric = dPoint })
|
||||
equal(lam20, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingRegular = 1 })
|
||||
equal(lam18, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingMFVC = dPoint })
|
||||
|
||||
|
||||
val dSegment = DSegment(dPoint, otherDPoint)
|
||||
|
||||
equal(dPointLam, { dSegment.p1 })
|
||||
equal(otherDPointLam, { dSegment.p2 })
|
||||
equal({ 1.0 }, { dPoint.x })
|
||||
equal({ 1.0 }, { dSegment.p1.x })
|
||||
equal({ 3.0 }, { otherDPoint.x })
|
||||
equal({ 3.0 }, { dSegment.p2.x })
|
||||
equal({ 2.0 }, { dPoint.y })
|
||||
equal({ 2.0 }, { dSegment.p1.y })
|
||||
equal({ 4.0 }, { otherDPoint.y })
|
||||
equal({ 4.0 }, { dSegment.p2.y })
|
||||
equal(dPointLam, { (dSegment as AbstractSegment<DPoint>).p1 })
|
||||
equal(otherDPointLam, { (dSegment as AbstractSegment<DPoint>).p2 })
|
||||
equal({ 1.0 }, { (dSegment as AbstractSegment<DPoint>).p1.x })
|
||||
equal({ 3.0 }, { (dSegment as AbstractSegment<DPoint>).p2.x })
|
||||
equal({ 2.0 }, { (dSegment as AbstractSegment<DPoint>).p1.y })
|
||||
equal({ 4.0 }, { (dSegment as AbstractSegment<DPoint>).p2.y })
|
||||
|
||||
return "OK"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,317 +0,0 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// https://youtrack.jetbrains.com/issue/KT-52236/Different-modality-in-psi-and-fir
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
// CHECK_BYTECODE_LISTING
|
||||
|
||||
interface AbstractPoint<T> {
|
||||
val x: T
|
||||
val y: T
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class MyDouble(val value: Double)
|
||||
|
||||
val Double.my
|
||||
get() = MyDouble(this)
|
||||
|
||||
@JvmInline
|
||||
value class DPoint(override val x: MyDouble, override val y: MyDouble): AbstractPoint<MyDouble>
|
||||
|
||||
interface GenericMFVCHolder<T> {
|
||||
var p: T
|
||||
var p1: T
|
||||
}
|
||||
|
||||
interface GenericMFVCHolderWithMFVCUpperBound<T : DPoint> {
|
||||
var p: T
|
||||
var p1: T
|
||||
}
|
||||
|
||||
interface ReifiedMFVCHolder {
|
||||
var p: DPoint
|
||||
var p1: DPoint
|
||||
}
|
||||
|
||||
data class DataClassException(val value: Any?): Exception()
|
||||
|
||||
interface GenericMFVCHolderWithImpls<T> {
|
||||
var p: T
|
||||
get() = throw DataClassException(1)
|
||||
set(value) = throw DataClassException(2 to value)
|
||||
|
||||
var p1: T
|
||||
get() = throw DataClassException(3)
|
||||
set(value) = throw DataClassException(4 to value)
|
||||
}
|
||||
|
||||
interface GenericMFVCHolderWithMFVCUpperBoundWithImpls<T : DPoint> {
|
||||
var p: T
|
||||
get() = throw DataClassException(5)
|
||||
set(value) = throw DataClassException(6 to value)
|
||||
|
||||
var p1: T
|
||||
get() = throw DataClassException(7)
|
||||
set(value) = throw DataClassException(8 to value)
|
||||
}
|
||||
|
||||
interface ReifiedMFVCHolderWithImpls {
|
||||
var p: DPoint
|
||||
get() = throw DataClassException(9)
|
||||
set(value) = throw DataClassException(10 to value)
|
||||
|
||||
var p1: DPoint
|
||||
get() = throw DataClassException(11)
|
||||
set(value) = throw DataClassException(12 to value)
|
||||
}
|
||||
|
||||
class RealOverride(override var p: DPoint) : GenericMFVCHolder<DPoint>, ReifiedMFVCHolder, GenericMFVCHolderWithMFVCUpperBound<DPoint> {
|
||||
override var p1: DPoint
|
||||
get() = throw DataClassException(13)
|
||||
set(value) = throw DataClassException(14 to value)
|
||||
}
|
||||
|
||||
class GenericFakeOverride : GenericMFVCHolderWithImpls<DPoint>
|
||||
class ReifiedFakeOverride : ReifiedMFVCHolderWithImpls
|
||||
class GenericFakeOverrideWithMFVCUpperBound : GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>
|
||||
|
||||
|
||||
@JvmInline
|
||||
value class GenericFakeOverrideMFVC(val field1: MyDouble, val field2: MyDouble) : GenericMFVCHolderWithImpls<DPoint>
|
||||
@JvmInline
|
||||
value class ReifiedFakeOverrideMFVC(val field1: MyDouble, val field2: MyDouble) : ReifiedMFVCHolderWithImpls
|
||||
@JvmInline
|
||||
value class GenericFakeOverrideMFVCWithMFVCUpperBound(val field1: MyDouble, val field2: MyDouble) : GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>
|
||||
|
||||
|
||||
interface SomePointInterface<T> {
|
||||
var somethingRegular: Int
|
||||
|
||||
var somethingGeneric: T
|
||||
|
||||
var somethingMFVC: DPoint
|
||||
}
|
||||
|
||||
interface SomePointInterfaceWithMFVCBound<T : DPoint> {
|
||||
var somethingRegular: Int
|
||||
|
||||
var somethingGeneric: T
|
||||
|
||||
var somethingMFVC: DPoint
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class DPointWithInterface(val x: MyDouble, val y: MyDouble) : SomePointInterface<DPoint>, SomePointInterfaceWithMFVCBound<DPoint> {
|
||||
override var somethingGeneric: DPoint
|
||||
get() = throw DataClassException(15)
|
||||
set(value) = throw DataClassException(16 to value)
|
||||
|
||||
override var somethingMFVC: DPoint
|
||||
get() = throw DataClassException(17)
|
||||
set(value) = throw DataClassException(18 to value)
|
||||
|
||||
override var somethingRegular: Int
|
||||
get() = throw DataClassException(19)
|
||||
set(value) = throw DataClassException(20 to value)
|
||||
}
|
||||
|
||||
|
||||
interface AbstractSegment<T> {
|
||||
val p1: T
|
||||
val p2: T
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class DSegment(override val p1: DPoint, override val p2: DPoint): AbstractSegment<DPoint>
|
||||
|
||||
fun <T> equal(expected: () -> T, actual: () -> T) {
|
||||
val expectedResult = runCatching { expected() }
|
||||
val actualResult = runCatching { actual() }
|
||||
require(expectedResult == actualResult) { "Expected: $expectedResult\nActual: $actualResult" }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val dPoint = DPoint(1.0.my, 2.0.my)
|
||||
|
||||
val lam1: () -> DPoint = { throw DataClassException(1) }
|
||||
val lam2: () -> Unit = { throw DataClassException(2 to dPoint) }
|
||||
val lam3: () -> DPoint = { throw DataClassException(3) }
|
||||
val lam4: () -> Unit = { throw DataClassException(4 to dPoint) }
|
||||
val lam5: () -> DPoint = { throw DataClassException(5) }
|
||||
val lam6: () -> Unit = { throw DataClassException(6 to dPoint) }
|
||||
val lam7: () -> DPoint = { throw DataClassException(7) }
|
||||
val lam8: () -> Unit = { throw DataClassException(8 to dPoint) }
|
||||
val lam9: () -> DPoint = { throw DataClassException(9) }
|
||||
val lam10: () -> Unit = { throw DataClassException(10 to dPoint) }
|
||||
val lam11: () -> DPoint = { throw DataClassException(11) }
|
||||
val lam12: () -> Unit = { throw DataClassException(12 to dPoint) }
|
||||
val lam13: () -> DPoint = { throw DataClassException(13) }
|
||||
val lam14: () -> Unit = { throw DataClassException(14 to dPoint) }
|
||||
val lam15: () -> DPoint = { throw DataClassException(15) }
|
||||
val lam16: () -> Unit = { throw DataClassException(16 to dPoint) }
|
||||
val lam17: () -> DPoint = { throw DataClassException(17) }
|
||||
val lam18: () -> Unit = { throw DataClassException(18 to dPoint) }
|
||||
val lam19: () -> Int = { throw DataClassException(19) }
|
||||
val lam20: () -> Unit = { throw DataClassException(20 to 1) }
|
||||
val emptyLam = {}
|
||||
val dPointLam = { dPoint }
|
||||
val otherDPoint = DPoint(3.0.my, 4.0.my)
|
||||
val otherDPointLam = { otherDPoint }
|
||||
equal({ "DPoint(x=MyDouble(value=1.0), y=MyDouble(value=2.0))" }, { dPoint.toString() })
|
||||
equal({ "DPoint(x=MyDouble(value=1.0), y=MyDouble(value=2.0))" }, { (dPoint as Any).toString() })
|
||||
|
||||
equal({ true }, { dPoint.equals(dPoint) })
|
||||
equal({ true }, { dPoint.equals(dPoint as Any) })
|
||||
equal({ true }, { (dPoint as Any).equals(dPoint) })
|
||||
equal({ true }, { (dPoint as Any).equals(dPoint as Any) })
|
||||
|
||||
equal({ false }, { dPoint.equals(otherDPoint) })
|
||||
equal({ false }, { dPoint.equals(otherDPoint as Any) })
|
||||
equal({ false }, { (dPoint as Any).equals(otherDPoint) })
|
||||
equal({ false }, { (dPoint as Any).equals(otherDPoint as Any) })
|
||||
|
||||
equal({ dPoint.hashCode() }, { (dPoint as Any).hashCode() })
|
||||
|
||||
equal({ 1.0.my }, { dPoint.x })
|
||||
equal({ 1.0.my }, { (dPoint as AbstractPoint<Double>).x })
|
||||
equal({ 2.0.my }, { dPoint.y })
|
||||
equal({ 2.0.my }, { (dPoint as AbstractPoint<Double>).y })
|
||||
|
||||
|
||||
val realOverride = RealOverride(dPoint)
|
||||
|
||||
equal(dPointLam, { realOverride.p })
|
||||
equal(dPointLam, { (realOverride as GenericMFVCHolder<DPoint>).p })
|
||||
equal(lam13, { realOverride.p1 })
|
||||
equal(lam13, { (realOverride as GenericMFVCHolder<DPoint>).p1 })
|
||||
equal(dPointLam, { (realOverride as ReifiedMFVCHolder).p })
|
||||
equal(lam13, { realOverride.p1 })
|
||||
equal(lam13, { (realOverride as ReifiedMFVCHolder).p1 })
|
||||
equal(dPointLam, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p })
|
||||
equal(lam13, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p1 })
|
||||
|
||||
|
||||
equal(emptyLam, { realOverride.p = dPoint })
|
||||
equal(emptyLam, { (realOverride as GenericMFVCHolder<DPoint>).p = dPoint })
|
||||
equal(lam14, { realOverride.p1 = dPoint })
|
||||
equal(lam14, { (realOverride as GenericMFVCHolder<DPoint>).p1 = dPoint })
|
||||
equal(emptyLam, { (realOverride as ReifiedMFVCHolder).p = dPoint })
|
||||
equal(lam14, { (realOverride as ReifiedMFVCHolder).p1 = dPoint })
|
||||
equal(emptyLam, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p = dPoint })
|
||||
equal(lam14, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<DPoint>).p1 = dPoint })
|
||||
|
||||
|
||||
val genericFakeOverride = GenericFakeOverride()
|
||||
|
||||
equal(lam1, { genericFakeOverride.p })
|
||||
equal(lam1, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p })
|
||||
equal(lam3, { genericFakeOverride.p1 })
|
||||
equal(lam3, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p1 })
|
||||
val reifiedFakeOverride = ReifiedFakeOverride()
|
||||
equal(lam9, { reifiedFakeOverride.p })
|
||||
equal(lam9, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p })
|
||||
equal(lam11, { reifiedFakeOverride.p1 })
|
||||
equal(lam11, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p1 })
|
||||
val genericFakeOverrideWithMFVCUpperBound = GenericFakeOverrideWithMFVCUpperBound()
|
||||
equal(lam5, { genericFakeOverrideWithMFVCUpperBound.p })
|
||||
equal(lam5, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p })
|
||||
equal(lam7, { genericFakeOverrideWithMFVCUpperBound.p1 })
|
||||
equal(lam7, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 })
|
||||
|
||||
equal(lam2, { genericFakeOverride.p = dPoint })
|
||||
equal(lam2, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam4, { genericFakeOverride.p1 = dPoint })
|
||||
equal(lam4, { (genericFakeOverride as GenericMFVCHolderWithImpls<DPoint>).p1 = dPoint })
|
||||
equal(lam10, { reifiedFakeOverride.p = dPoint })
|
||||
equal(lam10, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p = dPoint })
|
||||
equal(lam12, { reifiedFakeOverride.p1 = dPoint })
|
||||
equal(lam12, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls).p1 = dPoint })
|
||||
equal(lam6, { genericFakeOverrideWithMFVCUpperBound.p = dPoint })
|
||||
equal(lam6, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam8, { genericFakeOverrideWithMFVCUpperBound.p1 = dPoint })
|
||||
equal(lam8, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 = dPoint })
|
||||
|
||||
|
||||
val genericFakeOverrideMFVC = GenericFakeOverrideMFVC(1.0.my, 2.0.my)
|
||||
|
||||
equal(lam1, { genericFakeOverrideMFVC.p })
|
||||
equal(lam1, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p })
|
||||
equal(lam3, { genericFakeOverrideMFVC.p1 })
|
||||
equal(lam3, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p1 })
|
||||
|
||||
val reifiedFakeOverrideMFVC = ReifiedFakeOverrideMFVC(1.0.my, 2.0.my)
|
||||
equal(lam9, { reifiedFakeOverrideMFVC.p })
|
||||
equal(lam9, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p })
|
||||
equal(lam11, { reifiedFakeOverrideMFVC.p1 })
|
||||
equal(lam11, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p1 })
|
||||
|
||||
val genericFakeOverrideMFVCWithMFVCUpperBound = GenericFakeOverrideMFVCWithMFVCUpperBound(1.0.my, 2.0.my)
|
||||
equal(lam5, { genericFakeOverrideMFVCWithMFVCUpperBound.p })
|
||||
equal(lam5, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p })
|
||||
equal(lam7, { genericFakeOverrideMFVCWithMFVCUpperBound.p1 })
|
||||
equal(lam7, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 })
|
||||
|
||||
equal(lam2, { genericFakeOverrideMFVC.p = dPoint })
|
||||
equal(lam2, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam4, { genericFakeOverrideMFVC.p1 = dPoint })
|
||||
equal(lam4, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<DPoint>).p1 = dPoint })
|
||||
|
||||
equal(lam10, { reifiedFakeOverrideMFVC.p = dPoint })
|
||||
equal(lam10, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p = dPoint })
|
||||
equal(lam12, { reifiedFakeOverrideMFVC.p1 = dPoint })
|
||||
equal(lam12, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls).p1 = dPoint })
|
||||
|
||||
equal(lam6, { genericFakeOverrideMFVCWithMFVCUpperBound.p = dPoint })
|
||||
equal(lam6, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p = dPoint })
|
||||
equal(lam8, { genericFakeOverrideMFVCWithMFVCUpperBound.p1 = dPoint })
|
||||
equal(lam8, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<DPoint>).p1 = dPoint })
|
||||
|
||||
|
||||
val dPointWithInterface = DPointWithInterface(1.0.my, 2.0.my)
|
||||
|
||||
equal(lam15, { dPointWithInterface.somethingGeneric })
|
||||
equal(lam15, { (dPointWithInterface as SomePointInterface<DPoint>).somethingGeneric })
|
||||
equal(lam19, { dPointWithInterface.somethingRegular })
|
||||
equal(lam19, { (dPointWithInterface as SomePointInterface<DPoint>).somethingRegular })
|
||||
equal(lam17, { dPointWithInterface.somethingMFVC })
|
||||
equal(lam17, { (dPointWithInterface as SomePointInterface<DPoint>).somethingMFVC })
|
||||
|
||||
equal(lam15, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingGeneric })
|
||||
equal(lam19, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingRegular })
|
||||
equal(lam17, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingMFVC })
|
||||
|
||||
equal(lam16, { dPointWithInterface.somethingGeneric = dPoint })
|
||||
equal(lam16, { (dPointWithInterface as SomePointInterface<DPoint>).somethingGeneric = dPoint })
|
||||
equal(lam20, { dPointWithInterface.somethingRegular = 1 })
|
||||
equal(lam20, { (dPointWithInterface as SomePointInterface<DPoint>).somethingRegular = 1 })
|
||||
equal(lam18, { dPointWithInterface.somethingMFVC = dPoint })
|
||||
equal(lam18, { (dPointWithInterface as SomePointInterface<DPoint>).somethingMFVC = dPoint })
|
||||
|
||||
equal(lam16, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingGeneric = dPoint })
|
||||
equal(lam20, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingRegular = 1 })
|
||||
equal(lam18, { (dPointWithInterface as SomePointInterfaceWithMFVCBound<DPoint>).somethingMFVC = dPoint })
|
||||
|
||||
|
||||
val dSegment = DSegment(dPoint, otherDPoint)
|
||||
|
||||
equal(dPointLam, { dSegment.p1 })
|
||||
equal(otherDPointLam, { dSegment.p2 })
|
||||
equal({ 1.0.my }, { dPoint.x })
|
||||
equal({ 1.0.my }, { dSegment.p1.x })
|
||||
equal({ 3.0.my }, { otherDPoint.x })
|
||||
equal({ 3.0.my }, { dSegment.p2.x })
|
||||
equal({ 2.0.my }, { dPoint.y })
|
||||
equal({ 2.0.my }, { dSegment.p1.y })
|
||||
equal({ 4.0.my }, { otherDPoint.y })
|
||||
equal({ 4.0.my }, { dSegment.p2.y })
|
||||
equal(dPointLam, { (dSegment as AbstractSegment<DPoint>).p1 })
|
||||
equal(otherDPointLam, { (dSegment as AbstractSegment<DPoint>).p2 })
|
||||
equal({ 1.0.my }, { (dSegment as AbstractSegment<DPoint>).p1.x })
|
||||
equal({ 3.0.my }, { (dSegment as AbstractSegment<DPoint>).p2.x })
|
||||
equal({ 2.0.my }, { (dSegment as AbstractSegment<DPoint>).p1.y })
|
||||
equal({ 4.0.my }, { (dSegment as AbstractSegment<DPoint>).p2.y })
|
||||
|
||||
return "OK"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,327 +0,0 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// https://youtrack.jetbrains.com/issue/KT-52236/Different-modality-in-psi-and-fir
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
// LANGUAGE: +GenericInlineClassParameter
|
||||
// CHECK_BYTECODE_LISTING
|
||||
|
||||
interface AbstractPoint<T> {
|
||||
val x: T
|
||||
val y: T
|
||||
}
|
||||
|
||||
interface SomeInterface<X> {
|
||||
fun <T, R: X> someFunction1(x: X, t: T, r: R) = Unit
|
||||
fun <T, R: X> someFunction2(x: XPoint<X>, t: XPoint<T>, r: XPoint<R>) = Unit
|
||||
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class XPoint<X>(override val x: X, override val y: X): AbstractPoint<X>, SomeInterface<X> {
|
||||
override fun <T, R: X> someFunction1(x: X, t: T, r: R) = Unit
|
||||
override fun <T, R: X> someFunction2(x: XPoint<X>, t: XPoint<T>, r: XPoint<R>) = Unit
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class YPoint<X>(val x: X)
|
||||
|
||||
fun <S: List<Int>> genericFunctionMFVC(v: XPoint<S>) {}
|
||||
fun <S: List<Int>> genericFunctionIC(v: YPoint<S>) {}
|
||||
|
||||
interface GenericMFVCHolder<T> {
|
||||
var p: T
|
||||
var p1: T
|
||||
}
|
||||
|
||||
interface GenericMFVCHolderWithMFVCUpperBound<X, T : XPoint<X>> {
|
||||
var p: T
|
||||
var p1: T
|
||||
}
|
||||
|
||||
interface ReifiedMFVCHolder<X> {
|
||||
var p: XPoint<X>
|
||||
var p1: XPoint<X>
|
||||
}
|
||||
|
||||
data class DataClassException(val value: Any?): Exception()
|
||||
|
||||
interface GenericMFVCHolderWithImpls<T> {
|
||||
var p: T
|
||||
get() = throw DataClassException(1)
|
||||
set(value) = throw DataClassException(2 to value)
|
||||
|
||||
var p1: T
|
||||
get() = throw DataClassException(3)
|
||||
set(value) = throw DataClassException(4 to value)
|
||||
}
|
||||
|
||||
interface GenericMFVCHolderWithMFVCUpperBoundWithImpls<X, T : XPoint<X>> {
|
||||
var p: T
|
||||
get() = throw DataClassException(5)
|
||||
set(value) = throw DataClassException(6 to value)
|
||||
|
||||
var p1: T
|
||||
get() = throw DataClassException(7)
|
||||
set(value) = throw DataClassException(8 to value)
|
||||
}
|
||||
|
||||
interface ReifiedMFVCHolderWithImpls<X> {
|
||||
var p: XPoint<X>
|
||||
get() = throw DataClassException(9)
|
||||
set(value) = throw DataClassException(10 to value)
|
||||
|
||||
var p1: XPoint<X>
|
||||
get() = throw DataClassException(11)
|
||||
set(value) = throw DataClassException(12 to value)
|
||||
}
|
||||
|
||||
class RealOverride<X>(override var p: XPoint<X>) : GenericMFVCHolder<XPoint<X>>, ReifiedMFVCHolder<X>, GenericMFVCHolderWithMFVCUpperBound<X, XPoint<X>> {
|
||||
override var p1: XPoint<X>
|
||||
get() = throw DataClassException(13)
|
||||
set(value) = throw DataClassException(14 to value)
|
||||
}
|
||||
|
||||
class GenericFakeOverride<X> : GenericMFVCHolderWithImpls<XPoint<X>>
|
||||
class ReifiedFakeOverride<X> : ReifiedMFVCHolderWithImpls<X>
|
||||
class GenericFakeOverrideWithMFVCUpperBound<X> : GenericMFVCHolderWithMFVCUpperBoundWithImpls<X, XPoint<X>>
|
||||
|
||||
|
||||
@JvmInline
|
||||
value class GenericFakeOverrideMFVC<X>(val field1: X, val field2: X) : GenericMFVCHolderWithImpls<XPoint<X>>
|
||||
@JvmInline
|
||||
value class ReifiedFakeOverrideMFVC<X>(val field1: X, val field2: X) : ReifiedMFVCHolderWithImpls<X>
|
||||
@JvmInline
|
||||
value class GenericFakeOverrideMFVCWithMFVCUpperBound<X>(val field1: X, val field2: X) : GenericMFVCHolderWithMFVCUpperBoundWithImpls<X, XPoint<X>>
|
||||
|
||||
|
||||
interface SomePointInterface<X, T> {
|
||||
var somethingRegular: Int
|
||||
|
||||
var somethingGeneric: T
|
||||
|
||||
var somethingMFVC: XPoint<X>
|
||||
}
|
||||
|
||||
interface SomePointInterfaceWithMFVCBound<X, T : XPoint<X>> {
|
||||
var somethingRegular: Int
|
||||
|
||||
var somethingGeneric: T
|
||||
|
||||
var somethingMFVC: XPoint<X>
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class XPointWithInterface<X, Y, Z>(val x: Y, val y: Z) : SomePointInterface<X, XPoint<X>>, SomePointInterfaceWithMFVCBound<X, XPoint<X>> {
|
||||
override var somethingGeneric: XPoint<X>
|
||||
get() = throw DataClassException(15)
|
||||
set(value) = throw DataClassException(16 to value)
|
||||
|
||||
override var somethingMFVC: XPoint<X>
|
||||
get() = throw DataClassException(17)
|
||||
set(value) = throw DataClassException(18 to value)
|
||||
|
||||
override var somethingRegular: Int
|
||||
get() = throw DataClassException(19)
|
||||
set(value) = throw DataClassException(20 to value)
|
||||
}
|
||||
|
||||
|
||||
interface AbstractSegment<T> {
|
||||
val p1: T
|
||||
val p2: T
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class XSegment<X>(override val p1: XPoint<X>, override val p2: XPoint<X>): AbstractSegment<XPoint<X>>
|
||||
|
||||
fun <T> equal(expected: () -> T, actual: () -> T) {
|
||||
val expectedResult = runCatching { expected() }
|
||||
val actualResult = runCatching { actual() }
|
||||
require(expectedResult == actualResult) { "Expected: $expectedResult\nActual: $actualResult" }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val xPoint = XPoint(1.0, 2.0)
|
||||
|
||||
val lam1: () -> XPoint<Double> = { throw DataClassException(1) }
|
||||
val lam2: () -> Unit = { throw DataClassException(2 to xPoint) }
|
||||
val lam3: () -> XPoint<Double> = { throw DataClassException(3) }
|
||||
val lam4: () -> Unit = { throw DataClassException(4 to xPoint) }
|
||||
val lam5: () -> XPoint<Double> = { throw DataClassException(5) }
|
||||
val lam6: () -> Unit = { throw DataClassException(6 to xPoint) }
|
||||
val lam7: () -> XPoint<Double> = { throw DataClassException(7) }
|
||||
val lam8: () -> Unit = { throw DataClassException(8 to xPoint) }
|
||||
val lam9: () -> XPoint<Double> = { throw DataClassException(9) }
|
||||
val lam10: () -> Unit = { throw DataClassException(10 to xPoint) }
|
||||
val lam11: () -> XPoint<Double> = { throw DataClassException(11) }
|
||||
val lam12: () -> Unit = { throw DataClassException(12 to xPoint) }
|
||||
val lam13: () -> XPoint<Double> = { throw DataClassException(13) }
|
||||
val lam14: () -> Unit = { throw DataClassException(14 to xPoint) }
|
||||
val lam15: () -> XPoint<Double> = { throw DataClassException(15) }
|
||||
val lam16: () -> Unit = { throw DataClassException(16 to xPoint) }
|
||||
val lam17: () -> XPoint<Double> = { throw DataClassException(17) }
|
||||
val lam18: () -> Unit = { throw DataClassException(18 to xPoint) }
|
||||
val lam19: () -> Int = { throw DataClassException(19) }
|
||||
val lam20: () -> Unit = { throw DataClassException(20 to 1) }
|
||||
val emptyLam = {}
|
||||
val xPointLam = { xPoint }
|
||||
val otherXPoint = XPoint(3.0, 4.0)
|
||||
val otherXPointLam = { otherXPoint }
|
||||
equal({ "XPoint(x=1.0, y=2.0)" }, { xPoint.toString() })
|
||||
equal({ "XPoint(x=1.0, y=2.0)" }, { (xPoint as Any).toString() })
|
||||
|
||||
equal({ true }, { xPoint.equals(xPoint) })
|
||||
equal({ true }, { xPoint.equals(xPoint as Any) })
|
||||
equal({ true }, { (xPoint as Any).equals(xPoint) })
|
||||
equal({ true }, { (xPoint as Any).equals(xPoint as Any) })
|
||||
|
||||
equal({ false }, { xPoint.equals(otherXPoint) })
|
||||
equal({ false }, { xPoint.equals(otherXPoint as Any) })
|
||||
equal({ false }, { (xPoint as Any).equals(otherXPoint) })
|
||||
equal({ false }, { (xPoint as Any).equals(otherXPoint as Any) })
|
||||
|
||||
equal({ xPoint.hashCode() }, { (xPoint as Any).hashCode() })
|
||||
|
||||
equal({ 1.0 }, { xPoint.x })
|
||||
equal({ 1.0 }, { (xPoint as AbstractPoint<Double>).x })
|
||||
equal({ 2.0 }, { xPoint.y })
|
||||
equal({ 2.0 }, { (xPoint as AbstractPoint<Double>).y })
|
||||
|
||||
|
||||
val realOverride = RealOverride(xPoint)
|
||||
|
||||
equal(xPointLam, { realOverride.p })
|
||||
equal(xPointLam, { (realOverride as GenericMFVCHolder<XPoint<Double>>).p })
|
||||
equal(lam13, { realOverride.p1 })
|
||||
equal(lam13, { (realOverride as GenericMFVCHolder<XPoint<Double>>).p1 })
|
||||
equal(xPointLam, { (realOverride as ReifiedMFVCHolder<Double>).p })
|
||||
equal(lam13, { realOverride.p1 })
|
||||
equal(lam13, { (realOverride as ReifiedMFVCHolder<Double>).p1 })
|
||||
equal(xPointLam, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<Double, XPoint<Double>>).p })
|
||||
equal(lam13, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<Double, XPoint<Double>>).p1 })
|
||||
|
||||
|
||||
equal(emptyLam, { realOverride.p = xPoint })
|
||||
equal(emptyLam, { (realOverride as GenericMFVCHolder<XPoint<Double>>).p = xPoint })
|
||||
equal(lam14, { realOverride.p1 = xPoint })
|
||||
equal(lam14, { (realOverride as GenericMFVCHolder<XPoint<Double>>).p1 = xPoint })
|
||||
equal(emptyLam, { (realOverride as ReifiedMFVCHolder<Double>).p = xPoint })
|
||||
equal(lam14, { (realOverride as ReifiedMFVCHolder<Double>).p1 = xPoint })
|
||||
equal(emptyLam, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<Double, XPoint<Double>>).p = xPoint })
|
||||
equal(lam14, { (realOverride as GenericMFVCHolderWithMFVCUpperBound<Double, XPoint<Double>>).p1 = xPoint })
|
||||
|
||||
|
||||
val genericFakeOverride = GenericFakeOverride<Double>()
|
||||
|
||||
equal(lam1, { genericFakeOverride.p })
|
||||
equal(lam1, { (genericFakeOverride as GenericMFVCHolderWithImpls<XPoint<Double>>).p })
|
||||
equal(lam3, { genericFakeOverride.p1 })
|
||||
equal(lam3, { (genericFakeOverride as GenericMFVCHolderWithImpls<XPoint<Double>>).p1 })
|
||||
val reifiedFakeOverride = ReifiedFakeOverride<Double>()
|
||||
equal(lam9, { reifiedFakeOverride.p })
|
||||
equal(lam9, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls<Double>).p })
|
||||
equal(lam11, { reifiedFakeOverride.p1 })
|
||||
equal(lam11, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls<Double>).p1 })
|
||||
val genericFakeOverrideWithMFVCUpperBound = GenericFakeOverrideWithMFVCUpperBound<Double>()
|
||||
equal(lam5, { genericFakeOverrideWithMFVCUpperBound.p })
|
||||
equal(lam5, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p })
|
||||
equal(lam7, { genericFakeOverrideWithMFVCUpperBound.p1 })
|
||||
equal(lam7, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p1 })
|
||||
|
||||
equal(lam2, { genericFakeOverride.p = xPoint })
|
||||
equal(lam2, { (genericFakeOverride as GenericMFVCHolderWithImpls<XPoint<Double>>).p = xPoint })
|
||||
equal(lam4, { genericFakeOverride.p1 = xPoint })
|
||||
equal(lam4, { (genericFakeOverride as GenericMFVCHolderWithImpls<XPoint<Double>>).p1 = xPoint })
|
||||
equal(lam10, { reifiedFakeOverride.p = xPoint })
|
||||
equal(lam10, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls<Double>).p = xPoint })
|
||||
equal(lam12, { reifiedFakeOverride.p1 = xPoint })
|
||||
equal(lam12, { (reifiedFakeOverride as ReifiedMFVCHolderWithImpls<Double>).p1 = xPoint })
|
||||
equal(lam6, { genericFakeOverrideWithMFVCUpperBound.p = xPoint })
|
||||
equal(lam6, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p = xPoint })
|
||||
equal(lam8, { genericFakeOverrideWithMFVCUpperBound.p1 = xPoint })
|
||||
equal(lam8, { (genericFakeOverrideWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p1 = xPoint })
|
||||
|
||||
|
||||
val genericFakeOverrideMFVC = GenericFakeOverrideMFVC(1.0, 2.0)
|
||||
|
||||
equal(lam1, { genericFakeOverrideMFVC.p })
|
||||
equal(lam1, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<XPoint<Double>>).p })
|
||||
equal(lam3, { genericFakeOverrideMFVC.p1 })
|
||||
equal(lam3, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<XPoint<Double>>).p1 })
|
||||
|
||||
val reifiedFakeOverrideMFVC = ReifiedFakeOverrideMFVC(1.0, 2.0)
|
||||
equal(lam9, { reifiedFakeOverrideMFVC.p })
|
||||
equal(lam9, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls<Double>).p })
|
||||
equal(lam11, { reifiedFakeOverrideMFVC.p1 })
|
||||
equal(lam11, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls<Double>).p1 })
|
||||
|
||||
val genericFakeOverrideMFVCWithMFVCUpperBound = GenericFakeOverrideMFVCWithMFVCUpperBound(1.0, 2.0)
|
||||
equal(lam5, { genericFakeOverrideMFVCWithMFVCUpperBound.p })
|
||||
equal(lam5, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p })
|
||||
equal(lam7, { genericFakeOverrideMFVCWithMFVCUpperBound.p1 })
|
||||
equal(lam7, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p1 })
|
||||
|
||||
equal(lam2, { genericFakeOverrideMFVC.p = xPoint })
|
||||
equal(lam2, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<XPoint<Double>>).p = xPoint })
|
||||
equal(lam4, { genericFakeOverrideMFVC.p1 = xPoint })
|
||||
equal(lam4, { (genericFakeOverrideMFVC as GenericMFVCHolderWithImpls<XPoint<Double>>).p1 = xPoint })
|
||||
|
||||
equal(lam10, { reifiedFakeOverrideMFVC.p = xPoint })
|
||||
equal(lam10, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls<Double>).p = xPoint })
|
||||
equal(lam12, { reifiedFakeOverrideMFVC.p1 = xPoint })
|
||||
equal(lam12, { (reifiedFakeOverrideMFVC as ReifiedMFVCHolderWithImpls<Double>).p1 = xPoint })
|
||||
|
||||
equal(lam6, { genericFakeOverrideMFVCWithMFVCUpperBound.p = xPoint })
|
||||
equal(lam6, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p = xPoint })
|
||||
equal(lam8, { genericFakeOverrideMFVCWithMFVCUpperBound.p1 = xPoint })
|
||||
equal(lam8, { (genericFakeOverrideMFVCWithMFVCUpperBound as GenericMFVCHolderWithMFVCUpperBoundWithImpls<Double, XPoint<Double>>).p1 = xPoint })
|
||||
|
||||
|
||||
val xPointWithInterface = XPointWithInterface<Double, Double, Double>(1.0, 2.0)
|
||||
|
||||
equal(lam15, { xPointWithInterface.somethingGeneric })
|
||||
equal(lam15, { (xPointWithInterface as SomePointInterface<Double, XPoint<Double>>).somethingGeneric })
|
||||
equal(lam19, { xPointWithInterface.somethingRegular })
|
||||
equal(lam19, { (xPointWithInterface as SomePointInterface<Double, XPoint<Double>>).somethingRegular })
|
||||
equal(lam17, { xPointWithInterface.somethingMFVC })
|
||||
equal(lam17, { (xPointWithInterface as SomePointInterface<Double, XPoint<Double>>).somethingMFVC })
|
||||
|
||||
equal(lam15, { (xPointWithInterface as SomePointInterfaceWithMFVCBound<Double, XPoint<Double>>).somethingGeneric })
|
||||
equal(lam19, { (xPointWithInterface as SomePointInterfaceWithMFVCBound<Double, XPoint<Double>>).somethingRegular })
|
||||
equal(lam17, { (xPointWithInterface as SomePointInterfaceWithMFVCBound<Double, XPoint<Double>>).somethingMFVC })
|
||||
|
||||
equal(lam16, { xPointWithInterface.somethingGeneric = xPoint })
|
||||
equal(lam16, { (xPointWithInterface as SomePointInterface<Double, XPoint<Double>>).somethingGeneric = xPoint })
|
||||
equal(lam20, { xPointWithInterface.somethingRegular = 1 })
|
||||
equal(lam20, { (xPointWithInterface as SomePointInterface<Double, XPoint<Double>>).somethingRegular = 1 })
|
||||
equal(lam18, { xPointWithInterface.somethingMFVC = xPoint })
|
||||
equal(lam18, { (xPointWithInterface as SomePointInterface<Double, XPoint<Double>>).somethingMFVC = xPoint })
|
||||
|
||||
equal(lam16, { (xPointWithInterface as SomePointInterfaceWithMFVCBound<Double, XPoint<Double>>).somethingGeneric = xPoint })
|
||||
equal(lam20, { (xPointWithInterface as SomePointInterfaceWithMFVCBound<Double, XPoint<Double>>).somethingRegular = 1 })
|
||||
equal(lam18, { (xPointWithInterface as SomePointInterfaceWithMFVCBound<Double, XPoint<Double>>).somethingMFVC = xPoint })
|
||||
|
||||
|
||||
val xSegment = XSegment(xPoint, otherXPoint)
|
||||
|
||||
equal(xPointLam, { xSegment.p1 })
|
||||
equal(otherXPointLam, { xSegment.p2 })
|
||||
equal({ 1.0 }, { xPoint.x })
|
||||
equal({ 1.0 }, { xSegment.p1.x })
|
||||
equal({ 3.0 }, { otherXPoint.x })
|
||||
equal({ 3.0 }, { xSegment.p2.x })
|
||||
equal({ 2.0 }, { xPoint.y })
|
||||
equal({ 2.0 }, { xSegment.p1.y })
|
||||
equal({ 4.0 }, { otherXPoint.y })
|
||||
equal({ 4.0 }, { xSegment.p2.y })
|
||||
equal(xPointLam, { (xSegment as AbstractSegment<XPoint<Double>>).p1 })
|
||||
equal(otherXPointLam, { (xSegment as AbstractSegment<XPoint<Double>>).p2 })
|
||||
equal({ 1.0 }, { (xSegment as AbstractSegment<XPoint<Double>>).p1.x })
|
||||
equal({ 3.0 }, { (xSegment as AbstractSegment<XPoint<Double>>).p2.x })
|
||||
equal({ 2.0 }, { (xSegment as AbstractSegment<XPoint<Double>>).p1.y })
|
||||
equal({ 4.0 }, { (xSegment as AbstractSegment<XPoint<Double>>).p2.y })
|
||||
|
||||
return "OK"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,34 +0,0 @@
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
// CHECK_BYTECODE_LISTING
|
||||
|
||||
@JvmInline
|
||||
value class DPoint(val x: Double, val y: Double)
|
||||
|
||||
class PointBox(var value: DPoint)
|
||||
|
||||
fun box(): String {
|
||||
var p = DPoint(1.0, 2.0)
|
||||
try {
|
||||
p = DPoint(3.0, error("Failure"))
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
if (p != DPoint(1.0, 2.0)) {
|
||||
return "Partially reassigned variable"
|
||||
}
|
||||
|
||||
val box = PointBox(p)
|
||||
|
||||
try {
|
||||
box.value = DPoint(3.0, error("Failure"))
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
|
||||
if (box.value != DPoint(1.0, 2.0)) {
|
||||
return "Partially reassigned field"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class DPoint {
|
||||
// source: 'throwingMFVCReassignments.kt'
|
||||
private final field field-0: double
|
||||
private final field field-1: double
|
||||
private synthetic method <init>(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 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 PointBox {
|
||||
// source: 'throwingMFVCReassignments.kt'
|
||||
private field value-0: double
|
||||
private field value-1: double
|
||||
public method <init>(p0: double, p1: double): void
|
||||
public final @org.jetbrains.annotations.NotNull method getValue(): DPoint
|
||||
public synthetic final method getValue-0(): double
|
||||
public synthetic final method getValue-1(): double
|
||||
public final method setValue-sUp7gFk(p0: double, p1: double): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class ThrowingMFVCReassignmentsKt {
|
||||
// source: 'throwingMFVCReassignments.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// 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) {
|
||||
init {
|
||||
require(x != 0.0 && y != 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
fun tryOk() = try {
|
||||
DPoint(1.0, 2.0)
|
||||
} catch(_: Throwable) {
|
||||
DPoint(0.0, 3.0)
|
||||
} finally {
|
||||
DPoint(4.0, 5.0)
|
||||
}
|
||||
|
||||
fun tryFail1() = try {
|
||||
DPoint(0.0, 1.0)
|
||||
} catch(_: Throwable) {
|
||||
DPoint(2.0, 3.0)
|
||||
} finally {
|
||||
DPoint(4.0, 5.0)
|
||||
}
|
||||
|
||||
fun tryFail2() = try {
|
||||
DPoint(1.0, 2.0)
|
||||
} catch(_: Throwable) {
|
||||
DPoint(3.0, 4.0)
|
||||
} finally {
|
||||
DPoint(5.0, 0.0)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
require(runCatching { tryOk() } == Result.success(DPoint(1.0, 2.0)))
|
||||
require(runCatching { tryFail1() } == Result.success(DPoint(2.0, 3.0)))
|
||||
require(runCatching { tryFail2() }.isFailure)
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class DPoint {
|
||||
// source: 'tryExpressions.kt'
|
||||
private final field field-0: double
|
||||
private final field field-1: double
|
||||
private synthetic method <init>(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 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 TryExpressionsKt {
|
||||
// source: 'tryExpressions.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static @org.jetbrains.annotations.NotNull method tryFail1(): DPoint
|
||||
public final static @org.jetbrains.annotations.NotNull method tryFail2(): DPoint
|
||||
public final static @org.jetbrains.annotations.NotNull method tryOk(): DPoint
|
||||
public final inner class kotlin/Result$Companion
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
// CHECK_BYTECODE_LISTING
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
|
||||
@JvmInline
|
||||
value class Public(val x: Int, val y: Int) {
|
||||
companion object {
|
||||
var x: Int = 0
|
||||
val y: Int
|
||||
get() = 1
|
||||
var z: Public = Public(0, 0)
|
||||
val t: Public
|
||||
get() = Public(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class Internal(internal val x: Int, internal val y: Int) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
var x: Int = 0
|
||||
|
||||
@JvmStatic
|
||||
val y: Int
|
||||
get() = 1
|
||||
var z: Internal = Internal(0, 0)
|
||||
|
||||
@JvmStatic
|
||||
val t: Internal
|
||||
get() = Internal(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class Private(private val x: Int, private val y: Int)
|
||||
|
||||
@JvmInline
|
||||
value class PublicPublic(val value: Public)
|
||||
|
||||
@JvmInline
|
||||
value class InternalPublic(internal val value: Public)
|
||||
|
||||
@JvmInline
|
||||
value class PrivatePublic(private val value: Public)
|
||||
|
||||
@JvmInline
|
||||
value class PublicInternal(val value: Internal)
|
||||
|
||||
@JvmInline
|
||||
value class InternalInternal(internal val value: Internal)
|
||||
|
||||
@JvmInline
|
||||
value class PrivateInternal(private val value: Internal)
|
||||
|
||||
@JvmInline
|
||||
value class PublicPrivate(val value: Private)
|
||||
|
||||
@JvmInline
|
||||
value class InternalPrivate(internal val value: Private)
|
||||
|
||||
@JvmInline
|
||||
value class PrivatePrivate(private val value: Private)
|
||||
|
||||
class Regular {
|
||||
var x1: Public = Public(1, 2)
|
||||
internal var x2: Public = Public(3, 4)
|
||||
private var x3: Public = Public(5, 6)
|
||||
|
||||
var x4: Public = Public(7, 8)
|
||||
private set
|
||||
internal var x5: Public = Public(9, 10)
|
||||
private set
|
||||
|
||||
var x6: Public = Public(11, 12)
|
||||
internal set
|
||||
|
||||
|
||||
var y1: Internal = Internal(13, 14)
|
||||
internal var y2: Internal = Internal(15, 16)
|
||||
private var y3: Internal = Internal(17, 18)
|
||||
|
||||
var y4: Internal = Internal(19, 20)
|
||||
private set
|
||||
internal var y5: Internal = Internal(21, 22)
|
||||
private set
|
||||
|
||||
var y6: Internal = Internal(23, 24)
|
||||
internal set
|
||||
|
||||
|
||||
var z1: Private = Private(25, 26)
|
||||
internal var z2: Private = Private(27, 28)
|
||||
private var z3: Private = Private(29, 30)
|
||||
|
||||
var z4: Private = Private(31, 32)
|
||||
private set
|
||||
internal var z5: Private = Private(33, 34)
|
||||
private set
|
||||
|
||||
var z6: Private = Private(35, 36)
|
||||
internal set
|
||||
|
||||
companion object {
|
||||
var staticX1: Public = Public(-1, -2)
|
||||
internal var staticX2: Public = Public(-3, -4)
|
||||
private var staticX3: Public = Public(-5, -6)
|
||||
|
||||
var staticX4: Public = Public(-7, -8)
|
||||
private set
|
||||
internal var staticX5: Public = Public(-9, -10)
|
||||
private set
|
||||
|
||||
var staticX6: Public = Public(-11, -12)
|
||||
internal set
|
||||
|
||||
|
||||
var staticY1: Internal = Internal(-13, -14)
|
||||
internal var staticY2: Internal = Internal(-15, -16)
|
||||
private var staticY3: Internal = Internal(-17, -18)
|
||||
|
||||
var staticY4: Internal = Internal(-19, -20)
|
||||
private set
|
||||
internal var staticY5: Internal = Internal(-21, -22)
|
||||
private set
|
||||
|
||||
var staticY6: Internal = Internal(-23, -24)
|
||||
internal set
|
||||
|
||||
|
||||
var staticZ1: Private = Private(-25, -26)
|
||||
internal var staticZ2: Private = Private(-27, -28)
|
||||
private var staticZ3: Private = Private(-29, -30)
|
||||
|
||||
var staticZ4: Private = Private(-31, -32)
|
||||
private set
|
||||
internal var staticZ5: Private = Private(-33, -34)
|
||||
private set
|
||||
|
||||
var staticZ6: Private = Private(-35, -36)
|
||||
internal set
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticX1: Public = Public(-1, -2)
|
||||
|
||||
@JvmStatic
|
||||
internal var jvmStaticX2: Public = Public(-3, -4)
|
||||
|
||||
@JvmStatic
|
||||
private var jvmStaticX3: Public = Public(-5, -6)
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticX4: Public = Public(-7, -8)
|
||||
private set
|
||||
|
||||
@JvmStatic
|
||||
internal var jvmStaticX5: Public = Public(-9, -10)
|
||||
private set
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticX6: Public = Public(-11, -12)
|
||||
internal set
|
||||
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticY1: Internal = Internal(-13, -14)
|
||||
|
||||
@JvmStatic
|
||||
internal var jvmStaticY2: Internal = Internal(-15, -16)
|
||||
|
||||
@JvmStatic
|
||||
private var jvmStaticY3: Internal = Internal(-17, -18)
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticY4: Internal = Internal(-19, -20)
|
||||
private set
|
||||
|
||||
@JvmStatic
|
||||
internal var jvmStaticY5: Internal = Internal(-21, -22)
|
||||
private set
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticY6: Internal = Internal(-23, -24)
|
||||
internal set
|
||||
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticZ1: Private = Private(-25, -26)
|
||||
|
||||
@JvmStatic
|
||||
internal var jvmStaticZ2: Private = Private(-27, -28)
|
||||
|
||||
@JvmStatic
|
||||
private var jvmStaticZ3: Private = Private(-29, -30)
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticZ4: Private = Private(-31, -32)
|
||||
private set
|
||||
|
||||
@JvmStatic
|
||||
internal var jvmStaticZ5: Private = Private(-33, -34)
|
||||
private set
|
||||
|
||||
@JvmStatic
|
||||
var jvmStaticZ6: Private = Private(-35, -36)
|
||||
internal set
|
||||
|
||||
}
|
||||
|
||||
fun callAll() {
|
||||
x1; x2; x3; x4; x5; x6
|
||||
x1.x; x1.y; x2.x; x2.y; x3.x; x3.y; x4.x; x4.y; x5.x; x5.y; x6.x; x6.y
|
||||
x1 = x1; x2 = x2; x3 = x3; x4 = x4; x5 = x5; x6 = x6
|
||||
|
||||
y1; y2; y3; y4; y5; y6
|
||||
y1.x; y1.y; y2.x; y2.y; y3.x; y3.y; y4.x; y4.y; y5.x; y5.y; y6.x; y6.y
|
||||
y1 = y1; y2 = y2; y3 = y3; y4 = y4; y5 = y5; y6 = y6
|
||||
|
||||
z1; z2; z3; z4; z5; z6
|
||||
z1 = z1; z2 = z2; z3 = z3; z4 = z4; z5 = z5; z6 = z6
|
||||
|
||||
|
||||
staticX1; staticX2; staticX3; staticX4; staticX5; staticX6
|
||||
staticX1.x; staticX1.y; staticX2.x; staticX2.y; staticX3.x; staticX3.y; staticX4.x; staticX4.y; staticX5.x; staticX5.y; staticX6.x; staticX6.y
|
||||
staticX1 = staticX1; staticX2 = staticX2; staticX3 = staticX3; staticX4 = staticX4; staticX5 = staticX5; staticX6 = staticX6
|
||||
|
||||
staticY1; staticY2; staticY3; staticY4; staticY5; staticY6
|
||||
staticY1.x; staticY1.y; staticY2.x; staticY2.y; staticY3.x; staticY3.y; staticY4.x; staticY4.y; staticY5.x; staticY5.y; staticY6.x; staticY6.y
|
||||
staticY1 = staticY1; staticY2 = staticY2; staticY3 = staticY3; staticY4 = staticY4; staticY5 = staticY5; staticY6 = staticY6
|
||||
|
||||
staticZ1; staticZ2; staticZ3; staticZ4; staticZ5; staticZ6
|
||||
staticZ1 = staticZ1; staticZ2 = staticZ2; staticZ3 = staticZ3; staticZ4 = staticZ4; staticZ5 = staticZ5; staticZ6 = staticZ6
|
||||
|
||||
|
||||
jvmStaticX1; jvmStaticX2; jvmStaticX3; jvmStaticX4; jvmStaticX5; jvmStaticX6
|
||||
jvmStaticX1.x; jvmStaticX1.y; jvmStaticX2.x; jvmStaticX2.y; jvmStaticX3.x; jvmStaticX3.y; jvmStaticX4.x; jvmStaticX4.y; jvmStaticX5.x; jvmStaticX5.y; jvmStaticX6.x; jvmStaticX6.y
|
||||
jvmStaticX1 = jvmStaticX1; jvmStaticX2 = jvmStaticX2; jvmStaticX3 = jvmStaticX3; jvmStaticX4 = jvmStaticX4; jvmStaticX5 =
|
||||
jvmStaticX5; jvmStaticX6 = jvmStaticX6
|
||||
|
||||
jvmStaticY1; jvmStaticY2; jvmStaticY3; jvmStaticY4; jvmStaticY5; jvmStaticY6
|
||||
jvmStaticY1.x; jvmStaticY1.y; jvmStaticY2.x; jvmStaticY2.y; jvmStaticY3.x; jvmStaticY3.y; jvmStaticY4.x; jvmStaticY4.y; jvmStaticY5.x; jvmStaticY5.y; jvmStaticY6.x; jvmStaticY6.y
|
||||
jvmStaticY1 = jvmStaticY1; jvmStaticY2 = jvmStaticY2; jvmStaticY3 = jvmStaticY3; jvmStaticY4 = jvmStaticY4; jvmStaticY5 =
|
||||
jvmStaticY5; jvmStaticY6 = jvmStaticY6
|
||||
|
||||
jvmStaticZ1; jvmStaticZ2; jvmStaticZ3; jvmStaticZ4; jvmStaticZ5; jvmStaticZ6
|
||||
jvmStaticZ1 = jvmStaticZ1; jvmStaticZ2 = jvmStaticZ2; jvmStaticZ3 = jvmStaticZ3; jvmStaticZ4 = jvmStaticZ4; jvmStaticZ5 =
|
||||
jvmStaticZ5; jvmStaticZ6 = jvmStaticZ6
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val r = Regular()
|
||||
r.apply {
|
||||
callAll()
|
||||
|
||||
|
||||
x1; x2; x4; x5; x6
|
||||
x1.x; x1.y; x2.x; x2.y; x4.x; x4.y; x5.x; x5.y; x6.x; x6.y
|
||||
x1 = x1; x2 = x2; x6 = x6
|
||||
|
||||
y1; y2; y4; y5; y6
|
||||
y1.x; y1.y; y2.x; y2.y; y4.x; y4.y; y5.x; y5.y; y6.x; y6.y
|
||||
y1 = y1; y2 = y2; y6 = y6
|
||||
|
||||
z1; z2; z4; z5; z6
|
||||
z1 = z1; z2 = z2; z6 = z6
|
||||
}
|
||||
|
||||
Regular.Companion.apply {
|
||||
staticX1; staticX2; staticX4; staticX5; staticX6
|
||||
staticX1.x; staticX1.y; staticX2.x; staticX2.y; staticX4.x; staticX4.y; staticX5.x; staticX5.y; staticX6.x; staticX6.y
|
||||
staticX1 = staticX1; staticX2 = staticX2; staticX6 = staticX6
|
||||
|
||||
staticY1; staticY2; staticY4; staticY5; staticY6
|
||||
staticY1.x; staticY1.y; staticY2.x; staticY2.y; staticY4.x; staticY4.y; staticY5.x; staticY5.y; staticY6.x; staticY6.y
|
||||
staticY1 = staticY1; staticY2 = staticY2; staticY6 = staticY6
|
||||
|
||||
staticZ1; staticZ2; staticZ4; staticZ5; staticZ6
|
||||
staticZ1 = staticZ1; staticZ2 = staticZ2; staticZ6 = staticZ6
|
||||
|
||||
|
||||
jvmStaticX1; jvmStaticX2; jvmStaticX4; jvmStaticX5; jvmStaticX6
|
||||
jvmStaticX1.x; jvmStaticX1.y; jvmStaticX2.x; jvmStaticX2.y; jvmStaticX4.x; jvmStaticX4.y; jvmStaticX5.x; jvmStaticX5.y; jvmStaticX6.x; jvmStaticX6.y
|
||||
jvmStaticX1 = jvmStaticX1; jvmStaticX2 = jvmStaticX2; jvmStaticX6 = jvmStaticX6
|
||||
|
||||
jvmStaticY1; jvmStaticY2; jvmStaticY4; jvmStaticY5; jvmStaticY6
|
||||
jvmStaticY1.x; jvmStaticY1.y; jvmStaticY2.x; jvmStaticY2.y; jvmStaticY4.x; jvmStaticY4.y; jvmStaticY5.x; jvmStaticY5.y; jvmStaticY6.x; jvmStaticY6.y
|
||||
jvmStaticY1 = jvmStaticY1; jvmStaticY2 = jvmStaticY2; jvmStaticY6 = jvmStaticY6
|
||||
|
||||
jvmStaticZ1; jvmStaticZ2; jvmStaticZ4; jvmStaticZ5; jvmStaticZ6
|
||||
jvmStaticZ1 = jvmStaticZ1; jvmStaticZ2 = jvmStaticZ2; jvmStaticZ6 = jvmStaticZ6
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,780 +0,0 @@
|
||||
@kotlin.Metadata
|
||||
public final class Internal$Companion {
|
||||
// source: 'visibility.kt'
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getT$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getT(): Internal
|
||||
public synthetic final method getT-0(): int
|
||||
public synthetic final method getT-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getX$annotations(): void
|
||||
public final method getX(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getY$annotations(): void
|
||||
public final method getY(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getZ(): Internal
|
||||
public synthetic final method getZ-0(): int
|
||||
public synthetic final method getZ-1(): int
|
||||
public final method setX(p0: int): void
|
||||
public final method setZ-sUp7gFk(p0: int, p1: int): void
|
||||
public final inner class Internal$Companion
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class Internal {
|
||||
// source: 'visibility.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull field Companion: Internal$Companion
|
||||
private final field field-0: int
|
||||
private final field field-1: int
|
||||
private static field x: int
|
||||
static method <clinit>(): void
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method access$getX$cp(): int
|
||||
public synthetic final static method access$getZ-0$cp(): int
|
||||
public synthetic final static method access$getZ-1$cp(): int
|
||||
public synthetic final static method access$setX$cp(p0: int): void
|
||||
public synthetic final static method access$setZ-0$cp(p0: int): void
|
||||
public synthetic final static method access$setZ-1$cp(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): Internal
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public final static @org.jetbrains.annotations.NotNull method getT(): Internal
|
||||
public final static method getX(): int
|
||||
public final static method getY(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public final static method setX(p0: int): void
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): int
|
||||
public synthetic final method unbox-impl-1(): int
|
||||
public final inner class Internal$Companion
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class InternalInternal {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): InternalInternal
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Internal
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class InternalPrivate {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): InternalPrivate
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Private
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class InternalPublic {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): InternalPublic
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Public
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class Private {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0: int
|
||||
private final field field-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): Private
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): int
|
||||
public synthetic final method unbox-impl-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class PrivateInternal {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): PrivateInternal
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Internal
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class PrivatePrivate {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): PrivatePrivate
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Private
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class PrivatePublic {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): PrivatePublic
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Public
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Public$Companion {
|
||||
// source: 'visibility.kt'
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public final @org.jetbrains.annotations.NotNull method getT(): Public
|
||||
public synthetic final method getT-0(): int
|
||||
public synthetic final method getT-1(): int
|
||||
public final method getX(): int
|
||||
public final method getY(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getZ(): Public
|
||||
public synthetic final method getZ-0(): int
|
||||
public synthetic final method getZ-1(): int
|
||||
public final method setX(p0: int): void
|
||||
public final method setZ-sUp7gFk(p0: int, p1: int): void
|
||||
public final inner class Public$Companion
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class Public {
|
||||
// source: 'visibility.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull field Companion: Public$Companion
|
||||
private final field field-0: int
|
||||
private final field field-1: int
|
||||
private static field x: int
|
||||
static method <clinit>(): void
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method access$getX$cp(): int
|
||||
public synthetic final static method access$getZ-0$cp(): int
|
||||
public synthetic final static method access$getZ-1$cp(): int
|
||||
public synthetic final static method access$setX$cp(p0: int): void
|
||||
public synthetic final static method access$setZ-0$cp(p0: int): void
|
||||
public synthetic final static method access$setZ-1$cp(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): Public
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): int
|
||||
public synthetic final method unbox-impl-1(): int
|
||||
public final inner class Public$Companion
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class PublicInternal {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): PublicInternal
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Internal
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class PublicPrivate {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): PublicPrivate
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Private
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class PublicPublic {
|
||||
// source: 'visibility.kt'
|
||||
private final field field-0-0: int
|
||||
private final field field-0-1: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): PublicPublic
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-0(): Public
|
||||
public synthetic final method unbox-impl-0-0(): int
|
||||
public synthetic final method unbox-impl-0-1(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Regular$Companion {
|
||||
// source: 'visibility.kt'
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic final static method access$getJvmStaticX3(p0: Regular$Companion): Public
|
||||
public synthetic final static method access$getJvmStaticY3(p0: Regular$Companion): Internal
|
||||
public synthetic final static method access$getJvmStaticZ3(p0: Regular$Companion): Private
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticX1$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticX1(): Public
|
||||
public synthetic final method getJvmStaticX1-0(): int
|
||||
public synthetic final method getJvmStaticX1-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticX2$main$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticX2$main(): Public
|
||||
public synthetic final method getJvmStaticX2-0(): int
|
||||
public synthetic final method getJvmStaticX2-1(): int
|
||||
private synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticX3$annotations(): void
|
||||
private final method getJvmStaticX3(): Public
|
||||
public synthetic final method getJvmStaticX3-0(): int
|
||||
public synthetic final method getJvmStaticX3-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticX4$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticX4(): Public
|
||||
public synthetic final method getJvmStaticX4-0(): int
|
||||
public synthetic final method getJvmStaticX4-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticX5$main$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticX5$main(): Public
|
||||
public synthetic final method getJvmStaticX5-0(): int
|
||||
public synthetic final method getJvmStaticX5-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticX6$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticX6(): Public
|
||||
public synthetic final method getJvmStaticX6-0(): int
|
||||
public synthetic final method getJvmStaticX6-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticY1$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticY1(): Internal
|
||||
public synthetic final method getJvmStaticY1-0(): int
|
||||
public synthetic final method getJvmStaticY1-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticY2$main$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticY2$main(): Internal
|
||||
public synthetic final method getJvmStaticY2-0(): int
|
||||
public synthetic final method getJvmStaticY2-1(): int
|
||||
private synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticY3$annotations(): void
|
||||
private final method getJvmStaticY3(): Internal
|
||||
public synthetic final method getJvmStaticY3-0(): int
|
||||
public synthetic final method getJvmStaticY3-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticY4$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticY4(): Internal
|
||||
public synthetic final method getJvmStaticY4-0(): int
|
||||
public synthetic final method getJvmStaticY4-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticY5$main$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticY5$main(): Internal
|
||||
public synthetic final method getJvmStaticY5-0(): int
|
||||
public synthetic final method getJvmStaticY5-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticY6$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticY6(): Internal
|
||||
public synthetic final method getJvmStaticY6-0(): int
|
||||
public synthetic final method getJvmStaticY6-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticZ1$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticZ1(): Private
|
||||
public synthetic final method getJvmStaticZ1-0(): int
|
||||
public synthetic final method getJvmStaticZ1-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticZ2$main$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticZ2$main(): Private
|
||||
public synthetic final method getJvmStaticZ2-0(): int
|
||||
public synthetic final method getJvmStaticZ2-1(): int
|
||||
private synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticZ3$annotations(): void
|
||||
private final method getJvmStaticZ3(): Private
|
||||
public synthetic final method getJvmStaticZ3-0(): int
|
||||
public synthetic final method getJvmStaticZ3-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticZ4$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticZ4(): Private
|
||||
public synthetic final method getJvmStaticZ4-0(): int
|
||||
public synthetic final method getJvmStaticZ4-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticZ5$main$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticZ5$main(): Private
|
||||
public synthetic final method getJvmStaticZ5-0(): int
|
||||
public synthetic final method getJvmStaticZ5-1(): int
|
||||
public synthetic deprecated static @kotlin.jvm.JvmStatic method getJvmStaticZ6$annotations(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getJvmStaticZ6(): Private
|
||||
public synthetic final method getJvmStaticZ6-0(): int
|
||||
public synthetic final method getJvmStaticZ6-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticX1(): Public
|
||||
public synthetic final method getStaticX1-0(): int
|
||||
public synthetic final method getStaticX1-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticX2$main(): Public
|
||||
public synthetic final method getStaticX2-0(): int
|
||||
public synthetic final method getStaticX2-1(): int
|
||||
private final method getStaticX3(): Public
|
||||
public synthetic final method getStaticX3-0(): int
|
||||
public synthetic final method getStaticX3-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticX4(): Public
|
||||
public synthetic final method getStaticX4-0(): int
|
||||
public synthetic final method getStaticX4-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticX5$main(): Public
|
||||
public synthetic final method getStaticX5-0(): int
|
||||
public synthetic final method getStaticX5-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticX6(): Public
|
||||
public synthetic final method getStaticX6-0(): int
|
||||
public synthetic final method getStaticX6-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticY1(): Internal
|
||||
public synthetic final method getStaticY1-0(): int
|
||||
public synthetic final method getStaticY1-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticY2$main(): Internal
|
||||
public synthetic final method getStaticY2-0(): int
|
||||
public synthetic final method getStaticY2-1(): int
|
||||
private final method getStaticY3(): Internal
|
||||
public synthetic final method getStaticY3-0(): int
|
||||
public synthetic final method getStaticY3-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticY4(): Internal
|
||||
public synthetic final method getStaticY4-0(): int
|
||||
public synthetic final method getStaticY4-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticY5$main(): Internal
|
||||
public synthetic final method getStaticY5-0(): int
|
||||
public synthetic final method getStaticY5-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticY6(): Internal
|
||||
public synthetic final method getStaticY6-0(): int
|
||||
public synthetic final method getStaticY6-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticZ1(): Private
|
||||
public synthetic final method getStaticZ1-0(): int
|
||||
public synthetic final method getStaticZ1-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticZ2$main(): Private
|
||||
public synthetic final method getStaticZ2-0(): int
|
||||
public synthetic final method getStaticZ2-1(): int
|
||||
private final method getStaticZ3(): Private
|
||||
public synthetic final method getStaticZ3-0(): int
|
||||
public synthetic final method getStaticZ3-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticZ4(): Private
|
||||
public synthetic final method getStaticZ4-0(): int
|
||||
public synthetic final method getStaticZ4-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticZ5$main(): Private
|
||||
public synthetic final method getStaticZ5-0(): int
|
||||
public synthetic final method getStaticZ5-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getStaticZ6(): Private
|
||||
public synthetic final method getStaticZ6-0(): int
|
||||
public synthetic final method getStaticZ6-1(): int
|
||||
public final method setJvmStaticX1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setJvmStaticX2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setJvmStaticX6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setJvmStaticY1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setJvmStaticY2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setJvmStaticY6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setJvmStaticZ1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setJvmStaticZ2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setJvmStaticZ6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setStaticX1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setStaticX2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setStaticX6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setStaticY1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setStaticY2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setStaticY6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setStaticZ1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setStaticZ2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setStaticZ6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final inner class Regular$Companion
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Regular {
|
||||
// source: 'visibility.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull field Companion: Regular$Companion
|
||||
private static field jvmStaticX1-0: int
|
||||
private static field jvmStaticX1-1: int
|
||||
private static field jvmStaticX2-0: int
|
||||
private static field jvmStaticX2-1: int
|
||||
private static field jvmStaticX3-0: int
|
||||
private static field jvmStaticX3-1: int
|
||||
private static field jvmStaticX4-0: int
|
||||
private static field jvmStaticX4-1: int
|
||||
private static field jvmStaticX5-0: int
|
||||
private static field jvmStaticX5-1: int
|
||||
private static field jvmStaticX6-0: int
|
||||
private static field jvmStaticX6-1: int
|
||||
private static field jvmStaticY1-0: int
|
||||
private static field jvmStaticY1-1: int
|
||||
private static field jvmStaticY2-0: int
|
||||
private static field jvmStaticY2-1: int
|
||||
private static field jvmStaticY3-0: int
|
||||
private static field jvmStaticY3-1: int
|
||||
private static field jvmStaticY4-0: int
|
||||
private static field jvmStaticY4-1: int
|
||||
private static field jvmStaticY5-0: int
|
||||
private static field jvmStaticY5-1: int
|
||||
private static field jvmStaticY6-0: int
|
||||
private static field jvmStaticY6-1: int
|
||||
private static field jvmStaticZ1-0: int
|
||||
private static field jvmStaticZ1-1: int
|
||||
private static field jvmStaticZ2-0: int
|
||||
private static field jvmStaticZ2-1: int
|
||||
private static field jvmStaticZ3-0: int
|
||||
private static field jvmStaticZ3-1: int
|
||||
private static field jvmStaticZ4-0: int
|
||||
private static field jvmStaticZ4-1: int
|
||||
private static field jvmStaticZ5-0: int
|
||||
private static field jvmStaticZ5-1: int
|
||||
private static field jvmStaticZ6-0: int
|
||||
private static field jvmStaticZ6-1: int
|
||||
private static field staticX1-0: int
|
||||
private static field staticX1-1: int
|
||||
private static field staticX2-0: int
|
||||
private static field staticX2-1: int
|
||||
private static field staticX3-0: int
|
||||
private static field staticX3-1: int
|
||||
private static field staticX4-0: int
|
||||
private static field staticX4-1: int
|
||||
private static field staticX5-0: int
|
||||
private static field staticX5-1: int
|
||||
private static field staticX6-0: int
|
||||
private static field staticX6-1: int
|
||||
private static field staticY1-0: int
|
||||
private static field staticY1-1: int
|
||||
private static field staticY2-0: int
|
||||
private static field staticY2-1: int
|
||||
private static field staticY3-0: int
|
||||
private static field staticY3-1: int
|
||||
private static field staticY4-0: int
|
||||
private static field staticY4-1: int
|
||||
private static field staticY5-0: int
|
||||
private static field staticY5-1: int
|
||||
private static field staticY6-0: int
|
||||
private static field staticY6-1: int
|
||||
private static field staticZ1-0: int
|
||||
private static field staticZ1-1: int
|
||||
private static field staticZ2-0: int
|
||||
private static field staticZ2-1: int
|
||||
private static field staticZ3-0: int
|
||||
private static field staticZ3-1: int
|
||||
private static field staticZ4-0: int
|
||||
private static field staticZ4-1: int
|
||||
private static field staticZ5-0: int
|
||||
private static field staticZ5-1: int
|
||||
private static field staticZ6-0: int
|
||||
private static field staticZ6-1: int
|
||||
private field x1-0: int
|
||||
private field x1-1: int
|
||||
private field x2-0: int
|
||||
private field x2-1: int
|
||||
private field x3-0: int
|
||||
private field x3-1: int
|
||||
private field x4-0: int
|
||||
private field x4-1: int
|
||||
private field x5-0: int
|
||||
private field x5-1: int
|
||||
private field x6-0: int
|
||||
private field x6-1: int
|
||||
private field y1-0: int
|
||||
private field y1-1: int
|
||||
private field y2-0: int
|
||||
private field y2-1: int
|
||||
private field y3-0: int
|
||||
private field y3-1: int
|
||||
private field y4-0: int
|
||||
private field y4-1: int
|
||||
private field y5-0: int
|
||||
private field y5-1: int
|
||||
private field y6-0: int
|
||||
private field y6-1: int
|
||||
private field z1-0: int
|
||||
private field z1-1: int
|
||||
private field z2-0: int
|
||||
private field z2-1: int
|
||||
private field z3-0: int
|
||||
private field z3-1: int
|
||||
private field z4-0: int
|
||||
private field z4-1: int
|
||||
private field z5-0: int
|
||||
private field z5-1: int
|
||||
private field z6-0: int
|
||||
private field z6-1: int
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
public synthetic final static method access$getJvmStaticX1-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX1-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX2-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX2-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX3-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX3-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX4-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX4-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX5-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX5-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX6-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticX6-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY1-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY1-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY2-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY2-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY3-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY3-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY4-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY4-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY5-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY5-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY6-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticY6-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ1-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ1-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ2-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ2-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ3-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ3-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ4-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ4-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ5-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ5-1$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ6-0$cp(): int
|
||||
public synthetic final static method access$getJvmStaticZ6-1$cp(): int
|
||||
public synthetic final static method access$getStaticX1-0$cp(): int
|
||||
public synthetic final static method access$getStaticX1-1$cp(): int
|
||||
public synthetic final static method access$getStaticX2-0$cp(): int
|
||||
public synthetic final static method access$getStaticX2-1$cp(): int
|
||||
public synthetic final static method access$getStaticX3-0$cp(): int
|
||||
public synthetic final static method access$getStaticX3-1$cp(): int
|
||||
public synthetic final static method access$getStaticX4-0$cp(): int
|
||||
public synthetic final static method access$getStaticX4-1$cp(): int
|
||||
public synthetic final static method access$getStaticX5-0$cp(): int
|
||||
public synthetic final static method access$getStaticX5-1$cp(): int
|
||||
public synthetic final static method access$getStaticX6-0$cp(): int
|
||||
public synthetic final static method access$getStaticX6-1$cp(): int
|
||||
public synthetic final static method access$getStaticY1-0$cp(): int
|
||||
public synthetic final static method access$getStaticY1-1$cp(): int
|
||||
public synthetic final static method access$getStaticY2-0$cp(): int
|
||||
public synthetic final static method access$getStaticY2-1$cp(): int
|
||||
public synthetic final static method access$getStaticY3-0$cp(): int
|
||||
public synthetic final static method access$getStaticY3-1$cp(): int
|
||||
public synthetic final static method access$getStaticY4-0$cp(): int
|
||||
public synthetic final static method access$getStaticY4-1$cp(): int
|
||||
public synthetic final static method access$getStaticY5-0$cp(): int
|
||||
public synthetic final static method access$getStaticY5-1$cp(): int
|
||||
public synthetic final static method access$getStaticY6-0$cp(): int
|
||||
public synthetic final static method access$getStaticY6-1$cp(): int
|
||||
public synthetic final static method access$getStaticZ1-0$cp(): int
|
||||
public synthetic final static method access$getStaticZ1-1$cp(): int
|
||||
public synthetic final static method access$getStaticZ2-0$cp(): int
|
||||
public synthetic final static method access$getStaticZ2-1$cp(): int
|
||||
public synthetic final static method access$getStaticZ3-0$cp(): int
|
||||
public synthetic final static method access$getStaticZ3-1$cp(): int
|
||||
public synthetic final static method access$getStaticZ4-0$cp(): int
|
||||
public synthetic final static method access$getStaticZ4-1$cp(): int
|
||||
public synthetic final static method access$getStaticZ5-0$cp(): int
|
||||
public synthetic final static method access$getStaticZ5-1$cp(): int
|
||||
public synthetic final static method access$getStaticZ6-0$cp(): int
|
||||
public synthetic final static method access$getStaticZ6-1$cp(): int
|
||||
public synthetic final static method access$setJvmStaticX1-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticX1-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticX2-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticX2-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticX6-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticX6-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticY1-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticY1-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticY2-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticY2-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticY6-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticY6-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticZ1-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticZ1-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticZ2-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticZ2-1$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticZ6-0$cp(p0: int): void
|
||||
public synthetic final static method access$setJvmStaticZ6-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticX1-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticX1-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticX2-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticX2-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticX6-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticX6-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticY1-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticY1-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticY2-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticY2-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticY6-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticY6-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticZ1-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticZ1-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticZ2-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticZ2-1$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticZ6-0$cp(p0: int): void
|
||||
public synthetic final static method access$setStaticZ6-1$cp(p0: int): void
|
||||
public final method callAll(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticX1(): Public
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticX2$main(): Public
|
||||
private final static method getJvmStaticX3(): Public
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticX4(): Public
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticX5$main(): Public
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticX6(): Public
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticY1(): Internal
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticY2$main(): Internal
|
||||
private final static method getJvmStaticY3(): Internal
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticY4(): Internal
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticY5$main(): Internal
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticY6(): Internal
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticZ1(): Private
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticZ2$main(): Private
|
||||
private final static method getJvmStaticZ3(): Private
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticZ4(): Private
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticZ5$main(): Private
|
||||
public final static @org.jetbrains.annotations.NotNull method getJvmStaticZ6(): Private
|
||||
public final @org.jetbrains.annotations.NotNull method getX1(): Public
|
||||
public synthetic final method getX1-0(): int
|
||||
public synthetic final method getX1-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getX2$main(): Public
|
||||
public synthetic final method getX2-0(): int
|
||||
public synthetic final method getX2-1(): int
|
||||
private final method getX3(): Public
|
||||
public synthetic final method getX3-0(): int
|
||||
public synthetic final method getX3-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getX4(): Public
|
||||
public synthetic final method getX4-0(): int
|
||||
public synthetic final method getX4-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getX5$main(): Public
|
||||
public synthetic final method getX5-0(): int
|
||||
public synthetic final method getX5-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getX6(): Public
|
||||
public synthetic final method getX6-0(): int
|
||||
public synthetic final method getX6-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getY1(): Internal
|
||||
public synthetic final method getY1-0(): int
|
||||
public synthetic final method getY1-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getY2$main(): Internal
|
||||
public synthetic final method getY2-0(): int
|
||||
public synthetic final method getY2-1(): int
|
||||
private final method getY3(): Internal
|
||||
public synthetic final method getY3-0(): int
|
||||
public synthetic final method getY3-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getY4(): Internal
|
||||
public synthetic final method getY4-0(): int
|
||||
public synthetic final method getY4-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getY5$main(): Internal
|
||||
public synthetic final method getY5-0(): int
|
||||
public synthetic final method getY5-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getY6(): Internal
|
||||
public synthetic final method getY6-0(): int
|
||||
public synthetic final method getY6-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getZ1(): Private
|
||||
public synthetic final method getZ1-0(): int
|
||||
public synthetic final method getZ1-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getZ2$main(): Private
|
||||
public synthetic final method getZ2-0(): int
|
||||
public synthetic final method getZ2-1(): int
|
||||
private final method getZ3(): Private
|
||||
public synthetic final method getZ3-0(): int
|
||||
public synthetic final method getZ3-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getZ4(): Private
|
||||
public synthetic final method getZ4-0(): int
|
||||
public synthetic final method getZ4-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getZ5$main(): Private
|
||||
public synthetic final method getZ5-0(): int
|
||||
public synthetic final method getZ5-1(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getZ6(): Private
|
||||
public synthetic final method getZ6-0(): int
|
||||
public synthetic final method getZ6-1(): int
|
||||
public final method setX1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setX2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setX6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setY1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setY2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setY6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setZ1-sUp7gFk(p0: int, p1: int): void
|
||||
public final method setZ2-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final method setZ6-sUp7gFk$main(p0: int, p1: int): void
|
||||
public final inner class Regular$Companion
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class VisibilityKt {
|
||||
// source: 'visibility.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final inner class Regular$Companion
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
// 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 ifExpr() = if (DPoint(0.0, 1.0).x > 0.0) DPoint(2.0, 3.0) else DPoint(4.0, 5.0)
|
||||
|
||||
fun whenExpr() = when {
|
||||
DPoint(6.0, 7.0).x > 0.0 -> DPoint(8.0, 9.0)
|
||||
DPoint(10.0, 11.0).x > 0.0 -> DPoint(12.0, 13.0)
|
||||
else -> DPoint(14.0, 15.0)
|
||||
}
|
||||
|
||||
fun ifBody() {
|
||||
if (DPoint(0.0, 1.0).x > 0.0) DPoint(2.0, 3.0) else DPoint(4.0, 5.0)
|
||||
val x = if (DPoint(0.0, 1.0).x > 0.0) DPoint(2.0, 3.0) else DPoint(4.0, 5.0)
|
||||
}
|
||||
|
||||
fun whenBody() {
|
||||
when {
|
||||
DPoint(6.0, 7.0).x > 0.0 -> DPoint(8.0, 9.0)
|
||||
DPoint(10.0, 11.0).x > 0.0 -> DPoint(12.0, 13.0)
|
||||
else -> DPoint(14.0, 15.0)
|
||||
}
|
||||
val x = when {
|
||||
DPoint(6.0, 7.0).x > 0.0 -> DPoint(8.0, 9.0)
|
||||
DPoint(10.0, 11.0).x > 0.0 -> DPoint(12.0, 13.0)
|
||||
else -> DPoint(14.0, 15.0)
|
||||
}
|
||||
}
|
||||
|
||||
// 1 ifExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
|
||||
// 0 ifExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
|
||||
// 1 whenExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
|
||||
// 0 whenExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
|
||||
// 0 ifBody.*(\n .*)*(\n .*box-impl.*)
|
||||
// 0 whenBody.*(\n .*)*(\n .*box-impl.*)
|
||||
@@ -1,67 +0,0 @@
|
||||
// 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 require(index: Int, condition: Boolean) = require(condition) { "$index" }
|
||||
|
||||
fun DPoint.toObject() = this as Any
|
||||
fun DPoint.toDPointOrNull() = this as DPoint?
|
||||
fun Nothing?.toDPointOrNull() = this as DPoint?
|
||||
|
||||
// separate to escape from StackOverflow in regex
|
||||
|
||||
fun equalsChecks1(left: DPoint, right: DPoint) {
|
||||
require(100, left == right)
|
||||
}
|
||||
|
||||
fun equalsChecks2(left: DPoint, right: DPoint) {
|
||||
require(101, left.toObject() == right)
|
||||
}
|
||||
fun equalsChecks3(left: DPoint, right: DPoint) {
|
||||
require(102, left == right.toObject())
|
||||
}
|
||||
fun equalsChecks4(left: DPoint, right: DPoint) {
|
||||
require(103, left.toObject() == right.toObject())
|
||||
}
|
||||
fun equalsChecks5(left: DPoint, right: DPoint) {
|
||||
require(104, null == right)
|
||||
}
|
||||
fun equalsChecks6(left: DPoint, right: DPoint) {
|
||||
require(105, left == null)
|
||||
}
|
||||
fun equalsChecks7(left: DPoint, right: DPoint) {
|
||||
require(106, null as Any? == right)
|
||||
}
|
||||
fun equalsChecks8(left: DPoint, right: DPoint) {
|
||||
require(107, left == null as Any?)
|
||||
}
|
||||
fun equalsChecks9(left: DPoint, right: DPoint) {
|
||||
require(108, null.toDPointOrNull() == right)
|
||||
}
|
||||
fun equalsChecks10(left: DPoint, right: DPoint) {
|
||||
require(109, left == null.toDPointOrNull())
|
||||
}
|
||||
fun equalsChecks11(left: DPoint, right: DPoint) {
|
||||
require(110, left.toDPointOrNull() == right)
|
||||
}
|
||||
fun equalsChecks12(left: DPoint, right: DPoint) {
|
||||
require(111, left == right.toDPointOrNull())
|
||||
}
|
||||
|
||||
// 1 BIPUSH 100\n {4}DLOAD 0\n {4}DLOAD 2\n {4}DLOAD 4\n {4}DLOAD 6\n {4}INVOKESTATIC .*equals-impl0.*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 101\n {4}DLOAD 0\n {4}DLOAD 2\n {4}.*toObject.*\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*box-impl.*\n {4}INVOKESTATIC .*Intrinsics.areEqual.*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 102\n {4}DLOAD 0\n {4}DLOAD 2\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*toObject.*\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 103\n {4}DLOAD 0\n {4}DLOAD 2\n {4}.*toObject.*\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*toObject.*\n {4}INVOKESTATIC .*Intrinsics.areEqual.*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 104\n {4}ICONST_0\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 105\n {4}DLOAD 0\n {4}DLOAD 2\n {4}ACONST_NULL\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 106\n {4}ACONST_NULL\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*box.*\n {4}INVOKESTATIC .*Intrinsics.areEqual.*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 107\n {4}DLOAD 0\n {4}DLOAD 2\n {4}ACONST_NULL\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 108\n {4}ACONST_NULL\n {4}.*toDPointOrNull.*\n {4}ASTORE.*\n {4}ALOAD.*\n {4}DUP\n {4}IFNONNULL.*(\n {3}([^b\n]|b[^o\n]|bo[^x\n]|box-impl-\d)+)*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 109\n {4}DLOAD 0\n {4}DLOAD 2\n {4}ACONST_NULL\n {4}.*toDPointOrNull.*\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 110\n {4}DLOAD 0\n {4}DLOAD 2\n {4}.*toDPointOrNull.*\n {4}ASTORE.*\n {4}ALOAD.*\n {4}DUP\n {4}IFNONNULL.*(\n {3}([^b\n]|b[^o\n]|bo[^x\n]|box-impl-\d)+)*\n {4}INVOKESTATIC .*require
|
||||
// 1 BIPUSH 111\n {4}DLOAD 0\n {4}DLOAD 2\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*toDPointOrNull.*\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
|
||||
@@ -1,76 +0,0 @@
|
||||
// CHECK_BYTECODE_LISTING
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
|
||||
@JvmInline
|
||||
value class A<T : Any>(val x: List<T>)
|
||||
|
||||
@JvmInline
|
||||
value class B(val x: UInt)
|
||||
|
||||
@JvmInline
|
||||
value class C(val x: Int, val y: B, val z: String = "3")
|
||||
|
||||
@JvmInline
|
||||
value class D(val x: C) {
|
||||
constructor(x: Int, y: UInt, z: Int) : this(C(x, B(y), z.toString()))
|
||||
|
||||
init {
|
||||
println(x.x)
|
||||
}
|
||||
}
|
||||
|
||||
class Regular(private val x: D) {
|
||||
fun privateAccess() {
|
||||
listOf(x.x.x)
|
||||
listOf(x.x)
|
||||
listOf(x)
|
||||
}
|
||||
}
|
||||
|
||||
fun functionWithoutBoxes(x: D, y: D) {
|
||||
var z: D = x
|
||||
val t: D = D(C(1, B(3U), "4"))
|
||||
z = t
|
||||
require(z == y)
|
||||
}
|
||||
|
||||
// 2 public static toString-impl\(IILjava/lang/String;\)Ljava/lang/String;
|
||||
// 2 INVOKESTATIC C.toString-impl \(IILjava/lang/String;\)Ljava/lang/String;
|
||||
// 1 INVOKESTATIC D.toString-impl \(IILjava/lang/String;\)Ljava/lang/String;
|
||||
// 2 public static hashCode-impl\(IILjava/lang/String;\)I
|
||||
// 2 INVOKESTATIC C.hashCode-impl \(IILjava/lang/String;\)I
|
||||
// 1 INVOKESTATIC D.hashCode-impl \(IILjava/lang/String;\)I
|
||||
// 2 public static equals-impl\(IILjava/lang/String;Ljava/lang/Object;\)Z
|
||||
// 2 public final static equals-impl0\(IILjava/lang/String;IILjava/lang/String;\)Z
|
||||
// 1 public final static constructor-impl\(III\)LD;
|
||||
// 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
|
||||
// 0 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;
|
||||
// 2 private synthetic <init>\(IILjava/lang/String;\)V
|
||||
// 1 public final static synthetic box-impl\(IILjava/lang/String;\)LD;
|
||||
// 1 public final static synthetic box-impl\(IILjava/lang/String;\)LC;
|
||||
// 1 public final synthetic unbox-impl-0\(\)I
|
||||
// 1 public final synthetic unbox-impl-1\(\)I
|
||||
// 1 public final synthetic unbox-impl-2\(\)Ljava/lang/String;
|
||||
// 1 private final I field-0-0\n
|
||||
// 1 private final I field-0-1\n
|
||||
// 1 private final Ljava/lang/String; field-0-2\n
|
||||
// 0 private final LC; (field.*)x\n
|
||||
// 1 private final I x\n
|
||||
// 1 private final I field-0\n
|
||||
// 1 private final I field-1\n
|
||||
// 1 private final Ljava/lang/String; field-2\n
|
||||
// 1 INVOKESPECIAL C.<init> \(IILjava/lang/String;\)V
|
||||
// 1 INVOKESPECIAL D.<init> \(IILjava/lang/String;\)V
|
||||
// 2 INVOKESTATIC D.box-impl \(IILjava/lang/String;\)LD;
|
||||
// 2 INVOKESTATIC C.box-impl \(IILjava/lang/String;\)LC;
|
||||
// 1 public final static functionWithoutBoxes-GPBa7dw\(IILjava/lang/String;IILjava/lang/String;\)V
|
||||
// 0 functionWithoutBoxes.*(\n {3}.*)*(\n {4}(NEW [ABCD]|.*(box|[ABCD]\.<init>|LA;|LB;|LC;|LD;)))
|
||||
// 1 privateAccess.*(\n .+)*(\n GETFIELD Regular\.x-0-0 : I)(\n .+)*(\n INVOKEVIRTUAL Regular\.getX-0 \(\)LC;)(\n .+)*(\n INVOKESPECIAL Regular\.getX \(\)LD;)
|
||||
@@ -1,71 +0,0 @@
|
||||
// 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)
|
||||
|
||||
class Box(var value: DPoint)
|
||||
|
||||
fun supplier(index: Int) {} // to make usage of the argument
|
||||
fun supplier(index: Int, x: DPoint) {} // to make usage of the argument
|
||||
|
||||
fun reassignVariable(x: DPoint, box: Box) {
|
||||
supplier(100)
|
||||
var p = DPoint(1.0, 2.0) // should not use temporary variables
|
||||
supplier(101, p)
|
||||
p = p // should not use temporary variables
|
||||
supplier(102, p)
|
||||
p = DPoint(3.0, 4.0) // should use tempVars
|
||||
supplier(103, p)
|
||||
p = x // should not use temporary variables
|
||||
supplier(104, p)
|
||||
p = box.value // should use temporary variables
|
||||
supplier(105, p)
|
||||
p = listOf(p)[0] // should use temporary variables
|
||||
supplier(106, p)
|
||||
}
|
||||
|
||||
fun reassignField(x: DPoint, box: Box) {
|
||||
supplier(107)
|
||||
val p = DPoint(5.0, 6.0)
|
||||
supplier(108, p)
|
||||
var b = Box(p) // should not use temporary variables
|
||||
supplier(109)
|
||||
b.value = b.value // should not use temporary variables
|
||||
supplier(110)
|
||||
b.value = DPoint(7.0, 8.0) // should use tempVars
|
||||
supplier(111)
|
||||
b.value = x // should not use temporary variables
|
||||
supplier(112)
|
||||
b.value = box.value // should not use temporary variables
|
||||
supplier(113)
|
||||
b.value = listOf(p)[0] // should use temporary variables
|
||||
supplier(114)
|
||||
}
|
||||
|
||||
// 1 100(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}101
|
||||
// 0 100(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}101
|
||||
// 1 101(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}102
|
||||
// 0 101(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}102
|
||||
// 1 102(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){4}103
|
||||
// 0 102(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){5}103
|
||||
// 1 103(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}104
|
||||
// 0 103(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}104
|
||||
// 1 104(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){4}105
|
||||
// 0 104(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){5}105
|
||||
// 1 105(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){4}106
|
||||
// 0 105(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){5}106
|
||||
|
||||
// 1 107(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}108
|
||||
// 0 107(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}108
|
||||
// 0 108(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){1}109
|
||||
// 0 109(\D|\d\D|\d\d\D)*([DA]STORE(\D|\d\D|\d\d\D)*){1}110
|
||||
// 1 110(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}111
|
||||
// 0 110(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}111
|
||||
// 0 111(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){1}112
|
||||
// 0 112(\D|\d\D|\d\d\D)*([DA]STORE(\D|\d\D|\d\d\D)*){1}113
|
||||
// 1 113(\D|\d\D|\d\d\D)*(ASTORE(\D|\d\D|\d\d\D)*){1}114
|
||||
// 0 113(\D|\d\D|\d\d\D)*(ASTORE(\D|\d\D|\d\d\D)*){2}114
|
||||
@@ -1,49 +0,0 @@
|
||||
// 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 acceptBoxed(x: Any?) {}
|
||||
fun acceptFlattened(x: DPoint) {}
|
||||
fun returnBoxed() = DPoint(3.0, 4.0)
|
||||
|
||||
fun testFlattened2Boxed() {
|
||||
acceptBoxed(DPoint(1.0, 2.0))
|
||||
}
|
||||
|
||||
fun testBoxed2Boxed() {
|
||||
acceptBoxed(returnBoxed())
|
||||
}
|
||||
|
||||
fun testFlattened2Flattened() {
|
||||
acceptFlattened(DPoint(1.0, 2.0))
|
||||
}
|
||||
|
||||
fun testBoxed2Flattened() {
|
||||
acceptFlattened(returnBoxed())
|
||||
}
|
||||
|
||||
fun testIgnoredFlattened() {
|
||||
DPoint(1.0, 2.0)
|
||||
DPoint(1.0, 2.0)
|
||||
}
|
||||
|
||||
fun testIgnoredBoxed() {
|
||||
returnBoxed()
|
||||
}
|
||||
|
||||
// 1 testFlattened2Boxed\(\)V(\n {3}.*)*((\n {3}.*box-impl .*)(\n {3}.*)*){1}
|
||||
// 0 testFlattened2Boxed\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){2}
|
||||
// 0 testBoxed2Boxed\(\)V(\n {3}.*)*((\n {3}.*(box-impl|DSTORE|DLOAD).*)(\n {3}.*)*){1}
|
||||
// 0 testFlattened2Flattened\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){1}
|
||||
// 1 testFlattened2Flattened\(\)V(\n {3}.*)*((\n {3}.*DSTORE.*)(\n {3}.*)*){2}
|
||||
// 0 testFlattened2Flattened\(\)V(\n {3}.*)*((\n {3}.*DSTORE.*)(\n {3}.*)*){3}
|
||||
// 0 testBoxed2Flattened\(\)V(\n {3}.*)*((\n {3}.*box-impl .*)(\n {3}.*)*){1}
|
||||
// 1 testBoxed2Flattened\(\)V(\n {3}.*)*((\n {3}.*unbox-impl.*)(\n {3}.*)*){2}
|
||||
// 0 testBoxed2Flattened\(\)V(\n {3}.*)*((\n {3}.*unbox-impl.*)(\n {3}.*)*){3}
|
||||
// 0 testIgnoredFlattened\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){1}
|
||||
// 0 testIgnoredBoxed\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){1}
|
||||
@@ -1,144 +0,0 @@
|
||||
// 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) {
|
||||
val opposite: DPoint
|
||||
get() = DPoint(-x, -y)
|
||||
}
|
||||
|
||||
class DSegment(var p1: DPoint, var p2: DPoint) {
|
||||
|
||||
val center: DPoint
|
||||
get() = DPoint(p1.x / 2 + p2.x / 2, p1.y / 2 + p2.y / 2)
|
||||
|
||||
var notImplemented: DPoint
|
||||
get() = TODO()
|
||||
set(_) = TODO()
|
||||
|
||||
var point1WithBackingFieldAndDefaultGetter: DPoint = p1
|
||||
var point2WithBackingFieldAndDefaultGetter: DPoint = p1
|
||||
get() = field
|
||||
set(value) {
|
||||
field = value
|
||||
require("${2 + 2}" == "4")
|
||||
}
|
||||
|
||||
var pointWithBackingFieldAndCustomGetter: DPoint = p1
|
||||
get() = field.also { require("${2 + 2}" == "4") }
|
||||
set(value) {
|
||||
field = value
|
||||
require("${2 + 2}" == "4")
|
||||
}
|
||||
|
||||
init {
|
||||
p1 = p1
|
||||
}
|
||||
}
|
||||
|
||||
fun tryGetSegment(segment: DSegment) {
|
||||
segment.p1
|
||||
segment.p1.x
|
||||
segment.p1.y
|
||||
segment.p2
|
||||
segment.p2.x
|
||||
segment.p2.y
|
||||
segment.center
|
||||
segment.center.x
|
||||
segment.center.y
|
||||
segment.notImplemented
|
||||
segment.notImplemented.x
|
||||
segment.notImplemented.y
|
||||
segment.point1WithBackingFieldAndDefaultGetter
|
||||
segment.point1WithBackingFieldAndDefaultGetter.x
|
||||
segment.point1WithBackingFieldAndDefaultGetter.y
|
||||
segment.point2WithBackingFieldAndDefaultGetter
|
||||
segment.point2WithBackingFieldAndDefaultGetter.x
|
||||
segment.point2WithBackingFieldAndDefaultGetter.y
|
||||
segment.pointWithBackingFieldAndCustomGetter
|
||||
segment.pointWithBackingFieldAndCustomGetter.x
|
||||
segment.pointWithBackingFieldAndCustomGetter.y
|
||||
}
|
||||
|
||||
fun trySetSegment(segment: DSegment) {
|
||||
segment.notImplemented = segment.p1
|
||||
segment.point1WithBackingFieldAndDefaultGetter = segment.p1
|
||||
segment.point2WithBackingFieldAndDefaultGetter = segment.p1
|
||||
segment.pointWithBackingFieldAndCustomGetter = segment.p1
|
||||
segment.p1 = segment.p1
|
||||
segment.p2 = segment.p2
|
||||
}
|
||||
|
||||
// 0 public final getOpposite\(\)LDPoint;
|
||||
// 1 public final static getOpposite-impl\(DD\)LDPoint;
|
||||
// 1 private D p1-0
|
||||
// 1 private D p1-1
|
||||
// 0 private DPoint; p1
|
||||
// 1 private D p2-0
|
||||
// 1 private D p2-1
|
||||
// 0 private DPoint; p2
|
||||
// 1 private D point1WithBackingFieldAndDefaultGetter-0
|
||||
// 1 private D point1WithBackingFieldAndDefaultGetter-1
|
||||
// 0 private DPoint; point1WithBackingFieldAndDefaultGetter
|
||||
// 1 private D point2WithBackingFieldAndDefaultGetter-0
|
||||
// 1 private D point2WithBackingFieldAndDefaultGetter-1
|
||||
// 0 private DPoint; point2WithBackingFieldAndDefaultGetter
|
||||
// 1 private D pointWithBackingFieldAndCustomGetter-0
|
||||
// 1 private D pointWithBackingFieldAndCustomGetter-1
|
||||
// 0 private DPoint; pointWithBackingFieldAndCustomGetter
|
||||
// 0 private DPoint; notImplemented
|
||||
// 0 private D notImplemented
|
||||
// 0 private DPoint; center
|
||||
// 0 private D center
|
||||
// 1 public <init>\(DDDD\)V
|
||||
// 0 public <init>\(DDDD\)V.*(\n {3}.*)*(\n {4}.*box)
|
||||
// 1 public final getP1\(\)LDPoint;
|
||||
// 1 public final setP1-sUp7gFk\(DD\)V
|
||||
// 1 public final getP2\(\)LDPoint;
|
||||
// 1 public final setP2-sUp7gFk\(DD\)V
|
||||
// 1 public final getCenter\(\)LDPoint;
|
||||
// 1 public final getNotImplemented\(\)LDPoint;
|
||||
// 1 public final setNotImplemented-sUp7gFk\(DD\)V
|
||||
// 1 public final getPoint1WithBackingFieldAndDefaultGetter\(\)LDPoint;
|
||||
// 1 public final setPoint1WithBackingFieldAndDefaultGetter-sUp7gFk\(DD\)V
|
||||
// 1 public final getPoint2WithBackingFieldAndDefaultGetter\(\)LDPoint;
|
||||
// 1 public final setPoint2WithBackingFieldAndDefaultGetter-sUp7gFk\(DD\)V
|
||||
// 1 public final getPointWithBackingFieldAndCustomGetter\(\)LDPoint;
|
||||
// 1 public final setPointWithBackingFieldAndCustomGetter-sUp7gFk\(DD\)V
|
||||
// 1 public final synthetic getP1-0\(\)D
|
||||
// 1 public final synthetic getP1-1\(\)D
|
||||
// 1 public final synthetic getP2-0\(\)D
|
||||
// 1 public final synthetic getP2-1\(\)D
|
||||
// 1 public final synthetic getPoint1WithBackingFieldAndDefaultGetter-0\(\)D
|
||||
// 1 public final synthetic getPoint1WithBackingFieldAndDefaultGetter-1\(\)D
|
||||
// 1 public final synthetic getPoint2WithBackingFieldAndDefaultGetter-0\(\)D
|
||||
// 1 public final synthetic getPoint2WithBackingFieldAndDefaultGetter-1\(\)D
|
||||
// 0 public final getCenter\$
|
||||
// 0 public final getNotImplemented\$
|
||||
// 0 public final getPointWithBackingFieldAndCustomGetter\$
|
||||
// 0 ^ {2}\b.*get.*\$.*(\n {3}.*)*(\n {4}.*\.box)
|
||||
// 1 tryGetSegment\(LDSegment;\)V
|
||||
// 0 try[GS]etSegment\(LDSegment;\)V.*(\n {3}.*)*(\n {4}.*\.box)
|
||||
// 1 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}.*LDPoint;)){7}
|
||||
// 0 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}.*LDPoint;)){8}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*(\n {3}.*)*(\n {4}.*LDPoint;)
|
||||
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setNotImplemented-sUp7gFk \(DD\)V)){1}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setNotImplemented-sUp7gFk \(DD\)V)){2}
|
||||
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint1WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){1}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint1WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){2}
|
||||
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint2WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){1}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint2WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){2}
|
||||
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPointWithBackingFieldAndCustomGetter-sUp7gFk \(DD\)V)){1}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPointWithBackingFieldAndCustomGetter-sUp7gFk \(DD\)V)){2}
|
||||
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP1-sUp7gFk \(DD\)V)){1}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP1-sUp7gFk \(DD\)V)){2}
|
||||
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP2-sUp7gFk \(DD\)V)){1}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP2-sUp7gFk \(DD\)V)){2}
|
||||
// 0 try[GS]etSegment\(LDSegment;\)V.*(\n {3}.*)*(\n {4}INVOKEVIRTUAL DPoint\.get[XY] \(\)D)
|
||||
// 1 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*-[01] \(\)D)){14}
|
||||
// 0 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*-[01] \(\)D)){15}
|
||||
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*-[01] \(\)D)){12}
|
||||
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*-[01] \(\)D)){13}
|
||||
@@ -1,38 +0,0 @@
|
||||
// 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 tryExpr() = try {
|
||||
DPoint(0.0, 1.0)
|
||||
} catch(_: Throwable) {
|
||||
DPoint(2.0, 3.0)
|
||||
} finally {
|
||||
DPoint(4.0, 5.0)
|
||||
}
|
||||
|
||||
fun tryBody() {
|
||||
try {
|
||||
DPoint(0.0, 1.0)
|
||||
} catch(_: Throwable) {
|
||||
DPoint(2.0, 3.0)
|
||||
} finally {
|
||||
DPoint(4.0, 5.0)
|
||||
}
|
||||
val x: DPoint = try {
|
||||
DPoint(0.0, 1.0)
|
||||
} catch(_: Throwable) {
|
||||
DPoint(2.0, 3.0)
|
||||
} finally {
|
||||
DPoint(4.0, 5.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 1 tryExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
|
||||
// 0 tryExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
|
||||
// 0 tryBody.*(\n .*)*(\n .*box-impl.*)
|
||||
-11
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.test.runners.codegen;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -5456,16 +5455,6 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/valueClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ValueClasses {
|
||||
@Test
|
||||
public void testAllFilesPresentInValueClasses() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/valueClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/varargs")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
-60
@@ -50189,71 +50189,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/valueClasses/classFlattening.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("complex.kt")
|
||||
public void testComplex() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/complex.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionalExpressions.kt")
|
||||
public void testConditionalExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/conditionalExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equality.kt")
|
||||
public void testEquality() throws Exception {
|
||||
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 {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/mfvcFieldInitializationOrder.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrides.kt")
|
||||
public void testOverrides() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/overrides.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrides_inlineClass.kt")
|
||||
public void testOverrides_inlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/overrides_inlineClass.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrides_typeParameters.kt")
|
||||
public void testOverrides_typeParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/overrides_typeParameters.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("throwingMFVCReassignments.kt")
|
||||
public void testThrowingMFVCReassignments() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("tryExpressions.kt")
|
||||
public void testTryExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("visibility.kt")
|
||||
public void testVisibility() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/visibility.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
-53
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.test.runners.codegen;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -5780,58 +5779,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/valueClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ValueClasses {
|
||||
@Test
|
||||
public void testAllFilesPresentInValueClasses() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/valueClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conditionalExpressions.kt")
|
||||
public void testConditionalExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/conditionalExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalsBoxTest.kt")
|
||||
public void testEqualsBoxTest() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/equalsBoxTest.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcDeclaration.kt")
|
||||
public void testMfvcDeclaration() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcDeclaration.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcReassignments.kt")
|
||||
public void testMfvcReassignments() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/mfvcReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("passingMFVC2Functions.kt")
|
||||
public void testPassingMFVC2Functions() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/passingMFVC2Functions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("regularClassWithMFVC.kt")
|
||||
public void testRegularClassWithMFVC() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/regularClassWithMFVC.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("tryExpressions.kt")
|
||||
public void testTryExpressions() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/varargs")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
Reference in New Issue
Block a user