<commit_before>package org.jetbrains.kotlin.backend.konan.lower

import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanPlatform
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.ir.ir2string
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.singletonList

class DefaultArgumentStubGenerator internal constructor(val context: Context): DeclarationContainerLoweringPass {
    override fun lower(irDeclarationContainer: IrDeclarationContainer) {
        irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
            if (memberDeclaration is IrFunction)
                lower(memberDeclaration)
            else
                null
        }

    }

    object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
            IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")

    private fun lower(irFunction: IrFunction): List<IrFunction> {
        val functionDescriptor = irFunction.descriptor

        if (hasNotDefaultParameters(functionDescriptor))
            return irFunction.singletonList()

        val bodies = functionDescriptor.valueParameters
                .mapNotNull{irFunction.getDefault(it)}


        log("detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions")
        functionDescriptor.overriddenDescriptors.forEach { context.log("DEFAULT-REPLACER: $it") }
        if (bodies.isNotEmpty()) {
            val descriptor = functionDescriptor.generateDefaultsDescription(context)
            log("$functionDescriptor -> $descriptor")
            val builder = context.createIrBuilder(descriptor)
            val body = builder.irBlockBody(irFunction) {
                val params = mutableListOf<VariableDescriptor>()
                val variables = mutableMapOf<ValueDescriptor, ValueDescriptor>()
                if (descriptor.extensionReceiverParameter != null) {
                    variables[functionDescriptor.extensionReceiverParameter!!] = descriptor.extensionReceiverParameter!!
                }

                for (valueParameter in functionDescriptor.valueParameters) {
                    val parameterDescriptor = descriptor.valueParameters[valueParameter.index]
                    val temporaryVariableDescriptor = scope.createTemporaryVariableDescriptor(parameterDescriptor)
                    params.add(temporaryVariableDescriptor)
                    variables.put(valueParameter, temporaryVariableDescriptor)
                    if (valueParameter.hasDefaultValue()) {

                        val condition = irNotEquals(irCall(Helper.kIntAnd).apply {
                            dispatchReceiver = irGet(maskParameterDescriptor(descriptor, valueParameter.index / 32))
                            putValueArgument(0, irInt(1 shl (valueParameter.index % 32)))
                        }, irInt(0))
                        val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)

                        /* Use previously calculated values in next expression. */
                        expressionBody.transformChildrenVoid(object:IrElementTransformerVoid() {
                            override fun visitGetValue(expression: IrGetValue): IrExpression {
                                log("GetValue: ${expression.descriptor}")
                                val valueDescriptor = variables[expression.descriptor]
                                return when (valueDescriptor) {
                                    is VariableDescriptor          -> irGet(valueDescriptor)
                                    is ReceiverParameterDescriptor -> irGet(valueDescriptor)
                                    null                           -> expression
                                    else                           -> TODO("$valueDescriptor")
                                }

                            }
                        })
                        val variableInitialization = irIfThenElse(
                                type      = temporaryVariableDescriptor.type,
                                condition = condition,
                                thenPart  = expressionBody.expression,
                                elsePart  = irGet(parameterDescriptor))
                        + scope.createTemporaryVariable(
                                descriptor  = temporaryVariableDescriptor,
                                initializer = variableInitialization)
                        /* Mapping calculated values with its origin variables. */
                    } else {
                        + scope.createTemporaryVariable(
                                descriptor   = temporaryVariableDescriptor,
                                initializer = irGet(parameterDescriptor))
                    }
                }
                if (functionDescriptor is ClassConstructorDescriptor) {
                    + IrDelegatingConstructorCallImpl(
                            startOffset = irFunction.startOffset,
                            endOffset   = irFunction.endOffset,
                            descriptor  = functionDescriptor
                    ).apply {
                        params.forEachIndexed { i, variable ->
                            putValueArgument(i, irGet(variable))
                        }
                        if (functionDescriptor.dispatchReceiverParameter != null) {
                            dispatchReceiver = irThis()
                        }
                    }
                } else {
                    +irReturn(irCall(functionDescriptor).apply {
                        if (functionDescriptor.dispatchReceiverParameter != null) {
                            dispatchReceiver = irThis()
                        }
                        if (functionDescriptor.extensionReceiverParameter != null) {
                            extensionReceiver = irGet(variables[functionDescriptor.extensionReceiverParameter!!] as ReceiverParameterDescriptor)
                        }
                        params.forEachIndexed { i, variable ->
                            putValueArgument(i, irGet(variable))
                        }
                    })
                }
            }<commit_msg>backend: Don't save default args in original function<commit_after>package org.jetbrains.kotlin.backend.konan.lower

import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanPlatform
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.ir.ir2string
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.singletonList

class DefaultArgumentStubGenerator internal constructor(val context: Context): DeclarationContainerLoweringPass {
    override fun lower(irDeclarationContainer: IrDeclarationContainer) {
        irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
            if (memberDeclaration is IrFunction)
                lower(memberDeclaration)
            else
                null
        }

    }

    object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
            IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")

    private fun lower(irFunction: IrFunction): List<IrFunction> {
        val functionDescriptor = irFunction.descriptor

        if (hasNotDefaultParameters(functionDescriptor))
            return irFunction.singletonList()

        val bodies = functionDescriptor.valueParameters
                .mapNotNull{irFunction.getDefault(it)}


        log("detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions")
        functionDescriptor.overriddenDescriptors.forEach { context.log("DEFAULT-REPLACER: $it") }
        if (bodies.isNotEmpty()) {
            val descriptor = functionDescriptor.generateDefaultsDescription(context)
            log("$functionDescriptor -> $descriptor")
            val builder = context.createIrBuilder(descriptor)
            val body = builder.irBlockBody(irFunction) {
                val params = mutableListOf<VariableDescriptor>()
                val variables = mutableMapOf<ValueDescriptor, ValueDescriptor>()
                if (descriptor.extensionReceiverParameter != null) {
                    variables[functionDescriptor.extensionReceiverParameter!!] = descriptor.extensionReceiverParameter!!
                }

                for (valueParameter in functionDescriptor.valueParameters) {
                    val parameterDescriptor = descriptor.valueParameters[valueParameter.index]
                    val temporaryVariableDescriptor = scope.createTemporaryVariableDescriptor(parameterDescriptor)
                    params.add(temporaryVariableDescriptor)
                    variables.put(valueParameter, temporaryVariableDescriptor)
                    if (valueParameter.hasDefaultValue()) {

                        val condition = irNotEquals(irCall(Helper.kIntAnd).apply {
                            dispatchReceiver = irGet(maskParameterDescriptor(descriptor, valueParameter.index / 32))
                            putValueArgument(0, irInt(1 shl (valueParameter.index % 32)))
                        }, irInt(0))
                        val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)

                        /* Use previously calculated values in next expression. */
                        expressionBody.transformChildrenVoid(object:IrElementTransformerVoid() {
                            override fun visitGetValue(expression: IrGetValue): IrExpression {
                                log("GetValue: ${expression.descriptor}")
                                val valueDescriptor = variables[expression.descriptor]
                                return when (valueDescriptor) {
                                    is VariableDescriptor          -> irGet(valueDescriptor)
                                    is ReceiverParameterDescriptor -> irGet(valueDescriptor)
                                    null                           -> expression
                                    else                           -> TODO("$valueDescriptor")
                                }

                            }
                        })
                        val variableInitialization = irIfThenElse(
                                type      = temporaryVariableDescriptor.type,
                                condition = condition,
                                thenPart  = expressionBody.expression,
                                elsePart  = irGet(parameterDescriptor))
                        + scope.createTemporaryVariable(
                                descriptor  = temporaryVariableDescriptor,
                                initializer = variableInitialization)
                        /* Mapping calculated values with its origin variables. */
                    } else {
                        + scope.createTemporaryVariable(
                                descriptor   = temporaryVariableDescriptor,
                                initializer = irGet(parameterDescriptor))
                    }
                }
                if (functionDescriptor is ClassConstructorDescriptor) {
                    + IrDelegatingConstructorCallImpl(
                            startOffset = irFunction.startOffset,
                            endOffset   = irFunction.endOffset,
                            descriptor  = functionDescriptor
                    ).apply {
                        params.forEachIndexed { i, variable ->
                            putValueArgument(i, irGet(variable))
                        }
                        if (functionDescriptor.dispatchReceiverParameter != null) {
                            dispatchReceiver = irThis()
                        }
                    }
                } else {
                    +irReturn(irCall(functionDescriptor).apply {
                        if (functionDescriptor.dispatchReceiverParameter != null) {
                            dispatchReceiver = irThis()
                        }
                        if (functionDescriptor.extensionReceiverParameter != null) {
                            extensionReceiver = irGet(variables[functionDescriptor.extensionReceiverParameter!!] as ReceiverParameterDescriptor)
                        }
                        params.forEachIndexed { i, variable ->
                            putValueArgument(i, irGet(variable))
                        }
                    })
                }
            }
            // Replace default argument initializers with empty composites.
            functionDescriptor.valueParameters.forEach {
                if (it.declaresDefaultValue()) {
                    irFunction.putDefault(it, IrExpressionBodyImpl(irFunction.startOffset, irFunction.endOffset,
                            IrCompositeImpl(irFunction.startOffset, irFunction.startOffset, it.type)))
                }
            }
{'fraction_non_alphanumeric': 0.06890163738496474, 'fraction_numerical': 0.0009561372056890164, 'mean_word_length': 2.0147721131327687, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6005864', 'n_tokens_mistral': 3923, 'n_tokens_neox': 3641, 'n_words': 585}