Coverage Summary for Class: KronosIrClassNewTransformer (com.kotlinorm.compiler.plugin.transformer)

Class Class, % Method, % Branch, % Line, % Instruction, %
KronosIrClassNewTransformer 100% (1/1) 100% (18/18) 100% (18/18) 100% (29/29) 100% (299/299)


 /**
  * Copyright 2022-2025 kronos-orm
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package com.kotlinorm.compiler.plugin.transformer
 
 import com.kotlinorm.compiler.plugin.utils.context.withBuilder
 import com.kotlinorm.compiler.plugin.utils.createFromMapValueFunction
 import com.kotlinorm.compiler.plugin.utils.createGetFieldsFunction
 import com.kotlinorm.compiler.plugin.utils.createKClassFunction
 import com.kotlinorm.compiler.plugin.utils.createKronosComment
 import com.kotlinorm.compiler.plugin.utils.createKronosCreateTime
 import com.kotlinorm.compiler.plugin.utils.createKronosLogicDelete
 import com.kotlinorm.compiler.plugin.utils.createKronosOptimisticLock
 import com.kotlinorm.compiler.plugin.utils.createKronosTableIndex
 import com.kotlinorm.compiler.plugin.utils.createKronosTableName
 import com.kotlinorm.compiler.plugin.utils.createKronosUpdateTime
 import com.kotlinorm.compiler.plugin.utils.createPropertyGetter
 import com.kotlinorm.compiler.plugin.utils.createPropertySetter
 import com.kotlinorm.compiler.plugin.utils.createSafeFromMapValueFunction
 import com.kotlinorm.compiler.plugin.utils.createToMapFunction
 import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
 import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
 import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
 import org.jetbrains.kotlin.ir.IrStatement
 import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
 import org.jetbrains.kotlin.ir.declarations.IrClass
 import org.jetbrains.kotlin.ir.declarations.IrFunction
 import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
 import org.jetbrains.kotlin.ir.expressions.IrBlockBody
 import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
 import org.jetbrains.kotlin.ir.util.properties
 
 /**
  * Kronos Parser Transformer
  *
  * @author OUSC, Jieyao Lu
  *
  * Roughly speaking, the transform will turn the following:
  *
  *     // file: Foo.kt
  *     class Foo : KPojo {
  *         var username: String {get set}
  *         var password: String {get set}
  *
  *         fake override fun toDataMap(): MutableMap<String, Any?>
  *         fake override fun safeFromMapData(data: Map<String, Any?>): Foo
  *         fake override fun fromMapData(data: Map<String, Any?>): Foo
  *         fake override fun kronosTableName(): String
  *         fake override fun kronosTableComment(): String
  *         fake override fun kronosTableIndex(): List<KTableIndex>
  *         fake override fun kronosColumns(): List<Field>
  *         fake override fun kronosCreateTime(): KronosCommonStrategy
  *         fake override fun kronosUpdateTime(): KronosCommonStrategy
  *         fake override fun kronosLogicDelete(): KronosCommonStrategy
  *         fake override fun kronosOptimisticLock(): KronosCommonStrategy
  *     }
  *
  * into the following equivalent representation:
  *
  *    // file: Foo.kt
  *     class Foo : KPojo {
  *         var username: String {get set}
  *         var password: String {get set}
  *
  *         override fun toDataMap(): MutableMap<String, Any?> {
  *             return mutableMapOf(
  *                 "username" to username,
  *                 "password" to password
  *             )
  *         }
  *
  *         override fun safeFromMapData(data: Map<String, Any?>): Foo {
  *              try this.username = getSafeValue(data, "username") catch (e: Exception) e.printStackTrace()
  *              try this.password = getSafeValue(data, "password") catch (e: Exception) e.printStackTrace()
  *              return this
  *         }
  *
  *         override fun fromMapData(data: Map<String, Any?>): Foo {
  *              this.username = data["username"]
  *              this.password = data["password"]
  *              return this
  *         }
  *
  *         override fun kronosTableName(): String {
  *               return "foo"
  *         }
  *
  *         override fun kronosTableComment(): String {
  *              return "file: Foo.kt"
  *         }
  *
  *         override fun kronosTableIndex(): List<KTableIndex> {
  *              return listOf()
  *         }
  *
  *         override fun kronosColumns(): List<Field> {
  *              return listOf(Field("username"), Field("password"))
  *         }
  *
  *         override fun kronosCreateTime(): KronosCommonStrategy {
  *              return KronosCommonStrategy("create_time")
  *         }
  *
  *         override fun kronosUpdateTime(): KronosCommonStrategy {
  *              return KronosCommonStrategy("update_time")
  *         }
  *
  *         override fun kronosLogicDelete(): KronosCommonStrategy {
  *              return KronosCommonStrategy("deleted")
  *         }
  *
  *         override fun kronosOptimisticLock(): KronosCommonStrategy {
  *              return KronosCommonStrategy("version")
  *         }
  */
 class KronosIrClassNewTransformer(
     private val pluginContext: IrPluginContext, private val irClass: IrClass
 ) : IrElementTransformerVoidWithContext() {
     @OptIn(UnsafeDuringIrConstructionAPI::class)
     override fun visitFunctionNew(declaration: IrFunction): IrStatement {
         if (declaration is IrSimpleFunction && declaration.isFakeOverride) {
             irClass.properties.forEach {
                 it.isVar = true
                 it.isConst = false
             }
             fun replaceFakeBody(functionBodyFactory: () -> IrBlockBody) {
                 declaration.isFakeOverride = false
                 declaration.dispatchReceiverParameter = irClass.thisReceiver
                 declaration.body = functionBodyFactory()
             }
             with(DeclarationIrBuilder(pluginContext, declaration.symbol) as IrBuilderWithScope) {
                 withBuilder(pluginContext) {
                     when (declaration.name.asString()) {
                         "kClass" -> replaceFakeBody { createKClassFunction(irClass) }
                         "toDataMap" -> replaceFakeBody { createToMapFunction(irClass, declaration) }
                         "get" -> replaceFakeBody { createPropertyGetter(irClass, declaration) }
                         "set" -> replaceFakeBody { createPropertySetter(irClass, declaration) }
                         "safeFromMapData" -> replaceFakeBody { createSafeFromMapValueFunction(irClass, declaration) }
                         "fromMapData" -> replaceFakeBody { createFromMapValueFunction(irClass, declaration) }
                         "kronosTableName" -> replaceFakeBody { createKronosTableName(irClass) }
                         "kronosTableComment" -> replaceFakeBody { createKronosComment(irClass) }
                         "kronosTableIndex" -> replaceFakeBody { createKronosTableIndex(irClass) }
                         "kronosColumns" -> replaceFakeBody { createGetFieldsFunction(irClass) }
                         "kronosCreateTime" -> replaceFakeBody { createKronosCreateTime(irClass) }
                         "kronosUpdateTime" -> replaceFakeBody { createKronosUpdateTime(irClass) }
                         "kronosLogicDelete" -> replaceFakeBody { createKronosLogicDelete(irClass) }
                         "kronosOptimisticLock" -> replaceFakeBody { createKronosOptimisticLock(irClass) }
                     }
                 }
             }
         }
         return super.visitFunctionNew(declaration)
     }
 }