@@ -13,18 +13,13 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
1313import org.jetbrains.kotlin.ir.IrStatement
1414import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
1515import org.jetbrains.kotlin.ir.builders.*
16- import org.jetbrains.kotlin.ir.declarations.IrDeclaration
17- import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
18- import org.jetbrains.kotlin.ir.declarations.IrFunction
19- import org.jetbrains.kotlin.ir.declarations.IrProperty
16+ import org.jetbrains.kotlin.ir.declarations.*
2017import org.jetbrains.kotlin.ir.expressions.IrBody
18+ import org.jetbrains.kotlin.ir.expressions.IrCall
2119import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
2220import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
2321import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
24- import org.jetbrains.kotlin.ir.types.defaultType
25- import org.jetbrains.kotlin.ir.types.isNullable
26- import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
27- import org.jetbrains.kotlin.ir.types.typeWith
22+ import org.jetbrains.kotlin.ir.types.*
2823import org.jetbrains.kotlin.ir.util.isAnnotationWithEqualFqName
2924import org.jetbrains.kotlin.ir.util.primaryConstructor
3025import org.jetbrains.kotlin.name.ClassId
@@ -214,45 +209,107 @@ private fun generateTransformBodyForFunction(
214209 // println(transformTargetFunctionCall.owner.valueParameters)
215210 val owner = transformTargetFunctionCall.owner
216211
212+ // CoroutineScope
217213 if (owner.valueParameters.size > 1 ) {
218- val secondType = owner.valueParameters[1 ].type
219- val coroutineScopeTypeName = " kotlinx.coroutines.CoroutineScope" .fqn
220- val coroutineScopeTypeClassId = ClassId .topLevel(" kotlinx.coroutines.CoroutineScope" .fqn)
221- val coroutineScopeTypeNameUnsafe = coroutineScopeTypeName.toUnsafe()
222- if (secondType.isClassType(coroutineScopeTypeNameUnsafe)) {
223- function.dispatchReceiverParameter?.also { dispatchReceiverParameter ->
224- context.referenceClass(coroutineScopeTypeClassId)?.also { coroutineScopeRef ->
225- // irGet(dispatchReceiverParameter)
226- // irAs(irGet(dispatchReceiverParameter), coroutineScopeRef).safeAs<>()
227- if (dispatchReceiverParameter.type.isSubtypeOfClass(coroutineScopeRef)) {
228- // put 'this' to second arg
229- putValueArgument(1 , irGet(dispatchReceiverParameter))
230- } else {
231- // TODO scope safe cast
232- val scopeType = coroutineScopeRef.defaultType
233-
234- if (getValueArgument(1 )?.type?.isNullable() == true ) {
235- val irSafeAs = IrTypeOperatorCallImpl (
236- startOffset,
237- endOffset,
238- scopeType,
239- IrTypeOperator .SAFE_CAST ,
240- scopeType,
241- irGet(dispatchReceiverParameter)
242- )
243-
244- putValueArgument(1 , irSafeAs)
245- }
246-
247- // irAs(irGet(dispatchReceiverParameter), coroutineScopeRef.defaultType)
248-
249- }
250- }
214+ owner.valueParameters.forEachIndexed { index, valueParameter ->
215+ if (index == 0 ) {
216+ return @forEachIndexed
251217 }
218+
219+ val type = valueParameter.type
220+ tryResolveCoroutineScopeValueParameter(type, context, function, owner, this @irBlockBody, index)
252221 }
253222
223+ // val secondType = owner.valueParameters[1].type
224+ // val coroutineScopeTypeName = "kotlinx.coroutines.CoroutineScope".fqn
225+ // val coroutineScopeTypeClassId = ClassId.topLevel("kotlinx.coroutines.CoroutineScope".fqn)
226+ // val coroutineScopeTypeNameUnsafe = coroutineScopeTypeName.toUnsafe()
227+ // if (secondType.isClassType(coroutineScopeTypeNameUnsafe)) {
228+ // function.dispatchReceiverParameter?.also { dispatchReceiverParameter ->
229+ // context.referenceClass(coroutineScopeTypeClassId)?.also { coroutineScopeRef ->
230+ // // irGet(dispatchReceiverParameter)
231+ // // irAs(irGet(dispatchReceiverParameter), coroutineScopeRef).safeAs<>()
232+ // if (dispatchReceiverParameter.type.isSubtypeOfClass(coroutineScopeRef)) {
233+ // // put 'this' to second arg
234+ // putValueArgument(1, irGet(dispatchReceiverParameter))
235+ // } else {
236+ // // scope safe cast
237+ // val scopeType = coroutineScopeRef.defaultType
238+ //
239+ // val scopeParameter = owner.valueParameters.getOrNull(1)
240+ //
241+ // if (scopeParameter?.type?.isNullable() == true) {
242+ // val irSafeAs = IrTypeOperatorCallImpl(
243+ // startOffset,
244+ // endOffset,
245+ // scopeType,
246+ // IrTypeOperator.SAFE_CAST,
247+ // scopeType,
248+ // irGet(dispatchReceiverParameter)
249+ // )
250+ //
251+ // putValueArgument(1, irSafeAs)
252+ // }
253+ // // irAs(irGet(dispatchReceiverParameter), coroutineScopeRef.defaultType)
254+ // }
255+ // }
256+ // }
257+ // }
258+
254259 }
255260
256261 })
257262 }
258263}
264+
265+ private val coroutineScopeTypeName = " kotlinx.coroutines.CoroutineScope" .fqn
266+ private val coroutineScopeTypeClassId = ClassId .topLevel(" kotlinx.coroutines.CoroutineScope" .fqn)
267+ private val coroutineScopeTypeNameUnsafe = coroutineScopeTypeName.toUnsafe()
268+
269+ /* *
270+ * 解析类型为 CoroutineScope 的参数。
271+ * 如果当前参数类型为 CoroutineScope:
272+ * - 如果当前 dispatcher 即为 CoroutineScope 类型,将其填充
273+ * - 如果当前 dispatcher 不是 CoroutineScope 类型,但是此参数可以为 null,则使用 safe-cast 将 dispatcher 转化为 CoroutineScope ( `dispatcher as? CoroutineScope` )
274+ * - 其他情况忽略此参数(适用于此参数有默认值的情况)
275+ */
276+ private fun IrCall.tryResolveCoroutineScopeValueParameter (
277+ type : IrType ,
278+ context : IrPluginContext ,
279+ function : IrFunction ,
280+ owner : IrSimpleFunction ,
281+ builderWithScope : IrBuilderWithScope ,
282+ index : Int
283+ ) {
284+ if (type.isClassType(coroutineScopeTypeNameUnsafe)) {
285+ function.dispatchReceiverParameter?.also { dispatchReceiverParameter ->
286+ context.referenceClass(coroutineScopeTypeClassId)?.also { coroutineScopeRef ->
287+ // irGet(dispatchReceiverParameter)
288+ // irAs(irGet(dispatchReceiverParameter), coroutineScopeRef).safeAs<>()
289+ if (dispatchReceiverParameter.type.isSubtypeOfClass(coroutineScopeRef)) {
290+ // put 'this' to second arg
291+ putValueArgument(index, builderWithScope.irGet(dispatchReceiverParameter))
292+ } else {
293+ // scope safe cast
294+ val scopeType = coroutineScopeRef.defaultType
295+
296+ val scopeParameter = owner.valueParameters.getOrNull(1 )
297+
298+ if (scopeParameter?.type?.isNullable() == true ) {
299+ val irSafeAs = IrTypeOperatorCallImpl (
300+ startOffset,
301+ endOffset,
302+ scopeType,
303+ IrTypeOperator .SAFE_CAST ,
304+ scopeType,
305+ builderWithScope.irGet(dispatchReceiverParameter)
306+ )
307+
308+ putValueArgument(index, irSafeAs)
309+ }
310+ // irAs(irGet(dispatchReceiverParameter), coroutineScopeRef.defaultType)
311+ }
312+ }
313+ }
314+ }
315+ }
0 commit comments