/*
 * Copyright 2010-2024 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.
 */

// This file was generated automatically. See compiler/ir/ir.tree/tree-generator/ReadMe.md.
// DO NOT MODIFY IT MANUALLY.

package org.jetbrains.kotlin.ir.visitors

import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.utils.memoryOptimizedMap

/**
 * Auto-generated by [org.jetbrains.kotlin.ir.generator.print.TypeTransformerPrinter]
 */
abstract class IrTypeTransformer<out R, in D> : IrVisitor<R, D>() {
    abstract fun <Type : IrType?> transformTypeRecursively(container: IrElement, type: Type, data: D): Type

    override fun visitValueParameter(declaration: IrValueParameter, data: D): R {
        declaration.varargElementType = transformTypeRecursively(declaration, declaration.varargElementType, data)
        declaration.type = transformTypeRecursively(declaration, declaration.type, data)
        return super.visitValueParameter(declaration, data)
    }

    override fun visitClass(declaration: IrClass, data: D): R {
        declaration.valueClassRepresentation = declaration.valueClassRepresentation?.mapUnderlyingType {
            transformTypeRecursively(declaration, it, data)
        }
        declaration.superTypes = declaration.superTypes.memoryOptimizedMap {
            transformTypeRecursively(declaration, it, data)
        }
        return super.visitClass(declaration, data)
    }

    override fun visitTypeParameter(declaration: IrTypeParameter, data: D): R {
        declaration.superTypes = declaration.superTypes.memoryOptimizedMap {
            transformTypeRecursively(declaration, it, data)
        }
        return super.visitTypeParameter(declaration, data)
    }

    override fun visitFunction(declaration: IrFunction, data: D): R {
        declaration.returnType = transformTypeRecursively(declaration, declaration.returnType, data)
        return super.visitFunction(declaration, data)
    }

    override fun visitField(declaration: IrField, data: D): R {
        declaration.type = transformTypeRecursively(declaration, declaration.type, data)
        return super.visitField(declaration, data)
    }

    override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: D): R {
        declaration.type = transformTypeRecursively(declaration, declaration.type, data)
        return super.visitLocalDelegatedProperty(declaration, data)
    }

    override fun visitScript(declaration: IrScript, data: D): R {
        declaration.baseClass = transformTypeRecursively(declaration, declaration.baseClass, data)
        return super.visitScript(declaration, data)
    }

    override fun visitReplSnippet(declaration: IrReplSnippet, data: D): R {
        declaration.returnType = transformTypeRecursively(declaration, declaration.returnType, data)
        return super.visitReplSnippet(declaration, data)
    }

    override fun visitTypeAlias(declaration: IrTypeAlias, data: D): R {
        declaration.expandedType = transformTypeRecursively(declaration, declaration.expandedType, data)
        return super.visitTypeAlias(declaration, data)
    }

    override fun visitVariable(declaration: IrVariable, data: D): R {
        declaration.type = transformTypeRecursively(declaration, declaration.type, data)
        return super.visitVariable(declaration, data)
    }

    override fun visitExpression(expression: IrExpression, data: D): R {
        expression.type = transformTypeRecursively(expression, expression.type, data)
        return super.visitExpression(expression, data)
    }

    override fun visitMemberAccess(expression: IrMemberAccessExpression<*>, data: D): R {
        expression.typeArguments.replaceAll {
            transformTypeRecursively(expression, it, data)
        }
        return super.visitMemberAccess(expression, data)
    }

    override fun visitClassReference(expression: IrClassReference, data: D): R {
        expression.classType = transformTypeRecursively(expression, expression.classType, data)
        return super.visitClassReference(expression, data)
    }

    override fun visitConstantObject(expression: IrConstantObject, data: D): R {
        expression.typeArguments.replaceAll {
            transformTypeRecursively(expression, it, data)
        }
        return super.visitConstantObject(expression, data)
    }

    override fun visitTypeOperator(expression: IrTypeOperatorCall, data: D): R {
        expression.typeOperand = transformTypeRecursively(expression, expression.typeOperand, data)
        return super.visitTypeOperator(expression, data)
    }

    override fun visitVararg(expression: IrVararg, data: D): R {
        expression.varargElementType = transformTypeRecursively(expression, expression.varargElementType, data)
        return super.visitVararg(expression, data)
    }
}
