@@ -16,7 +16,9 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
16
16
import org.jetbrains.kotlin.ir.expressions.IrGetValue
17
17
import org.jetbrains.kotlin.ir.types.*
18
18
import org.jetbrains.kotlin.ir.util.functions
19
+ import org.jetbrains.kotlin.ir.util.hasShape
19
20
import org.jetbrains.kotlin.ir.util.isNullable
21
+ import org.jetbrains.kotlin.ir.util.nonDispatchParameters
20
22
import org.jetbrains.kotlin.ir.util.shallowCopy
21
23
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
22
24
import org.jetbrains.kotlin.name.Name
@@ -40,18 +42,27 @@ internal class StringConcatenationTypeNarrowing(val context: Context) : FileLowe
40
42
private val nameAppend = Name .identifier(" append" )
41
43
42
44
private val appendNullableStringFunction = stringBuilder.functions.single { // StringBuilder.append(String?)
43
- it.name == nameAppend &&
44
- it.valueParameters.singleOrNull()?.type?.isNullableString() == true
45
+ it.name == nameAppend && it.hasShape(
46
+ dispatchReceiver = true ,
47
+ regularParameters = 1 ,
48
+ parameterTypes = listOf (stringBuilder.typeWith(), context.irBuiltIns.stringType.makeNullable())
49
+ )
45
50
}
51
+
46
52
private val appendAnyFunction = stringBuilder.functions.single { // StringBuilder.append(Any?)
47
- it.name == nameAppend &&
48
- it.valueParameters.singleOrNull()?.type?.isNullableAny() == true
53
+ it.name == nameAppend && it.hasShape(
54
+ dispatchReceiver = true ,
55
+ regularParameters = 1 ,
56
+ parameterTypes = listOf (stringBuilder.typeWith(), context.irBuiltIns.anyNType)
57
+ )
49
58
}
50
59
51
60
private val plusImplFunction = string.functions.single { // external fun String.plusImpl(String)
52
- it.name == namePlusImpl &&
53
- it.valueParameters.size == 1 &&
54
- it.valueParameters.single().type.isString()
61
+ it.name == namePlusImpl && it.hasShape(
62
+ dispatchReceiver = true ,
63
+ regularParameters = 1 ,
64
+ parameterTypes = listOf (context.irBuiltIns.stringType, context.irBuiltIns.stringType)
65
+ )
55
66
}
56
67
57
68
override fun lower (irFile : IrFile ) {
@@ -64,13 +75,13 @@ internal class StringConcatenationTypeNarrowing(val context: Context) : FileLowe
64
75
builder.at(this )
65
76
when (symbol) {
66
77
appendAnyFunction.symbol -> // StringBuilder.append(Any?)
67
- buildConcatenationCall(appendNullableStringFunction, dispatchReceiver !! , buildArgForAppend(getValueArgument( 0 ) !! ))
78
+ buildConcatenationCall(appendNullableStringFunction, arguments[ 0 ] !! , buildArgForAppend(arguments[ 1 ] !! ))
68
79
69
80
context.irBuiltIns.memberStringPlus ->
70
- buildConcatenationCall(plusImplFunction, dispatchReceiver !! , buildNullableArgToString(getValueArgument( 0 ) !! ))
81
+ buildConcatenationCall(plusImplFunction, arguments[ 0 ] !! , buildNullableArgToString(arguments[ 1 ] !! ))
71
82
72
83
context.irBuiltIns.extensionStringPlus ->
73
- buildConcatenationCall(plusImplFunction, buildNullableArgToString(extensionReceiver !! ), buildNullableArgToString(getValueArgument( 0 ) !! ))
84
+ buildConcatenationCall(plusImplFunction, buildNullableArgToString(arguments[ 0 ] !! ), buildNullableArgToString(arguments[ 1 ] !! ))
74
85
75
86
else -> expression
76
87
}
@@ -80,8 +91,8 @@ internal class StringConcatenationTypeNarrowing(val context: Context) : FileLowe
80
91
private fun buildConcatenationCall (function : IrSimpleFunction , receiver : IrExpression , argument : IrExpression ): IrExpression =
81
92
builder.irCall(function.symbol, function.returnType, typeArgumentsCount = 0 )
82
93
.apply {
83
- putValueArgument( 0 , argument)
84
- dispatchReceiver = receiver
94
+ arguments[ 0 ] = receiver
95
+ arguments[ 1 ] = argument
85
96
}
86
97
87
98
/* * Builds snippet of type String
@@ -138,12 +149,12 @@ internal class StringConcatenationTypeNarrowing(val context: Context) : FileLowe
138
149
argument
139
150
else {
140
151
val calleeOrNull = argument.type.classOrNull?.owner?.functions?.singleOrNull {
141
- it.name == OperatorNameConventions .TO_STRING && it.valueParameters .isEmpty()
152
+ it.name == OperatorNameConventions .TO_STRING && it.nonDispatchParameters .isEmpty()
142
153
}?.symbol
143
154
val callee = calleeOrNull ? : context.symbols.memberToString // defaults to `Any.toString()`
144
155
builder
145
156
.irCall(callee, callee.owner.returnType, typeArgumentsCount = 0 )
146
- .apply { dispatchReceiver = argument }
157
+ .apply { arguments[ 0 ] = argument }
147
158
}
148
159
}
149
160
0 commit comments