16
16
17
17
package com.bnorm.power
18
18
19
- import org.jetbrains.kotlin.backend.common.BackendContext
20
19
import org.jetbrains.kotlin.backend.common.FileLoweringPass
20
+ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
21
+ import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
21
22
import org.jetbrains.kotlin.backend.common.ir.asSimpleLambda
22
23
import org.jetbrains.kotlin.backend.common.ir.inline
24
+ import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
23
25
import 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
25
27
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
28
+ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
26
29
import org.jetbrains.kotlin.descriptors.Visibilities
27
30
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
28
31
import org.jetbrains.kotlin.ir.IrElement
@@ -36,7 +39,6 @@ import org.jetbrains.kotlin.ir.builders.irReturn
36
39
import org.jetbrains.kotlin.ir.builders.irString
37
40
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
38
41
import org.jetbrains.kotlin.ir.declarations.IrFile
39
- import org.jetbrains.kotlin.ir.declarations.IrFunction
40
42
import org.jetbrains.kotlin.ir.declarations.path
41
43
import org.jetbrains.kotlin.ir.expressions.IrCall
42
44
import org.jetbrains.kotlin.ir.expressions.IrConst
@@ -46,16 +48,14 @@ import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
46
48
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
47
49
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
48
50
import org.jetbrains.kotlin.ir.types.getClass
49
- import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
50
51
import org.jetbrains.kotlin.ir.util.functions
51
- import org.jetbrains.kotlin.ir.util.getPackageFragment
52
52
import org.jetbrains.kotlin.ir.util.referenceFunction
53
- import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
54
53
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
55
54
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
56
55
import org.jetbrains.kotlin.ir.visitors.acceptVoid
57
56
import org.jetbrains.kotlin.name.FqName
58
57
import org.jetbrains.kotlin.name.Name
58
+ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
59
59
import org.jetbrains.kotlin.types.KotlinType
60
60
import org.jetbrains.kotlin.types.typeUtil.isBoolean
61
61
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
@@ -76,9 +76,9 @@ fun FileLoweringPass.runOnFileInOrder(irFile: IrFile) {
76
76
}
77
77
78
78
class PowerAssertCallTransformer (
79
- private val context : BackendContext ,
79
+ private val context : IrPluginContext ,
80
80
private val functions : Set <FqName >
81
- ) : IrElementTransformerVoid (), FileLoweringPass {
81
+ ) : IrElementTransformerVoidWithContext (), FileLoweringPass {
82
82
private lateinit var file: IrFile
83
83
private lateinit var fileSource: String
84
84
@@ -90,8 +90,8 @@ class PowerAssertCallTransformer(
90
90
}
91
91
92
92
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 })
95
95
return super .visitCall(expression)
96
96
97
97
val delegate = findDelegate(function) ? : run {
@@ -103,24 +103,26 @@ class PowerAssertCallTransformer(
103
103
val assertionArgument = expression.getValueArgument(0 )!!
104
104
val messageArgument = if (function.valueParameters.size == 2 ) expression.getValueArgument(1 ) else null
105
105
106
- context.createIrBuilder(expression.symbol).run {
106
+ val symbol = currentScope!! .scope.scopeOwnerSymbol
107
+ DeclarationIrBuilder (context, symbol).run {
107
108
at(expression)
108
109
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
-
122
110
val generator = object : PowerAssertGenerator () {
123
111
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
+
124
126
return delegate.buildCall(this , buildMessage(file, fileSource, title, expression, subStack))
125
127
}
126
128
}
@@ -140,7 +142,9 @@ class PowerAssertCallTransformer(
140
142
fun buildCall (builder : IrBuilderWithScope , message : IrExpression ): IrExpression
141
143
}
142
144
143
- private fun findDelegate (function : IrFunction ): FunctionDelegate ? {
145
+ private fun findDelegate (function : FunctionDescriptor ): FunctionDelegate ? {
146
+ fun KotlinType.toIrType () = context.typeTranslator.translateType(this )
147
+
144
148
return context.findOverloads(function)
145
149
.mapNotNull { overload ->
146
150
// TODO allow other signatures than (Boolean, String) and (Boolean, () -> String))
@@ -152,7 +156,7 @@ class PowerAssertCallTransformer(
152
156
isStringSupertype(parameters[1 ].type) -> {
153
157
object : FunctionDelegate {
154
158
override fun buildCall (builder : IrBuilderWithScope , message : IrExpression ): IrExpression = with (builder) {
155
- irCall(overload).apply {
159
+ irCall(overload, type = overload.descriptor.returnType !! .toIrType() ).apply {
156
160
putValueArgument(0 , irFalse())
157
161
putValueArgument(1 , message)
158
162
}
@@ -168,13 +172,13 @@ class PowerAssertCallTransformer(
168
172
visibility = Visibilities .LOCAL
169
173
origin = IrDeclarationOrigin .LOCAL_FUNCTION_FOR_LAMBDA
170
174
}.apply {
171
- val bodyBuilder = this @PowerAssertCallTransformer.context.createIrBuilder( symbol)
175
+ val bodyBuilder = DeclarationIrBuilder ( this @PowerAssertCallTransformer.context, symbol)
172
176
body = bodyBuilder.irBlockBody {
173
177
+ irReturn(message)
174
178
}
175
179
}
176
180
val expression = IrFunctionExpressionImpl (- 1 , - 1 , context.irBuiltIns.stringType, lambda, IrStatementOrigin .LAMBDA )
177
- irCall(overload).apply {
181
+ irCall(overload, type = overload.descriptor.returnType !! .toIrType() ).apply {
178
182
putValueArgument(0 , irFalse())
179
183
putValueArgument(1 , expression)
180
184
}
@@ -195,7 +199,7 @@ class PowerAssertCallTransformer(
195
199
}
196
200
197
201
// 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()
200
204
.getContributedFunctions(function.name, NoLookupLocation .FROM_BACKEND )
201
- .map { ir.symbols.externalSymbolTable .referenceFunction(it) }
205
+ .map { symbolTable .referenceFunction(it) }
0 commit comments