Skip to content

Commit c788e83

Browse files
committed
sad
1 parent c5c6b91 commit c788e83

File tree

7 files changed

+90
-105
lines changed

7 files changed

+90
-105
lines changed

buildSrc/src/main/kotlin/IProject.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ object IProject : ProjectDetail() {
99
const val DESCRIPTION = "Generate platform-compatible functions for Kotlin suspend functions"
1010
const val HOMEPAGE = "https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin"
1111

12-
override val version: Version = version(0, 5, 1) - version("local-test-3")
12+
override val version: Version = version(0, 5, 1) - version("local-test-4")
1313

1414
override val homepage: String get() = HOMEPAGE
1515

compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformTransformer.kt

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import org.jetbrains.kotlin.ir.builders.*
1515
import org.jetbrains.kotlin.ir.declarations.*
1616
import org.jetbrains.kotlin.ir.expressions.IrBody
1717
import org.jetbrains.kotlin.ir.expressions.IrCall
18+
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
1819
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
20+
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
1921
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
2022
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
2123
import org.jetbrains.kotlin.ir.types.*
@@ -162,7 +164,8 @@ class SuspendTransformTransformer(
162164
val originFunction = originFunctions.first()
163165

164166
function.body = null
165-
function.body = generateTransformBodyForFunction(
167+
// function.body = generateTransformBodyForFunction(
168+
function.body = generateTransformBodyForFunctionLambda(
166169
pluginContext,
167170
function,
168171
originFunction,
@@ -222,6 +225,55 @@ private fun generateTransformBodyForFunction(
222225
}
223226
}
224227

228+
/**
229+
* new
230+
*
231+
*/
232+
private fun generateTransformBodyForFunctionLambda(
233+
context: IrPluginContext,
234+
function: IrFunction,
235+
originFunction: IrFunction,
236+
transformTargetFunctionCall: IrSimpleFunctionSymbol,
237+
): IrBody {
238+
val originValueParameters = originFunction.valueParameters
239+
function.valueParameters.forEachIndexed { index, parameter ->
240+
val originFunctionValueParameter = originValueParameters[index]
241+
parameter.defaultValue = originFunctionValueParameter.defaultValue
242+
}
243+
244+
245+
return context.createIrBuilder(function.symbol).irBlockBody {
246+
val suspendLambdaFunc = context.createSuspendLambdaFunctionWithCoroutineScope(
247+
originFunction = originFunction,
248+
function = function,
249+
this
250+
).also { +it }
251+
252+
val lambdaType = context.symbols.suspendFunctionN(0).typeWith(suspendLambdaFunc.returnType)
253+
254+
val ex = IrFunctionExpressionImpl(-1, -1, lambdaType, suspendLambdaFunc, IrStatementOrigin.LAMBDA)
255+
+ex
256+
257+
+irReturn(irCall(transformTargetFunctionCall).apply {
258+
putValueArgument(0, ex)
259+
// argument: 1, if is CoroutineScope, and this is CoroutineScope.
260+
val owner = transformTargetFunctionCall.owner
261+
262+
// CoroutineScope
263+
val ownerValueParameters = owner.valueParameters
264+
265+
if (ownerValueParameters.size > 1) {
266+
for (index in 1..ownerValueParameters.lastIndex) {
267+
val valueParameter = ownerValueParameters[index]
268+
val type = valueParameter.type
269+
tryResolveCoroutineScopeValueParameter(type, context, function, owner, this@irBlockBody, index)
270+
}
271+
}
272+
273+
})
274+
}
275+
}
276+
225277
private val coroutineScopeTypeName = "kotlinx.coroutines.CoroutineScope".fqn
226278
private val coroutineScopeTypeClassId = ClassId.topLevel("kotlinx.coroutines.CoroutineScope".fqn)
227279
private val coroutineScopeTypeNameUnsafe = coroutineScopeTypeName.toUnsafe()

compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/IrFunctionUtils.kt

Lines changed: 25 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -141,103 +141,45 @@ fun IrPluginContext.createSuspendLambdaWithCoroutineScope(
141141
}
142142
}
143143

144-
/**
145-
* Generates a suspend lambda.
146-
*
147-
* - extends `suspend () -> Unit`.
148-
* - takes dispatch and extension receivers as param, followed by normal value params, to the constructor of this object
149-
*/
150144
fun IrPluginContext.createSuspendLambdaFunctionWithCoroutineScope(
151-
parent: IrDeclarationParent,
152-
lambdaType: IrSimpleType,
153145
originFunction: IrFunction,
154-
): IrClass {
155-
156-
157-
return IrFactoryImpl.buildClass {
146+
function: IrFunction,
147+
blockBodyBuilder: IrBlockBodyBuilder
148+
): IrSimpleFunction {
149+
val func = IrFactoryImpl.buildFun {
158150
name = SpecialNames.NO_NAME_PROVIDED
159-
kind = ClassKind.CLASS
160-
161-
/*
162-
Those three lines are required, especially `visibility` and `isInner`
163-
All the local classes should have it
164-
165-
see https://youtrack.jetbrains.com/issue/KT-53993/IR-kotlin.NotImplementedError-An-operation-is-not-implemented-IrClassImpl-is-not-supported-yet-here#focus=Comments-27-8622204.0-0
166-
*/
167-
168-
// isFun = true
169-
isInner = true
170151
visibility = DescriptorVisibilities.LOCAL
171-
}.apply clazz@{
172-
this.parent = parent
173-
superTypes = listOf(lambdaType)
174-
175-
val fields = originFunction.paramsAndReceiversAsParamsList().map {
176-
addField(it.name.identifierOrMappedSpecialName.synthesizedName, it.type)
177-
}
178-
179-
createImplicitParameterDeclarationWithWrappedDescriptor()
180-
181-
addConstructor {
182-
isPrimary = true
183-
}.apply constructor@{
184-
val newParams = fields.associateWith { irField ->
185-
this@constructor.addValueParameter {
186-
name = irField.name
187-
type = irField.type
188-
}
189-
}
190-
191-
this@constructor.body = createIrBuilder(symbol).irBlockBody {
192-
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
193-
194-
for ((irField, irValueParam) in newParams) {
195-
+irSetField(irGet(this@clazz.thisReceiver!!), irField, irGet(irValueParam))
196-
}
197-
198-
199-
}
200-
}
201-
202-
val irClass = this
203-
204-
addFunction("invoke", lambdaType.arguments.last().typeOrNull!!, isSuspend = true).apply functionInvoke@{
205-
this.overriddenSymbols =
206-
// listOf(irClass.superTypes[0].getClass()!!.functionsSequence.single { it.name.identifier == "invoke" && it.isOverridable }.symbol)
207-
listOf(lambdaType.getClass()!!.functionsSequence.single { it.name.identifier == "invoke" && it.isOverridable }.symbol)
152+
isSuspend = true
153+
returnType = function.returnType
154+
}
208155

209-
// this.createDispatchReceiverParameter()
210-
this.body = createIrBuilder(symbol).run {
211-
// don't use expr body, coroutine codegen can't generate for it.
212-
irBlockBody {
213-
+irCall(originFunction).apply call@{
214-
// set arguments
156+
with(func) {
157+
parent = function
158+
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
215159

216-
val arguments = fields.mapTo(LinkedList()) { it } // preserve order
217160

218-
fun IrField.irGetField0(): IrGetFieldImpl {
219-
return irGetField(
220-
receiver = irGet(this@functionInvoke.dispatchReceiverParameter!!),
221-
field = this
222-
)
223-
}
161+
body = createIrBuilder(symbol).run {
162+
// don't use expr body, coroutine codegen can't generate for it.
163+
irBlockBody {
164+
+irCall(originFunction).apply call@{
165+
// set arguments
166+
function.dispatchReceiverParameter?.also {
167+
this@call.dispatchReceiver = irGet(it)
168+
}
224169

225-
if (originFunction.dispatchReceiverParameter != null) {
226-
this@call.dispatchReceiver = arguments.pop().irGetField0()
227-
}
228-
if (originFunction.extensionReceiverParameter != null) {
229-
this@call.extensionReceiver = arguments.pop().irGetField0()
230-
}
170+
function.extensionReceiverParameter?.also {
171+
this@call.extensionReceiver = irGet(it)
172+
}
231173

232-
// this@call.putValueArgument(0, irGet(scopeParam))
233-
for ((index, irField) in arguments.withIndex()) {
234-
this@call.putValueArgument(index, irField.irGetField0())
235-
}
174+
for ((index, parameter) in function.valueParameters.withIndex()) {
175+
this@call.putValueArgument(index, irGet(parameter))
236176
}
237177
}
238178
}
239179
}
240180
}
181+
182+
return func
241183
}
242184

243185
fun IrFunction.paramsAndReceiversAsParamsList(): List<IrValueParameter> {

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ include(":runtime:suspend-transform-runtime")
88

99
include(":plugins:suspend-transform-plugin-gradle")
1010

11-
//include(":suspend-transform-plugin-sample")
11+
include(":suspend-transform-plugin-sample")
1212
include(":suspend-transform-plugin-sample-js")
1313
// include(":plugins:ide:suspend-transform-plugin-idea")

suspend-transform-plugin-sample-js/build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ buildscript {
1111
mavenCentral()
1212
}
1313
dependencies {
14-
classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.5.1-local-test-3")
14+
classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.5.1-local-test-4")
1515
}
1616
}
1717

1818

1919
kotlin {
2020
js(IR) {
2121
nodejs()
22+
useEsModules()
2223
binaries.executable()
24+
compilations.all {
25+
kotlinOptions {
26+
useEsClasses = true
27+
}
28+
}
2329
}
2430
}
2531

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
1-
import kotlinx.coroutines.CoroutineScope
2-
import kotlinx.coroutines.delay
3-
import kotlinx.coroutines.promise
1+
import kotlinx.coroutines.*
42
import kotlin.coroutines.EmptyCoroutineContext
53
import kotlin.js.Promise
64

75
suspend fun main() {
86
// runInAsync(block = SuspendFun()).await()
97
println(ForteScarlet().stringToInt("1"))
108
println(ForteScarlet().stringToIntAsync("1"))
11-
}
12-
13-
private val scope = CoroutineScope(EmptyCoroutineContext)
14-
15-
fun <T> runInAsync(block: suspend () -> T): Promise<T> {
16-
val b1 = block::invoke
17-
return scope.promise { b1() }
18-
}
19-
20-
class SuspendFun : (suspend () -> String) {
21-
override suspend fun invoke(): String {
22-
delay(1)
23-
return "SuspendFun"
24-
}
9+
println(ForteScarlet().stringToIntAsync("1").await())
2510
}

suspend-transform-plugin-sample/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ plugins {
1616
}
1717
dependencies {
1818
//this.implementation()
19-
classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.5.0")
19+
classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.5.1-local-test-4")
2020
}
2121
}
2222

0 commit comments

Comments
 (0)