Coverage Summary for Class: KClassCreatorUtil (com.kotlinorm.compiler.plugin.utils)
Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
KClassCreatorUtil |
100%
(1/1)
|
100%
(8/8)
|
50%
(3/6)
|
100%
(60/60)
|
98.8%
(328/332)
|
/**
* 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.utils
import com.kotlinorm.compiler.helpers.applyIrCall
import com.kotlinorm.compiler.helpers.createExprNew
import com.kotlinorm.compiler.helpers.createKClassExpr
import com.kotlinorm.compiler.helpers.kFunctionN
import com.kotlinorm.compiler.helpers.nType
import com.kotlinorm.compiler.plugin.utils.context.KotlinBuilderContext
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.IrValueParameterBuilder
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.builders.irBranch
import org.jetbrains.kotlin.ir.builders.irElseBranch
import org.jetbrains.kotlin.ir.builders.irEquals
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irNull
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.builders.irWhen
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.allParameters
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.statements
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
object KClassCreatorUtil {
val kPojoClasses = mutableSetOf<IrClass>()
val initFunctions = mutableSetOf<Pair<KotlinBuilderContext, IrFunction>>()
fun resetKClassCreator() {
kPojoClasses.clear()
initFunctions.clear()
}
private val IrPluginContext.kClassCreatorSymbol
get() = referenceProperties(
CallableId(
packageName = FqName("com.kotlinorm.utils"),
callableName = Name.identifier("kClassCreator")
)
).first()
@OptIn(UnsafeDuringIrConstructionAPI::class)
private val IrPluginContext.kClassCreatorSetterSymbol
get() = kClassCreatorSymbol.owner.setter!!.symbol
private fun IrPluginContext.lambdaArgument(
lambda: IrSimpleFunction,
type: IrType = kFunctionN(lambda.allParameters.size).typeWith(lambda.allParameters.map { it.type } + lambda.returnType),
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
): IrFunctionExpression = IrFunctionExpressionImpl(
startOffset,
endOffset,
type,
lambda,
IrStatementOrigin.LAMBDA
)
fun KotlinBuilderContext.buildKClassMapper(declaration: IrFunction) {
with(pluginContext){
with(builder){
declaration.body = irBlockBody {
val lambda = irFactory.buildFun {
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
name = SpecialNames.ANONYMOUS
visibility = DescriptorVisibilities.LOCAL
returnType = KPojoSymbol.nType
modality = Modality.FINAL
}.apply {
parent = declaration
valueParameters += irFactory.buildValueParameter(IrValueParameterBuilder().apply {
name = Name.identifier("kClass")
type = createKClassExpr(KPojoSymbol).type // KClass<KPojo>
}, this)
body = irBuiltIns.createIrBuilder(symbol).run {
irBlockBody {
+irReturn(
irWhen(
KPojoSymbol.nType,
kPojoClasses.distinctBy { it.fqNameWhenAvailable }.mapNotNull {
createExprNew(it.symbol)?.let { new ->
irBranch(
irEquals(
irGet(valueParameters.first()),
createKClassExpr(it.symbol)
),
new
)
}
} + irElseBranch(
irNull()
)
)
)
}
}
}
+applyIrCall(
kClassCreatorSetterSymbol,
lambdaArgument(lambda),
operator = IrStatementOrigin.EQ
)
declaration.body?.statements?.forEach { +it }
}
}
}
}
}