@@ -13,18 +13,13 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
13
13
import org.jetbrains.kotlin.ir.IrStatement
14
14
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
15
15
import 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.*
20
17
import org.jetbrains.kotlin.ir.expressions.IrBody
18
+ import org.jetbrains.kotlin.ir.expressions.IrCall
21
19
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
22
20
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
23
21
import 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.*
28
23
import org.jetbrains.kotlin.ir.util.isAnnotationWithEqualFqName
29
24
import org.jetbrains.kotlin.ir.util.primaryConstructor
30
25
import org.jetbrains.kotlin.name.ClassId
@@ -214,45 +209,107 @@ private fun generateTransformBodyForFunction(
214
209
// println(transformTargetFunctionCall.owner.valueParameters)
215
210
val owner = transformTargetFunctionCall.owner
216
211
212
+ // CoroutineScope
217
213
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
251
217
}
218
+
219
+ val type = valueParameter.type
220
+ tryResolveCoroutineScopeValueParameter(type, context, function, owner, this @irBlockBody, index)
252
221
}
253
222
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
+
254
259
}
255
260
256
261
})
257
262
}
258
263
}
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