Skip to content

Commit 837cc81

Browse files
committed
奇怪。为什么只要被获取的注解,它原本的范型类型就会被破坏呢?
1 parent 83095c0 commit 837cc81

File tree

8 files changed

+174
-49
lines changed

8 files changed

+174
-49
lines changed

compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package love.forte.plugin.suspendtrans.fir
22

3-
import love.forte.plugin.suspendtrans.annotation.ExperimentalReturnTypeOverrideGenericApi
43
import love.forte.plugin.suspendtrans.configuration.*
54
import love.forte.plugin.suspendtrans.fqn
65
import love.forte.plugin.suspendtrans.utils.*
@@ -356,7 +355,8 @@ class SuspendTransformFirTransformer(
356355
bridgeFunSymbol: FirNamedFunctionSymbol,
357356
newFunTarget: FirFunctionTarget,
358357
funData: SyntheticFunData,
359-
originalTypeParameterCache: MutableList<CopiedTypeParameterPair>
358+
originalTypeParameterCache: MutableList<CopiedTypeParameterPair>,
359+
returnTypeRef: FirTypeRef
360360
): FirBlock = buildBlock {
361361
this.source = originFunc.body?.source
362362

@@ -444,13 +444,13 @@ class SuspendTransformFirTransformer(
444444
}
445445
lambdaTarget.bind(lambda)
446446

447-
val returnType = resolveReturnType(funData, originFunc.returnTypeRef, originalTypeParameterCache)
447+
// val returnType = resolveReturnType(funData, originFunc.returnTypeRef, originalTypeParameterCache)
448448

449449
this.statements.add(
450450
buildReturnExpression {
451451
this.target = newFunTarget
452452
this.result = buildFunctionCall {
453-
this.coneTypeOrNull = returnType.coneType
453+
this.coneTypeOrNull = returnTypeRef.coneType
454454
this.source = originFunc.body?.source
455455
this.calleeReference = buildResolvedNamedReference {
456456
this.source = bridgeFunSymbol.source
@@ -672,7 +672,8 @@ class SuspendTransformFirTransformer(
672672
realBridgeFunSymbol,
673673
newFunTarget,
674674
funData,
675-
originalTypeParameterCache
675+
originalTypeParameterCache,
676+
returnTypeRef
676677
)
677678

678679
origin = key.origin
@@ -826,7 +827,8 @@ class SuspendTransformFirTransformer(
826827
),
827828
newFunTarget,
828829
funData,
829-
originalTypeParameterCache
830+
originalTypeParameterCache,
831+
returnTypeRef
830832
)
831833
}.also { getter ->
832834
newFunTarget.bind(getter)
@@ -974,12 +976,16 @@ class SuspendTransformFirTransformer(
974976
val anno = firAnnotation(func, markAnnotation, classSymbol)
975977
?: continue
976978

977-
@OptIn(ExperimentalReturnTypeOverrideGenericApi::class)
978-
val markAnnotationTypeArgument = if (markAnnotation.hasReturnTypeOverrideGeneric) {
979-
anno.typeArguments.firstOrNull()
980-
} else {
981-
null
982-
}
979+
val markAnnotationTypeArgument: FirTypeProjection? = null
980+
981+
// TODO 只要是一个标记注解,范型就会 'ERROR CLASS: Symbol not found for T'
982+
// 为什么?
983+
// @OptIn(ExperimentalReturnTypeOverrideGenericApi::class)
984+
// val markAnnotationTypeArgument: FirTypeProjection? = if (markAnnotation.hasReturnTypeOverrideGeneric) {
985+
// anno.typeArguments.firstOrNull()
986+
// } else {
987+
// null
988+
// }
983989

984990
// TODO 也许错误延后抛出,缓存里找不到的话即用即找,可以解决无法在当前模块下使用的问题?
985991
// see https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/issues/100
@@ -1030,14 +1036,16 @@ class SuspendTransformFirTransformer(
10301036
func: FirNamedFunctionSymbol,
10311037
markAnnotation: MarkAnnotation,
10321038
classSymbol: FirBasedSymbol<*>?
1033-
) = func.resolvedAnnotationsWithArguments.getAnnotationsByClassId(
1034-
markAnnotation.classId,
1035-
session
1036-
).firstOrNull()
1037-
?: classSymbol?.resolvedAnnotationsWithArguments?.getAnnotationsByClassId(
1039+
): FirAnnotation? {
1040+
return func.resolvedAnnotationsWithArguments.getAnnotationsByClassId(
10381041
markAnnotation.classId,
10391042
session
1040-
)?.firstOrNull()
1043+
).firstOrNull()
1044+
?: classSymbol?.resolvedAnnotationsWithArguments?.getAnnotationsByClassId(
1045+
markAnnotation.classId,
1046+
session
1047+
)?.firstOrNull()
1048+
}
10411049

10421050
private fun resolveReturnType(
10431051
funData: SyntheticFunData,
@@ -1047,9 +1055,10 @@ class SuspendTransformFirTransformer(
10471055
val transformer = funData.transformer
10481056
val returnTypeArg = funData.markAnnotationTypeArgument
10491057

1050-
val returnTypeConeType = returnTypeArg?.toConeTypeProjection()?.let {
1058+
val returnTypeConeType: ConeKotlinType = returnTypeArg?.toConeTypeProjection()?.let {
10511059
// if is star projection, use Any or Nothing? and the nullable?
1052-
it.type?.copyWithTypeParameters(originalTypeParameterCache)
1060+
it.type
1061+
?.copyConeTypeOrSelf(originalTypeParameterCache)
10531062
?: session.builtinTypes.nothingType.coneType
10541063
} ?: returnTypeRef.coneType
10551064

@@ -1093,10 +1102,12 @@ class SuspendTransformFirTransformer(
10931102
* @return function annotations `to` property annotations.
10941103
*/
10951104
private fun copyAnnotations(
1096-
original: FirSimpleFunction, syntheticFunData: SyntheticFunData,
1105+
original: FirSimpleFunction,
1106+
syntheticFunData: SyntheticFunData,
10971107
): CopyAnnotations {
10981108
val transformer = syntheticFunData.transformer
10991109

1110+
// val originalAnnotationClassIdMap = original.annotations.keysToMap { it.toAnnotationClassId(session) }
11001111
val originalAnnotationClassIdMap = original.annotations.keysToMap { it.toAnnotationClassId(session) }
11011112

11021113
val copyFunction = transformer.copyAnnotationsToSyntheticFunction
@@ -1133,6 +1144,7 @@ class SuspendTransformFirTransformer(
11331144
annotationTypeRef = buildResolvedTypeRef {
11341145
coneType = a.resolvedType
11351146
}
1147+
11361148
this.typeArguments.addAll(a.typeArguments)
11371149
this.argumentMapping = buildAnnotationArgumentMapping {
11381150
this.source = a.source
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package love.forte.plugin.suspendtrans.utils
22

3-
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
3+
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
44
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
55

6-
fun FirDeclaration.includeAnnotations(includes: List<FirAnnotation>) {
7-
replaceAnnotations(annotations + includes)
6+
fun FirSimpleFunction.includeAnnotations(includes: List<FirAnnotation>) {
7+
replaceAnnotations(symbol.resolvedAnnotationsWithArguments + includes)
88
}

compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package love.forte.plugin.suspendtrans.services
22

33
import love.forte.plugin.suspendtrans.SuspendTransformComponentRegistrar
4-
import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConfigurationApi
5-
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration
4+
import love.forte.plugin.suspendtrans.configuration.*
65
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jsPromiseTransformer
6+
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmApi4JAnnotationClassInfo
7+
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmAsyncMarkAnnotationClassInfo
78
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmAsyncTransformer
9+
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingMarkAnnotationClassInfo
10+
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformFunction
811
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformer
9-
import love.forte.plugin.suspendtrans.configuration.TargetPlatform
12+
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmNameAnnotationClassInfo
13+
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmSyntheticClassInfo
14+
import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.kotlinOptInClassInfo
1015
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot
1116
import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots
1217
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
@@ -35,9 +40,45 @@ class SuspendTransformerEnvironmentConfigurator(testServices: TestServices) : En
3540
TargetPlatform.JVM to listOf(
3641
jvmBlockingTransformer,
3742
jvmAsyncTransformer,
43+
44+
//Test for JvmBlockingWithType
45+
Transformer(
46+
markAnnotation = MarkAnnotation(
47+
classInfo = ClassInfo(
48+
packageName = "love.forte.plugin.suspendtrans.annotation",
49+
className = "JvmBlockingWithType"
50+
),
51+
defaultSuffix = "Blocking",
52+
markNameProperty = MarkNameProperty(
53+
propertyName = "markName",
54+
annotation = jvmNameAnnotationClassInfo,
55+
annotationMarkNamePropertyName = "name"
56+
),
57+
hasReturnTypeOverrideGeneric = true
58+
),
59+
transformFunctionInfo = jvmBlockingTransformFunction,
60+
transformReturnType = null,
61+
transformReturnTypeGeneric = false,
62+
originFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmSyntheticClassInfo)),
63+
syntheticFunctionIncludeAnnotations = listOf(
64+
IncludeAnnotation(
65+
classInfo = jvmApi4JAnnotationClassInfo,
66+
includeProperty = true
67+
)
68+
),
69+
copyAnnotationsToSyntheticFunction = true,
70+
copyAnnotationExcludes = listOf(
71+
jvmSyntheticClassInfo,
72+
jvmBlockingMarkAnnotationClassInfo,
73+
jvmAsyncMarkAnnotationClassInfo,
74+
kotlinOptInClassInfo,
75+
jvmNameAnnotationClassInfo,
76+
),
77+
)
3878
)
3979
)
4080
)
81+
4182
// register plugin
4283
SuspendTransformComponentRegistrar.register(this, testConfiguration)
4384
}
@@ -62,6 +103,16 @@ class SuspendTransformerEnvironmentConfigurator(testServices: TestServices) : En
62103
it
63104
)
64105
}
106+
getRuntimeJarFile("love.forte.plugin.suspendtrans.annotation.JvmBlockingWithType")?.let {
107+
configuration.addJvmClasspathRoot(
108+
it
109+
)
110+
}
111+
getRuntimeJarFile("love.forte.plugin.suspendtrans.annotation.JvmBlockingWithType0")?.let {
112+
configuration.addJvmClasspathRoot(
113+
it
114+
)
115+
}
65116

66117
// register coroutines
67118
getRuntimeJarFile("kotlinx.coroutines.CoroutineScope")?.let {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// FIR_DUMP
2+
// DUMP_IR
3+
// SOURCE
4+
// FILE: Main.kt [MainKt#main]
5+
6+
import love.forte.plugin.suspendtrans.annotation.JvmAsync
7+
import love.forte.plugin.suspendtrans.annotation.JvmBlocking
8+
import love.forte.plugin.suspendtrans.annotation.JvmBlockingWithType
9+
import love.forte.plugin.suspendtrans.annotation.JvmBlockingWithType0
10+
11+
annotation class FooAnno<T>
12+
13+
class Foo {
14+
@JvmBlockingWithType<T>
15+
@JvmBlockingWithType0<T>
16+
@FooAnno<T>
17+
suspend fun <T> foo(): T = "foo"
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package love.forte.plugin.suspendtrans.annotation
2+
3+
@OptIn(ExperimentalMultiplatform::class)
4+
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
5+
@Retention(AnnotationRetention.BINARY)
6+
@OptionalExpectation
7+
public expect annotation class JvmBlockingWithType<T>(
8+
val baseName: String = "",
9+
val suffix: String = "Blocking",
10+
val asProperty: Boolean = false,
11+
val markName: String = "",
12+
)
13+
14+
@OptIn(ExperimentalMultiplatform::class)
15+
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
16+
@Retention(AnnotationRetention.BINARY)
17+
@OptionalExpectation
18+
public expect annotation class JvmBlockingWithType0<T>(
19+
val baseName: String = "",
20+
val suffix: String = "Blocking",
21+
val asProperty: Boolean = false,
22+
val markName: String = "",
23+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package love.forte.plugin.suspendtrans.annotation
2+
3+
@OptIn(markerClass = [ExperimentalMultiplatform::class])
4+
@Target(allowedTargets = [AnnotationTarget.FUNCTION, AnnotationTarget.CLASS])
5+
@Retention(value = AnnotationRetention.BINARY)
6+
public actual annotation class JvmBlockingWithType<T> actual constructor(
7+
actual val baseName: String,
8+
actual val suffix: String,
9+
actual val asProperty: Boolean,
10+
actual val markName: String
11+
)
12+
13+
@OptIn(markerClass = [ExperimentalMultiplatform::class])
14+
@Target(allowedTargets = [AnnotationTarget.FUNCTION, AnnotationTarget.CLASS])
15+
@Retention(value = AnnotationRetention.BINARY)
16+
public actual annotation class JvmBlockingWithType0<T> actual constructor(
17+
actual val baseName: String,
18+
actual val suffix: String,
19+
actual val asProperty: Boolean,
20+
actual val markName: String
21+
)

tests/test-jvm/build.gradle.kts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,23 @@ suspendTransformPlugin {
6868
transformReturnTypeGeneric = false
6969
}
7070
//
71-
// addJvmAsync {
72-
// markAnnotation {
73-
// classInfo {
74-
// packageName = "love.forte.suspendtrans.test.runner"
75-
// className = "JvmResultAsync"
76-
// }
77-
// hasReturnTypeOverrideGeneric = true
78-
// }
79-
// transformFunctionInfo {
80-
// packageName = "love.forte.suspendtrans.test.runner"
81-
// functionName = "jvmResultToAsync"
82-
// }
83-
// // CompletableFuture<T>
84-
// // transformReturnType {
85-
// // }
86-
// transformReturnTypeGeneric = true
87-
// }
71+
addJvmAsync {
72+
markAnnotation {
73+
classInfo {
74+
packageName = "love.forte.suspendtrans.test.runner"
75+
className = "JvmResultAsync"
76+
}
77+
hasReturnTypeOverrideGeneric = true
78+
}
79+
transformFunctionInfo {
80+
packageName = "love.forte.suspendtrans.test.runner"
81+
functionName = "jvmResultToAsync"
82+
}
83+
// CompletableFuture<T>
84+
// transformReturnType {
85+
// }
86+
transformReturnTypeGeneric = true
87+
}
8888

8989
}
9090
}

tests/test-jvm/src/main/kotlin/love/forte/plugin/suspendtrans/sample/returntypeoverride/ReturnTypeOverrides.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import kotlinx.coroutines.delay
44
import love.forte.suspendtrans.test.runner.JvmResultAsync
55
import love.forte.suspendtrans.test.runner.JvmResultBlock
66

7-
interface Foo {
7+
interface Foo<R> {
88
@JvmResultBlock<String>
99
@JvmResultAsync<String>
1010
suspend fun hello(): Result<String> {
@@ -15,9 +15,9 @@ interface Foo {
1515
// TODO e: file://~/suspend-transform-kotlin-compile-plugin/tests/test-jvm/src/main/kotlin/love/forte/plugin/suspendtrans/sample/returntypeoverride/ReturnTypeOverrides.kt:16:21 Unresolved reference 'T'.
1616
// @JvmResultBlock<T>
1717
// @JvmResultAsync<T>
18-
// suspend fun <T> foo(value: T): Result<T> {
19-
// delay(1)
20-
// return Result.success(value)
21-
// }
18+
suspend fun <T> foo(value: T): Result<T> {
19+
delay(1)
20+
return Result.success(value)
21+
}
2222

2323
}

0 commit comments

Comments
 (0)