1616
1717package com.bnorm.power
1818
19- import org.jetbrains.kotlin.backend.common.BackendContext
2019import org.jetbrains.kotlin.backend.common.FileLoweringPass
20+ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
21+ import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
2122import org.jetbrains.kotlin.backend.common.ir.asSimpleLambda
2223import org.jetbrains.kotlin.backend.common.ir.inline
24+ import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
2325import org.jetbrains.kotlin.backend.common.lower.at
24- import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
26+ import org.jetbrains.kotlin.backend.common.serialization.findPackage
2527import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
28+ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
2629import org.jetbrains.kotlin.descriptors.Visibilities
2730import org.jetbrains.kotlin.incremental.components.NoLookupLocation
2831import org.jetbrains.kotlin.ir.IrElement
@@ -36,7 +39,6 @@ import org.jetbrains.kotlin.ir.builders.irReturn
3639import org.jetbrains.kotlin.ir.builders.irString
3740import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
3841import org.jetbrains.kotlin.ir.declarations.IrFile
39- import org.jetbrains.kotlin.ir.declarations.IrFunction
4042import org.jetbrains.kotlin.ir.declarations.path
4143import org.jetbrains.kotlin.ir.expressions.IrCall
4244import org.jetbrains.kotlin.ir.expressions.IrConst
@@ -46,16 +48,14 @@ import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
4648import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
4749import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
4850import org.jetbrains.kotlin.ir.types.getClass
49- import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
5051import org.jetbrains.kotlin.ir.util.functions
51- import org.jetbrains.kotlin.ir.util.getPackageFragment
5252import org.jetbrains.kotlin.ir.util.referenceFunction
53- import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
5453import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
5554import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
5655import org.jetbrains.kotlin.ir.visitors.acceptVoid
5756import org.jetbrains.kotlin.name.FqName
5857import org.jetbrains.kotlin.name.Name
58+ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
5959import org.jetbrains.kotlin.types.KotlinType
6060import org.jetbrains.kotlin.types.typeUtil.isBoolean
6161import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
@@ -76,9 +76,9 @@ fun FileLoweringPass.runOnFileInOrder(irFile: IrFile) {
7676}
7777
7878class PowerAssertCallTransformer (
79- private val context : BackendContext ,
79+ private val context : IrPluginContext ,
8080 private val functions : Set <FqName >
81- ) : IrElementTransformerVoid (), FileLoweringPass {
81+ ) : IrElementTransformerVoidWithContext (), FileLoweringPass {
8282 private lateinit var file: IrFile
8383 private lateinit var fileSource: String
8484
@@ -90,8 +90,8 @@ class PowerAssertCallTransformer(
9090 }
9191
9292 override fun visitCall (expression : IrCall ): IrExpression {
93- val function = expression.symbol.owner
94- if (functions.none { function.fqNameWhenAvailable == it })
93+ val function = expression.symbol.descriptor
94+ if (functions.none { function.fqNameSafe == it })
9595 return super .visitCall(expression)
9696
9797 val delegate = findDelegate(function) ? : run {
@@ -103,24 +103,26 @@ class PowerAssertCallTransformer(
103103 val assertionArgument = expression.getValueArgument(0 )!!
104104 val messageArgument = if (function.valueParameters.size == 2 ) expression.getValueArgument(1 ) else null
105105
106- context.createIrBuilder(expression.symbol).run {
106+ val symbol = currentScope!! .scope.scopeOwnerSymbol
107+ DeclarationIrBuilder (context, symbol).run {
107108 at(expression)
108109
109- val lambda = messageArgument?.asSimpleLambda()
110- val title = when {
111- messageArgument is IrConst <* > -> messageArgument
112- messageArgument is IrStringConcatenation -> messageArgument
113- lambda != null -> lambda.inline()
114- messageArgument != null -> {
115- val invoke = messageArgument.type.getClass()!! .functions.single { it.name == OperatorNameConventions .INVOKE }
116- irCallOp(invoke.symbol, invoke.returnType, messageArgument)
117- }
118- // TODO what should the default message be?
119- else -> irString(" Assertion failed" )
120- }
121-
122110 val generator = object : PowerAssertGenerator () {
123111 override fun IrBuilderWithScope.buildAssertThrow (subStack : List <IrStackVariable >): IrExpression {
112+
113+ val lambda = messageArgument?.asSimpleLambda()
114+ val title = when {
115+ messageArgument is IrConst <* > -> messageArgument
116+ messageArgument is IrStringConcatenation -> messageArgument
117+ lambda != null -> lambda.inline()
118+ messageArgument != null -> {
119+ val invoke = messageArgument.type.getClass()!! .functions.single { it.name == OperatorNameConventions .INVOKE }
120+ irCallOp(invoke.symbol, invoke.returnType, messageArgument)
121+ }
122+ // TODO what should the default message be?
123+ else -> irString(" Assertion failed" )
124+ }
125+
124126 return delegate.buildCall(this , buildMessage(file, fileSource, title, expression, subStack))
125127 }
126128 }
@@ -140,7 +142,9 @@ class PowerAssertCallTransformer(
140142 fun buildCall (builder : IrBuilderWithScope , message : IrExpression ): IrExpression
141143 }
142144
143- private fun findDelegate (function : IrFunction ): FunctionDelegate ? {
145+ private fun findDelegate (function : FunctionDescriptor ): FunctionDelegate ? {
146+ fun KotlinType.toIrType () = context.typeTranslator.translateType(this )
147+
144148 return context.findOverloads(function)
145149 .mapNotNull { overload ->
146150 // TODO allow other signatures than (Boolean, String) and (Boolean, () -> String))
@@ -152,7 +156,7 @@ class PowerAssertCallTransformer(
152156 isStringSupertype(parameters[1 ].type) -> {
153157 object : FunctionDelegate {
154158 override fun buildCall (builder : IrBuilderWithScope , message : IrExpression ): IrExpression = with (builder) {
155- irCall(overload).apply {
159+ irCall(overload, type = overload.descriptor.returnType !! .toIrType() ).apply {
156160 putValueArgument(0 , irFalse())
157161 putValueArgument(1 , message)
158162 }
@@ -168,13 +172,13 @@ class PowerAssertCallTransformer(
168172 visibility = Visibilities .LOCAL
169173 origin = IrDeclarationOrigin .LOCAL_FUNCTION_FOR_LAMBDA
170174 }.apply {
171- val bodyBuilder = this @PowerAssertCallTransformer.context.createIrBuilder( symbol)
175+ val bodyBuilder = DeclarationIrBuilder ( this @PowerAssertCallTransformer.context, symbol)
172176 body = bodyBuilder.irBlockBody {
173177 + irReturn(message)
174178 }
175179 }
176180 val expression = IrFunctionExpressionImpl (- 1 , - 1 , context.irBuiltIns.stringType, lambda, IrStatementOrigin .LAMBDA )
177- irCall(overload).apply {
181+ irCall(overload, type = overload.descriptor.returnType !! .toIrType() ).apply {
178182 putValueArgument(0 , irFalse())
179183 putValueArgument(1 , expression)
180184 }
@@ -195,7 +199,7 @@ class PowerAssertCallTransformer(
195199}
196200
197201// TODO is this the best way to find overload functions?
198- private fun BackendContext .findOverloads (function : IrFunction ): List <IrFunctionSymbol > =
199- function.getPackageFragment() !! .symbol.descriptor .getMemberScope()
202+ private fun IrPluginContext .findOverloads (function : FunctionDescriptor ): List <IrFunctionSymbol > =
203+ function.findPackage() .getMemberScope()
200204 .getContributedFunctions(function.name, NoLookupLocation .FROM_BACKEND )
201- .map { ir.symbols.externalSymbolTable .referenceFunction(it) }
205+ .map { symbolTable .referenceFunction(it) }
0 commit comments