[IR] Support default arguments
Signed-off-by: Evgeniy.Zhelenskiy <Evgeniy.Zhelenskiy@jetbrains.com> #KT-1179
This commit is contained in:
committed by
Space Team
parent
0c70b60988
commit
51e76aa19a
+6
@@ -50441,6 +50441,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/valueClasses/conditionalExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultParameters.kt")
|
||||
public void testDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/defaultParameters.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equality.kt")
|
||||
public void testEquality() throws Exception {
|
||||
|
||||
+64
-23
@@ -606,18 +606,50 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
.zipWithNext { start: Int, finish: Int -> replacement.explicitParameters.slice(start until finish) }
|
||||
)
|
||||
for (i in old2newList.indices) {
|
||||
val (param, newParamList) = old2newList[i]
|
||||
val (oldParameter, newParamList) = old2newList[i]
|
||||
when (val structure = parametersStructure[i]) {
|
||||
is RegularMapping -> valueDeclarationsRemapper.registerReplacement(oldParameter, newParamList.single())
|
||||
is MultiFieldValueClassMapping -> {
|
||||
val mfvcNodeInstance = structure.rootMfvcNode.createInstanceFromValueDeclarationsAndBoxType(
|
||||
structure.boxedType, newParamList
|
||||
)
|
||||
valueDeclarationsRemapper.registerReplacement(param, mfvcNodeInstance)
|
||||
valueDeclarationsRemapper.registerReplacement(oldParameter, mfvcNodeInstance)
|
||||
}
|
||||
|
||||
is RegularMapping -> valueDeclarationsRemapper.registerReplacement(param, newParamList.single())
|
||||
}
|
||||
}
|
||||
|
||||
withinScope(replacement) {
|
||||
addDefaultArgumentsIfNeeded(replacement, old2newList, parametersStructure)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addDefaultArgumentsIfNeeded(
|
||||
replacement: IrFunction,
|
||||
old2newList: List<Pair<IrValueParameter, List<IrValueParameter>>>,
|
||||
parametersStructure: List<RemappedParameter>
|
||||
) {
|
||||
for (i in old2newList.indices) {
|
||||
val (param, newParamList) = old2newList[i]
|
||||
val defaultValue = replacements.oldMfvcDefaultArguments[param] ?: continue
|
||||
val structure = parametersStructure[i]
|
||||
if (structure is MultiFieldValueClassMapping) {
|
||||
newParamList[0].defaultValue = with(context.createJvmIrBuilder(replacement.symbol)) {
|
||||
irExprBody(irBlock {
|
||||
val mfvcNodeInstance = structure.rootMfvcNode.createInstanceFromValueDeclarationsAndBoxType(
|
||||
param.type as IrSimpleType, newParamList
|
||||
)
|
||||
flattenExpressionTo(defaultValue, mfvcNodeInstance)
|
||||
+irGet(newParamList[0])
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitParameter(parameter: IrValueParameter) {
|
||||
if (parameter.origin != IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_PARAMETER) {
|
||||
super.visitParameter(parameter)
|
||||
}
|
||||
}
|
||||
|
||||
fun RootMfvcNode.replacePrimaryMultiFieldValueClassConstructor() {
|
||||
@@ -1033,12 +1065,14 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
if (constructor.isPrimary && constructor.constructedClass.isMultiFieldValueClass &&
|
||||
constructor.origin != JvmLoweredDeclarationOrigin.STATIC_MULTI_FIELD_VALUE_CLASS_CONSTRUCTOR
|
||||
) {
|
||||
val oldArguments = List(expression.valueArgumentsCount) { expression.getValueArgument(it) }
|
||||
val oldArguments = List(expression.valueArgumentsCount) {
|
||||
expression.getValueArgument(it) ?: error("Default arguments for MFVC primary constructors are not yet supported")
|
||||
}
|
||||
require(rootNode.subnodes.size == oldArguments.size) {
|
||||
"Old ${constructor.render()} must have ${rootNode.subnodes.size} arguments but got ${oldArguments.size}"
|
||||
}
|
||||
for ((subnode, argument) in rootNode.subnodes zip oldArguments) {
|
||||
argument?.let { flattenExpressionTo(it, instance[subnode.name]!!) }
|
||||
flattenExpressionTo(argument, instance[subnode.name]!!)
|
||||
}
|
||||
+irCall(rootNode.primaryConstructorImpl).apply {
|
||||
copyTypeArgumentsFrom(expression)
|
||||
@@ -1143,18 +1177,26 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
||||
}
|
||||
|
||||
private sealed class BlockOrBody {
|
||||
data class Body(val body: IrBody) : BlockOrBody()
|
||||
data class Block(val block: IrBlock) : BlockOrBody()
|
||||
abstract val element: IrElement
|
||||
|
||||
data class Body(val body: IrBody) : BlockOrBody() {
|
||||
override val element get() = body
|
||||
}
|
||||
|
||||
data class Block(val block: IrBlock) : BlockOrBody() {
|
||||
override val element get() = block
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the most narrow block or body which contains all usages of each of the given variables
|
||||
*/
|
||||
private fun findNearestBlocksForVariables(variables: Set<IrVariable>, body: IrBody): Map<IrVariable, BlockOrBody?> {
|
||||
private fun findNearestBlocksForVariables(variables: Set<IrVariable>, body: BlockOrBody): Map<IrVariable, BlockOrBody?> {
|
||||
if (variables.isEmpty()) return mapOf()
|
||||
val variableUsages = mutableMapOf<BlockOrBody, MutableSet<IrVariable>>()
|
||||
val childrenBlocks = mutableMapOf<BlockOrBody, MutableList<BlockOrBody>>()
|
||||
|
||||
body.acceptVoid(object : IrElementVisitorVoid {
|
||||
body.element.acceptVoid(object : IrElementVisitorVoid {
|
||||
private val stack = mutableListOf<BlockOrBody>()
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildren(this, null)
|
||||
@@ -1168,7 +1210,7 @@ private fun findNearestBlocksForVariables(variables: Set<IrVariable>, body: IrBo
|
||||
}
|
||||
|
||||
override fun visitBlock(expression: IrBlock) {
|
||||
childrenBlocks.getOrPut(currentStackElement()!!) { mutableListOf() }.add(Block(expression))
|
||||
currentStackElement()?.let { childrenBlocks.getOrPut(it) { mutableListOf() }.add(Block(expression)) }
|
||||
stack.add(Block(expression))
|
||||
super.visitBlock(expression)
|
||||
require(stack.removeLast() == Block(expression)) { "Invalid stack" }
|
||||
@@ -1195,7 +1237,7 @@ private fun findNearestBlocksForVariables(variables: Set<IrVariable>, body: IrBo
|
||||
}
|
||||
}
|
||||
|
||||
return variables.associateWith { dfs(BlockOrBody.Body(body), it) }
|
||||
return variables.associateWith { dfs(body, it) }
|
||||
}
|
||||
|
||||
private fun IrStatement.containsUsagesOf(variablesSet: Set<IrVariable>): Boolean {
|
||||
@@ -1217,20 +1259,20 @@ private fun IrStatement.containsUsagesOf(variablesSet: Set<IrVariable>): Boolean
|
||||
return used
|
||||
}
|
||||
|
||||
private fun IrBody.makeBodyWithAddedVariables(context: JvmBackendContext, variables: Set<IrVariable>, symbol: IrSymbol) =
|
||||
BlockOrBody.Body(this).makeBodyWithAddedVariables(context, variables, symbol) as IrBody
|
||||
|
||||
/**
|
||||
* Adds declarations of the variables to the most narrow possible block or body.
|
||||
* It adds them before the first usage within the block and inlines initialization of them when possible.
|
||||
*/
|
||||
fun IrBody.makeBodyWithAddedVariables(
|
||||
context: JvmBackendContext,
|
||||
variables: Set<IrVariable>,
|
||||
symbol: IrSymbol
|
||||
): IrBody {
|
||||
private fun BlockOrBody.makeBodyWithAddedVariables(context: JvmBackendContext, variables: Set<IrVariable>, symbol: IrSymbol): IrElement {
|
||||
if (variables.isEmpty()) return element
|
||||
val nearestBlocks = findNearestBlocksForVariables(variables, this)
|
||||
val containingVariables: Map<BlockOrBody, List<IrVariable>> = nearestBlocks.entries
|
||||
.mapNotNull { (k, v) -> if (v != null) k to v else null }
|
||||
.groupBy({ (_, v) -> v }, { (k, _) -> k })
|
||||
return transform(object : IrElementTransformerVoid() {
|
||||
return element.transform(object : IrElementTransformerVoid() {
|
||||
private fun getFlattenedStatements(container: IrStatementContainer): Sequence<IrStatement> = sequence {
|
||||
for (statement in container.statements) {
|
||||
if (statement is IrStatementContainer) {
|
||||
@@ -1306,12 +1348,11 @@ fun IrBody.makeBodyWithAddedVariables(
|
||||
override fun visitExpressionBody(body: IrExpressionBody): IrBody {
|
||||
val lowering = this
|
||||
containingVariables[BlockOrBody.Body(body)]?.takeIf { it.isNotEmpty() }?.let { bodyVars ->
|
||||
val blockBody = context.createJvmIrBuilder(symbol).irBlockBody {
|
||||
+irReturn(body.expression.transform(lowering, null))
|
||||
return with(context.createJvmIrBuilder(symbol)) {
|
||||
val blockBody = irBlock { +body.expression.transform(lowering, null) }
|
||||
replaceSetVariableWithInitialization(bodyVars, blockBody)
|
||||
irExprBody(blockBody)
|
||||
}
|
||||
blockBody.transformChildrenVoid()
|
||||
replaceSetVariableWithInitialization(bodyVars, blockBody)
|
||||
return blockBody
|
||||
}
|
||||
return super.visitExpressionBody(body)
|
||||
}
|
||||
|
||||
+17
-4
@@ -89,7 +89,7 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
|
||||
private fun transformFlattenedConstructor(function: IrConstructor, replacement: IrConstructor): List<IrDeclaration>? {
|
||||
replacement.valueParameters.forEach {
|
||||
it.transformChildrenVoid()
|
||||
visitParameter(it)
|
||||
it.defaultValue?.patchDeclarationParents(replacement)
|
||||
}
|
||||
allScopes.push(createScope(function))
|
||||
@@ -106,9 +106,18 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
|
||||
protected abstract fun transformSecondaryConstructorFlat(constructor: IrConstructor, replacement: IrSimpleFunction): List<IrDeclaration>
|
||||
|
||||
open fun visitParameter(parameter: IrValueParameter) {
|
||||
parameter.transformChildrenVoid()
|
||||
}
|
||||
|
||||
final override fun visitValueParameterNew(declaration: IrValueParameter): IrStatement {
|
||||
visitParameter(declaration)
|
||||
return declaration
|
||||
}
|
||||
|
||||
private fun transformSimpleFunctionFlat(function: IrSimpleFunction, replacement: IrSimpleFunction): List<IrDeclaration> {
|
||||
replacement.valueParameters.forEach {
|
||||
it.transformChildrenVoid()
|
||||
visitParameter(it)
|
||||
it.defaultValue?.patchDeclarationParents(replacement)
|
||||
}
|
||||
allScopes.push(createScope(replacement))
|
||||
@@ -184,7 +193,11 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
function,
|
||||
replacement,
|
||||
when {
|
||||
function.isTypedEquals() -> InlineClassAbi.mangledNameFor(function, mangleReturnTypes = false, useOldMangleRules = false)
|
||||
function.isValueClassTypedEquals -> InlineClassAbi.mangledNameFor(
|
||||
function,
|
||||
mangleReturnTypes = false,
|
||||
useOldMangleRules = false
|
||||
)
|
||||
// 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)
|
||||
@@ -233,4 +246,4 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
abstract fun createBridgeDeclaration(source: IrSimpleFunction, replacement: IrSimpleFunction, mangledName: Name): IrSimpleFunction
|
||||
|
||||
protected abstract fun createBridgeBody(source: IrSimpleFunction, target: IrSimpleFunction, original: IrFunction, inverted: Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
+22
-14
@@ -6,14 +6,14 @@
|
||||
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.backend.jvm.ir.*
|
||||
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.builders.irExprBody
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
@@ -44,29 +44,34 @@ class MemoizedMultiFieldValueClassReplacements(
|
||||
targetFunction: IrFunction,
|
||||
originWhenFlattened: IrDeclarationOrigin,
|
||||
): RemappedParameter {
|
||||
val oldParam = this
|
||||
if (!type.needsMfvcFlattening()) return RemappedParameter.RegularMapping(
|
||||
targetFunction.addValueParameter {
|
||||
updateFrom(this@grouped)
|
||||
this.name = this@grouped.name
|
||||
updateFrom(oldParam)
|
||||
this.name = oldParam.name
|
||||
index = targetFunction.valueParameters.size
|
||||
}.apply {
|
||||
copyAnnotationsFrom(this@grouped)
|
||||
defaultValue = oldParam.defaultValue
|
||||
copyAnnotationsFrom(oldParam)
|
||||
}
|
||||
)
|
||||
val rootMfvcNode = this@MemoizedMultiFieldValueClassReplacements.getRootMfvcNode(type.erasedUpperBound)!!
|
||||
require(!hasDefaultValue()) { "Default parameters values are not supported for multi-field value classes" }
|
||||
val rootMfvcNode = this@MemoizedMultiFieldValueClassReplacements.getRootMfvcNode(type.erasedUpperBound)
|
||||
defaultValue?.expression?.let { oldMfvcDefaultArguments.putIfAbsent(this, it) }
|
||||
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}")
|
||||
updateFrom(oldParam)
|
||||
this.name = Name.identifier("${name ?: oldParam.name}-${leaf.fullFieldName}")
|
||||
type = leaf.type.substitute(localSubstitutionMap)
|
||||
origin = originWhenFlattened
|
||||
index = targetFunction.valueParameters.size
|
||||
}.apply {
|
||||
defaultValue = null
|
||||
copyAnnotationsFrom(this@grouped)
|
||||
isAssignable = isAssignable || oldParam.defaultValue != null
|
||||
}.also { newParam ->
|
||||
newParam.defaultValue = oldParam.defaultValue?.let {
|
||||
context.createJvmIrBuilder(targetFunction.symbol).run { irExprBody(irGet(newParam)) }
|
||||
}
|
||||
require(oldParam.annotations.isEmpty()) { "Annotations are not supported for MFVC parameters" }
|
||||
}
|
||||
}
|
||||
return MultiFieldValueClassMapping(rootMfvcNode, newType, valueParameters)
|
||||
@@ -79,6 +84,9 @@ class MemoizedMultiFieldValueClassReplacements(
|
||||
originWhenFlattened: IrDeclarationOrigin,
|
||||
): List<RemappedParameter> = map { it.grouped(name, substitutionMap, targetFunction, originWhenFlattened) }
|
||||
|
||||
|
||||
val oldMfvcDefaultArguments = ConcurrentHashMap<IrValueParameter, IrExpression>()
|
||||
|
||||
private fun buildReplacement(
|
||||
function: IrFunction,
|
||||
replacementOrigin: IrDeclarationOrigin,
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// CHECK_BYTECODE_LISTING
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WORKS_WHEN_VALUE_CLASS
|
||||
// LANGUAGE: +ValueClasses
|
||||
|
||||
@JvmInline
|
||||
value class DPoint(/*inline */val x: Double/* = 1.0*/, /*inline */val y: Double/* = 2.0*/) {
|
||||
fun f1(a: Int, b: Int = -1, c: DPoint = DPoint(-2.0, -3.0)) = listOf(this, x, y, a, b, c)
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class DSegment(/*inline */val p1: DPoint/* = DPoint(3.0, 4.0)*/, /*inline */val p2: DPoint/* = DPoint(5.0, 6.0)*/, /*inline */val n: Int/* = 7*/) {
|
||||
fun f2(a: Int, b: Int = -1, c: DPoint = DPoint(-2.0, -3.0)) = listOf(this, p1, p2, n, a, b, c)
|
||||
}
|
||||
|
||||
data class Wrapper(val segment: DSegment = DSegment(DPoint(8.0, 9.0), DPoint(10.0, 11.0), 7), val n: Int = 12) {
|
||||
fun f3(a: Int, b: Int = -1, c: DPoint = DPoint(-2.0, -3.0)) = listOf(this, segment, n, a, b, c)
|
||||
}
|
||||
|
||||
fun complexFun(a1: Double, a2: DPoint, a3: Double = a1 * a2.x * a2.y, a4: DPoint = DPoint(a2.x * a1 * a3, a2.y * a1 * a3)) = "$a1, $a2, $a3, $a4"
|
||||
|
||||
inline fun complexInlineFun(a1: Double, a2: DPoint, a3: Double = a1 * a2.x * a2.y, a4: DPoint = DPoint(a2.x * a1 * a3, a2.y * a1 * a3)) = "$a1, $a2, $a3, $a4"
|
||||
|
||||
fun box(): String {
|
||||
// comments bellow are because MFVC primary constructors default parameters require support of inline arguments in regular functions
|
||||
// require(DPoint() == DPoint(1.0, 2.0)) { "${DPoint()} ${DPoint(1.0, 2.0)}" }
|
||||
// require(DPoint(3.0) == DPoint(3.0, 2.0)) { "${DPoint()} ${DPoint(3.0, 2.0)}" }
|
||||
// require(DPoint(x = 3.0) == DPoint(3.0, 2.0)) { "${DPoint()} ${DPoint(3.0, 2.0)}" }
|
||||
// require(DPoint(y = 3.0) == DPoint(1.0, 3.0)) { "${DPoint()} ${DPoint(1.0, 3.0)}" }
|
||||
// val defaultDPoint = DPoint()
|
||||
val defaultDPoint = DPoint(1.0, 2.0)
|
||||
require(defaultDPoint.f1(4) == listOf(DPoint(1.0, 2.0), 1.0, 2.0, 4, -1, DPoint(-2.0, -3.0))) {
|
||||
defaultDPoint.f1(4).toString()
|
||||
}
|
||||
require(defaultDPoint.f1(4, 1, DPoint(2.0, 3.0)) == listOf(DPoint(1.0, 2.0), 1.0, 2.0, 4, 1, DPoint(2.0, 3.0))) {
|
||||
defaultDPoint.f1(4, 1, DPoint(2.0, 3.0)).toString()
|
||||
}
|
||||
require(DPoint(-1.0, -2.0).f1(4) == listOf(DPoint(-1.0, -2.0), -1.0, -2.0, 4, -1, DPoint(-2.0, -3.0))) {
|
||||
defaultDPoint.f1(4).toString()
|
||||
}
|
||||
require(DPoint(-1.0, -2.0).f1(4, 1, DPoint(2.0, 3.0)) == listOf(DPoint(-1.0, -2.0), -1.0, -2.0, 4, 1, DPoint(2.0, 3.0))) {
|
||||
defaultDPoint.f1(4, 1, DPoint(2.0, 3.0)).toString()
|
||||
}
|
||||
|
||||
// require(DSegment() == DSegment(DPoint(3.0, 4.0), DPoint(5.0, 6.0), 7)) { DSegment().toString() }
|
||||
// val defaultDSegment = DSegment()
|
||||
val defaultDSegment = DSegment(DPoint(3.0, 4.0), DPoint(5.0, 6.0), 7)
|
||||
require(defaultDSegment.f2(100) == listOf(defaultDSegment, DPoint(3.0, 4.0), DPoint(5.0, 6.0), 7, 100, -1, DPoint(-2.0, -3.0))) {
|
||||
defaultDSegment.f2(100).toString()
|
||||
}
|
||||
require(defaultDSegment.f2(100, b = 1) == listOf(defaultDSegment, DPoint(3.0, 4.0), DPoint(5.0, 6.0), 7, 100, 1, DPoint(-2.0, -3.0))) {
|
||||
defaultDSegment.f2(100, b = 1).toString()
|
||||
}
|
||||
|
||||
require(Wrapper() == Wrapper(DSegment(DPoint(8.0, 9.0), DPoint(10.0, 11.0), 7), 12)) { Wrapper().toString() }
|
||||
require(Wrapper().f3(100) == listOf(Wrapper(), DSegment(DPoint(8.0, 9.0), DPoint(10.0, 11.0), 7), 12, 100, -1, DPoint(-2.0, -3.0))) {
|
||||
Wrapper().f3(100).toString()
|
||||
}
|
||||
require(Wrapper().f3(100, b = 1) == listOf(Wrapper(), DSegment(DPoint(8.0, 9.0), DPoint(10.0, 11.0), 7), 12, 100, 1, DPoint(-2.0, -3.0))) {
|
||||
Wrapper().f3(100, b = 1).toString()
|
||||
}
|
||||
|
||||
require(complexFun(2.0, DPoint(3.0, 5.0)) == "2.0, ${DPoint(3.0, 5.0)}, 30.0, ${DPoint(180.0, 300.0)}") {
|
||||
complexFun(2.0, DPoint(3.0, 5.0))
|
||||
}
|
||||
require(complexFun(2.0, DPoint(3.0, 5.0), 7.0) == "2.0, ${DPoint(3.0, 5.0)}, 7.0, ${DPoint(42.0, 70.0)}") {
|
||||
complexFun(2.0, DPoint(3.0, 5.0), 7.0)
|
||||
}
|
||||
require(complexFun(2.0, DPoint(3.0, 5.0), a4 = DPoint(11.0, 13.0)) == "2.0, ${DPoint(3.0, 5.0)}, 30.0, ${DPoint(11.0, 13.0)}") {
|
||||
complexFun(2.0, DPoint(3.0, 5.0), a4 = DPoint(11.0, 13.0))
|
||||
}
|
||||
require(complexFun(2.0, DPoint(3.0, 5.0), 7.0, DPoint(11.0, 13.0)) == "2.0, ${DPoint(3.0, 5.0)}, 7.0, ${DPoint(11.0, 13.0)}") {
|
||||
complexFun(2.0, DPoint(3.0, 5.0), 7.0, DPoint(11.0, 13.0))
|
||||
}
|
||||
|
||||
require(complexInlineFun(2.0, DPoint(3.0, 5.0)) == "2.0, ${DPoint(3.0, 5.0)}, 30.0, ${DPoint(180.0, 300.0)}") {
|
||||
complexInlineFun(2.0, DPoint(3.0, 5.0))
|
||||
}
|
||||
require(complexInlineFun(2.0, DPoint(3.0, 5.0), 7.0) == "2.0, ${DPoint(3.0, 5.0)}, 7.0, ${DPoint(42.0, 70.0)}") {
|
||||
complexInlineFun(2.0, DPoint(3.0, 5.0), 7.0)
|
||||
}
|
||||
require(complexInlineFun(2.0, DPoint(3.0, 5.0), a4 = DPoint(11.0, 13.0)) == "2.0, ${DPoint(3.0, 5.0)}, 30.0, ${DPoint(11.0, 13.0)}") {
|
||||
complexInlineFun(2.0, DPoint(3.0, 5.0), a4 = DPoint(11.0, 13.0))
|
||||
}
|
||||
require(complexInlineFun(2.0, DPoint(3.0, 5.0), 7.0, DPoint(11.0, 13.0)) == "2.0, ${DPoint(3.0, 5.0)}, 7.0, ${DPoint(11.0, 13.0)}") {
|
||||
complexInlineFun(2.0, DPoint(3.0, 5.0), 7.0, DPoint(11.0, 13.0))
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class DPoint {
|
||||
// source: 'defaultParameters.kt'
|
||||
private final field x: double
|
||||
private final field y: 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 synthetic static method f1-lIoT8es$default(p0: double, p1: double, p2: int, p3: int, p4: double, p5: double, p6: int, p7: java.lang.Object): java.util.List
|
||||
public final static @org.jetbrains.annotations.NotNull method f1-lIoT8es(p0: double, p1: double, p2: int, p3: int, p4: double, p5: double): java.util.List
|
||||
public final method getX(): double
|
||||
public final method getY(): double
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: double, p1: double): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: double, p1: double): java.lang.String
|
||||
public synthetic final method unbox-impl-x(): double
|
||||
public synthetic final method unbox-impl-y(): double
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class DSegment {
|
||||
// source: 'defaultParameters.kt'
|
||||
private final field n: int
|
||||
private final field p1-x: double
|
||||
private final field p1-y: double
|
||||
private final field p2-x: double
|
||||
private final field p2-y: double
|
||||
private synthetic method <init>(p0: double, p1: double, p2: double, p3: double, p4: int): void
|
||||
public synthetic final static method box-impl(p0: double, p1: double, p2: double, p3: double, p4: int): DSegment
|
||||
public final static method constructor-impl(p0: double, p1: double, p2: double, p3: double, p4: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: double, p1: double, p2: double, p3: double, p4: int, p5: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double, p4: int, p5: double, p6: double, p7: double, p8: double, p9: int): boolean
|
||||
public synthetic static method f2-lIoT8es$default(p0: double, p1: double, p2: double, p3: double, p4: int, p5: int, p6: int, p7: double, p8: double, p9: int, p10: java.lang.Object): java.util.List
|
||||
public final static @org.jetbrains.annotations.NotNull method f2-lIoT8es(p0: double, p1: double, p2: double, p3: double, p4: int, p5: int, p6: int, p7: double, p8: double): java.util.List
|
||||
public final method getN(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getP1(): DPoint
|
||||
public final @org.jetbrains.annotations.NotNull method getP2(): DPoint
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: double, p1: double, p2: double, p3: double, p4: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: double, p1: double, p2: double, p3: double, p4: int): java.lang.String
|
||||
public synthetic final method unbox-impl-n(): int
|
||||
public synthetic final method unbox-impl-p1(): DPoint
|
||||
public synthetic final method unbox-impl-p1-x(): double
|
||||
public synthetic final method unbox-impl-p1-y(): double
|
||||
public synthetic final method unbox-impl-p2(): DPoint
|
||||
public synthetic final method unbox-impl-p2-x(): double
|
||||
public synthetic final method unbox-impl-p2-y(): double
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class DefaultParametersKt {
|
||||
// source: 'defaultParameters.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public synthetic static method complexFun-552ch2I$default(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double, p6: int, p7: java.lang.Object): java.lang.String
|
||||
public final static @org.jetbrains.annotations.NotNull method complexFun-552ch2I(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double): java.lang.String
|
||||
public synthetic static method complexInlineFun-552ch2I$default(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double, p6: int, p7: java.lang.Object): java.lang.String
|
||||
public final static @org.jetbrains.annotations.NotNull method complexInlineFun-552ch2I(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double): java.lang.String
|
||||
public final inner class kotlin/jvm/internal/Ref$DoubleRef
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Wrapper {
|
||||
// source: 'defaultParameters.kt'
|
||||
private final field n: int
|
||||
private final field segment-n: int
|
||||
private final field segment-p1-x: double
|
||||
private final field segment-p1-y: double
|
||||
private final field segment-p2-x: double
|
||||
private final field segment-p2-y: double
|
||||
public method <init>(): void
|
||||
public method <init>(p0: double, p1: double, p2: double, p3: double, p4: int, p5: int): void
|
||||
public synthetic method <init>(p0: double, p1: double, p2: double, p3: double, p4: int, p5: int, p6: int, p7: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public final @org.jetbrains.annotations.NotNull method component1(): DSegment
|
||||
public final method component2(): int
|
||||
public synthetic static method copy-GPBa7dw$default(p0: Wrapper, p1: double, p2: double, p3: double, p4: double, p5: int, p6: int, p7: int, p8: java.lang.Object): Wrapper
|
||||
public final @org.jetbrains.annotations.NotNull method copy-GPBa7dw(p0: double, p1: double, p2: double, p3: double, p4: int, p5: int): Wrapper
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public synthetic static method f3-lIoT8es$default(p0: Wrapper, p1: int, p2: int, p3: double, p4: double, p5: int, p6: java.lang.Object): java.util.List
|
||||
public final @org.jetbrains.annotations.NotNull method f3-lIoT8es(p0: int, p1: int, p2: double, p3: double): java.util.List
|
||||
public final method getN(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getSegment(): DSegment
|
||||
public synthetic final method getSegment-n(): int
|
||||
public synthetic final method getSegment-p1(): DPoint
|
||||
public synthetic final method getSegment-p1-x(): double
|
||||
public synthetic final method getSegment-p1-y(): double
|
||||
public synthetic final method getSegment-p2(): DPoint
|
||||
public synthetic final method getSegment-p2-x(): double
|
||||
public synthetic final method getSegment-p2-y(): double
|
||||
public method hashCode(): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
}
|
||||
+6
@@ -50441,6 +50441,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/valueClasses/conditionalExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultParameters.kt")
|
||||
public void testDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/defaultParameters.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equality.kt")
|
||||
public void testEquality() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user