Skip to content

Commit 18f80b3

Browse files
authored
合并拉取请求 #4
支持类级注释
2 parents 7d4b27d + 53eba3f commit 18f80b3

File tree

3 files changed

+91
-56
lines changed

3 files changed

+91
-56
lines changed

compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SuspendTransformSyntheticResolveExtension.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ open class SuspendTransformSyntheticResolveExtension(open val configuration: Sus
7878
return syntheticFunctions.getCurrentSyntheticDescriptorNames(thisDescriptor)
7979
}
8080

81+
8182
override fun generateSyntheticMethods(
8283
thisDescriptor: ClassDescriptor,
8384
name: Name,
@@ -107,9 +108,11 @@ open class SuspendTransformSyntheticResolveExtension(open val configuration: Sus
107108

108109
// check and add synthetic functions.
109110
// find all annotated
110-
result.forEach { originFunction ->
111+
result
112+
.filter { f -> f.isSuspend }
113+
.forEach { originFunction ->
111114
val resolvedAnnotations =
112-
originFunction.annotations.resolveToTransformAnnotations(configuration, originFunction.name.identifier)
115+
originFunction.resolveToTransformAnnotations(thisDescriptor, configuration)
113116
if (resolvedAnnotations.isEmpty) {
114117
return@forEach
115118
}
@@ -151,7 +154,6 @@ open class SuspendTransformSyntheticResolveExtension(open val configuration: Sus
151154
type: SyntheticType,
152155
): AbstractSuspendTransformFunctionDescriptor<*>? {
153156
if (annotationData == null) return null
154-
val asProperty = annotationData.asProperty == true
155157
return when {
156158
classDescriptor.platform.isJvm() && type == SyntheticType.JVM_BLOCKING -> SuspendTransformJvmBlockingFunctionDescriptorImpl(
157159
classDescriptor,

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

Lines changed: 83 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,21 @@
11
package love.forte.plugin.suspendtrans.utils
22

33
import love.forte.plugin.suspendtrans.*
4-
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
4+
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
5+
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
56
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
67
import org.jetbrains.kotlin.descriptors.annotations.Annotations
78
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
89
import org.jetbrains.kotlin.ir.builders.irCall
9-
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
10-
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
1110
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
1211
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
1312
import org.jetbrains.kotlin.ir.util.constructors
1413
import org.jetbrains.kotlin.ir.util.irConstructorCall
15-
import org.jetbrains.kotlin.name.FqName
1614
import org.jetbrains.kotlin.resolve.annotations.argumentValue
1715
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
1816
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
1917

2018

21-
fun AnnotationDescriptor?.functionName(
22-
baseNamePropertyName: String = "baseName",
23-
suffixPropertyName: String = "suffix",
24-
defaultBaseName: String, defaultSuffix: String,
25-
): String {
26-
if (this == null) return "$defaultBaseName$defaultSuffix"
27-
28-
val visitor = object : AbstractNullableAnnotationArgumentVoidDataVisitor<String>() {
29-
override fun visitStringValue(value: String): String = value
30-
}
31-
32-
val baseName = argumentValue(baseNamePropertyName)?.accept(visitor, null)
33-
val suffix = argumentValue(suffixPropertyName)?.accept(visitor, null)
34-
35-
return (baseName ?: defaultBaseName) + (suffix ?: defaultSuffix)
36-
}
37-
38-
/**
39-
* Get the `@Generated` annotation.
40-
*/
41-
val IrPluginContext.generatedAnnotation get() = referenceClass(generatedAnnotationName)!!
42-
43-
4419
fun IrBuilderWithScope.irAnnotationConstructor(
4520
clazz: IrClassSymbol,
4621
): IrConstructorCall {
@@ -49,19 +24,6 @@ fun IrBuilderWithScope.irAnnotationConstructor(
4924
}
5025
}
5126

52-
fun List<IrConstructorCall>.filterNotCompileAnnotations(): List<IrConstructorCall> = filterNot {
53-
it.type.isClassType(toJvmAsyncAnnotationName.toUnsafe()) || it.type.isClassType(toJvmBlockingAnnotationName.toUnsafe()) || it.type.isClassType(
54-
toJsPromiseAnnotationName.toUnsafe()
55-
)
56-
}
57-
58-
private fun IrDeclarationWithName.hasEqualFqName(fqName: FqName): Boolean =
59-
name == fqName.shortName() && when (val parent = parent) {
60-
is IrPackageFragment -> parent.fqName == fqName.parent()
61-
is IrDeclarationWithName -> parent.hasEqualFqName(fqName.parent())
62-
else -> false
63-
}
64-
6527
fun Iterable<AnnotationDescriptor>.filterNotCompileAnnotations(): List<AnnotationDescriptor> = filterNot {
6628
val annotationFqNameUnsafe = it.annotationClass?.fqNameUnsafe ?: return@filterNot true
6729

@@ -72,19 +34,35 @@ fun Iterable<AnnotationDescriptor>.filterNotCompileAnnotations(): List<Annotatio
7234

7335
data class TransformAnnotationData(
7436
val annotationDescriptor: AnnotationDescriptor,
75-
val annotationBaseNamePropertyName: String = "baseName",
76-
val annotationSuffixPropertyName: String = "suffix",
77-
val annotationAsPropertyPropertyName: String = "asProperty",
78-
val defaultBaseName: String,
79-
val defaultSuffix: String,
37+
val baseName: String?,
38+
val suffix: String?,
39+
val asProperty: Boolean?,
40+
val functionName: String
8041
) {
81-
val baseName: String? = annotationDescriptor.argumentValue(annotationBaseNamePropertyName)
82-
?.accept(AbstractNullableAnnotationArgumentVoidDataVisitor.stringOnly, null)
83-
val suffix: String? = annotationDescriptor.argumentValue(annotationSuffixPropertyName)
84-
?.accept(AbstractNullableAnnotationArgumentVoidDataVisitor.stringOnly, null)
85-
val asProperty: Boolean? = annotationDescriptor.argumentValue(annotationAsPropertyPropertyName)
86-
?.accept(AbstractNullableAnnotationArgumentVoidDataVisitor.booleanOnly, null)
87-
val functionName: String = "${baseName ?: defaultBaseName}${suffix ?: defaultSuffix}"
42+
companion object {
43+
fun of(
44+
annotationDescriptor: AnnotationDescriptor,
45+
annotationBaseNamePropertyName: String = "baseName",
46+
annotationSuffixPropertyName: String = "suffix",
47+
annotationAsPropertyPropertyName: String = "asProperty",
48+
defaultBaseName: String,
49+
defaultSuffix: String,
50+
): TransformAnnotationData {
51+
val baseName = annotationDescriptor.argumentValue(annotationBaseNamePropertyName)
52+
?.accept(AbstractNullableAnnotationArgumentVoidDataVisitor.stringOnly, null)
53+
?.takeIf { it.isNotEmpty() }
54+
val suffix = annotationDescriptor.argumentValue(annotationSuffixPropertyName)
55+
?.accept(AbstractNullableAnnotationArgumentVoidDataVisitor.stringOnly, null)
56+
?.takeIf { it.isNotEmpty() }
57+
val asProperty = annotationDescriptor.argumentValue(annotationAsPropertyPropertyName)
58+
?.accept(AbstractNullableAnnotationArgumentVoidDataVisitor.booleanOnly, null)
59+
val functionName = "${baseName ?: defaultBaseName}${suffix ?: defaultSuffix}"
60+
61+
return TransformAnnotationData(annotationDescriptor, baseName, suffix, asProperty, functionName)
62+
}
63+
}
64+
65+
8866
}
8967

9068
open class FunctionTransformAnnotations(
@@ -100,6 +78,58 @@ open class FunctionTransformAnnotations(
10078
}
10179
}
10280

81+
82+
fun FunctionDescriptor.resolveToTransformAnnotations(
83+
containing: DeclarationDescriptor = this.containingDeclaration,
84+
configuration: SuspendTransformConfiguration
85+
): FunctionTransformAnnotations {
86+
val baseName = this.name.identifier
87+
val containingAnnotations = containing.annotations.resolveToTransformAnnotations(configuration, baseName)
88+
val functionAnnotations = this.annotations.resolveToTransformAnnotations(configuration, baseName)
89+
90+
return containingAnnotations + functionAnnotations
91+
}
92+
93+
/*
94+
* 后者优先。
95+
*/
96+
private operator fun FunctionTransformAnnotations.plus(other: FunctionTransformAnnotations): FunctionTransformAnnotations {
97+
if (other.isEmpty) return this
98+
99+
return FunctionTransformAnnotations(
100+
jvmBlockingAnnotationData + other.jvmBlockingAnnotationData,
101+
jvmAsyncAnnotationData + other.jvmAsyncAnnotationData,
102+
jsAsyncAnnotationData + other.jsAsyncAnnotationData,
103+
)
104+
}
105+
106+
/*
107+
* 后者优先。
108+
*/
109+
private operator fun TransformAnnotationData?.plus(other: TransformAnnotationData?): TransformAnnotationData? {
110+
if (this == null && other == null) return null
111+
if (other == null) return this
112+
if (this == null) return other
113+
114+
val baseName = other.baseName ?: this.baseName
115+
val suffix = other.suffix ?: this.suffix
116+
117+
val functionName = if (baseName == null) other.functionName else buildString {
118+
append(baseName)
119+
suffix?.also(::append)
120+
}
121+
122+
return TransformAnnotationData(
123+
annotationDescriptor = other.annotationDescriptor,
124+
baseName = baseName,
125+
suffix = suffix,
126+
asProperty = other.asProperty ?: this.asProperty,
127+
functionName = functionName
128+
)
129+
130+
}
131+
132+
103133
fun Annotations.resolveToTransformAnnotations(
104134
configuration: SuspendTransformConfiguration,
105135
functionBaseName: String
@@ -112,7 +142,7 @@ fun Annotations.resolveToTransformAnnotations(
112142
annotationAsPropertyPropertyName: String = this.asPropertyProperty,
113143
): TransformAnnotationData? {
114144
return findAnnotation(this.annotationName.fqn)?.let {
115-
TransformAnnotationData(
145+
TransformAnnotationData.of(
116146
it,
117147
annotationBaseNamePropertyName,
118148
annotationSuffixPropertyName,

compiler/suspend-transform-plugin/testData/justTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import love.forte.plugin.suspendtrans.annotation.JvmBlocking
77
@kotlin.annotation.Target(AnnotationTarget.FUNCTION)
88
annotation class Hi
99

10+
@JvmBlocking
11+
suspend fun hello(): String = "hello"
12+
1013
class JustTest : ITest { // : ITest
1114

1215
@Hi

0 commit comments

Comments
 (0)