Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions buildSrc/src/main/kotlin/IProject.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import love.forte.gradle.common.core.project.ProjectDetail
import love.forte.gradle.common.core.project.Version
import love.forte.gradle.common.core.project.minus
import love.forte.gradle.common.core.project.version

object IProject : ProjectDetail() {
Expand All @@ -9,7 +8,7 @@ object IProject : ProjectDetail() {
const val DESCRIPTION = "Generate platform-compatible functions for Kotlin suspend functions"
const val HOMEPAGE = "https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin"

override val version: Version = version(0, 8, 0) - version("beta1")
override val version: Version = version(0, 9, 0)

override val homepage: String get() = HOMEPAGE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,28 @@ data class Transformer(
val originFunctionIncludeAnnotations: List<IncludeAnnotation>,

/**
* 需要在生成出来的函数上追截的注解信息。(不需要指定 `@Generated`)
* 需要在生成出来的函数上追加的注解信息。(不需要指定 `@Generated`)
*/
val syntheticFunctionIncludeAnnotations: List<IncludeAnnotation>,

/**
* 是否复制源函数上的注解到新的函数上。
* 如果生成的是属性类型,则表示是否复制到 `getter` 上。
*/
val copyAnnotationsToSyntheticFunction: Boolean,

/**
* 复制原函数上注解时需要排除掉的注解。
*/
val copyAnnotationExcludes: List<ClassInfo>
)
) {
/**
* 如果是生成属性的话,是否复制源函数上的注解到新的属性上
*
* @since 0.9.0
*/
var copyAnnotationsToSyntheticProperty: Boolean = false
}

/**
* 用于标记的注解信息.
Expand Down Expand Up @@ -131,7 +139,14 @@ data class MarkAnnotation @JvmOverloads constructor(
@Serializable
data class IncludeAnnotation(
val classInfo: ClassInfo, val repeatable: Boolean = false
)
) {
/**
* 如果是追加,是否追加到property上
*
* @since 0.9.0
*/
var includeProperty: Boolean = false
}

/**
*
Expand Down Expand Up @@ -234,7 +249,10 @@ open class SuspendTransformConfiguration {
originFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmSyntheticClassInfo)),
copyAnnotationsToSyntheticFunction = true,
copyAnnotationExcludes = listOf(jvmSyntheticClassInfo, jvmBlockingAnnotationInfo.classInfo),
syntheticFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmApi4JAnnotationClassInfo))
syntheticFunctionIncludeAnnotations = listOf(
IncludeAnnotation(jvmApi4JAnnotationClassInfo)
.apply { includeProperty = true }
)
)
//endregion

Expand All @@ -261,7 +279,11 @@ open class SuspendTransformConfiguration {
originFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmSyntheticClassInfo)),
copyAnnotationsToSyntheticFunction = true,
copyAnnotationExcludes = listOf(jvmSyntheticClassInfo, jvmAsyncAnnotationInfo.classInfo),
syntheticFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmApi4JAnnotationClassInfo))
syntheticFunctionIncludeAnnotations = listOf(
IncludeAnnotation(jvmApi4JAnnotationClassInfo).apply {
includeProperty = true
}
)
)
//endregion

Expand Down Expand Up @@ -291,7 +313,11 @@ open class SuspendTransformConfiguration {
originFunctionIncludeAnnotations = listOf(),
copyAnnotationsToSyntheticFunction = true,
copyAnnotationExcludes = listOf(jsAsyncAnnotationInfo.classInfo),
syntheticFunctionIncludeAnnotations = listOf(IncludeAnnotation(jsApi4JsAnnotationInfo))
syntheticFunctionIncludeAnnotations = listOf(
IncludeAnnotation(jsApi4JsAnnotationInfo).apply {
includeProperty = true
}
)
)
//endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,15 +401,14 @@ class SuspendTransformFirTransformer(
): Pair<List<FirAnnotation>, List<FirAnnotation>> {
val transformer = funData.transformer

val (copyFunction, excludes, includes) = CopyAnnotationsData(
val (copyFunction, copyProperty, excludes, includes) = CopyAnnotationsData(
transformer.copyAnnotationsToSyntheticFunction,
transformer.copyAnnotationsToSyntheticProperty,
transformer.copyAnnotationExcludes.map { it.toClassId() },
transformer.syntheticFunctionIncludeAnnotations.map { it.toInfo() }
)

val annotationList = mutableListOf<FirAnnotation>()

with(annotationList) {
val functionAnnotationList = buildList<FirAnnotation> {
if (copyFunction) {
val notCompileAnnotationsCopied = original.annotations.filterNot {
val annotationClassId = it.toAnnotationClassId(session) ?: return@filterNot true
Expand Down Expand Up @@ -448,7 +447,32 @@ class SuspendTransformFirTransformer(
}
}

return annotationList to emptyList()
val propertyAnnotationList = buildList<FirAnnotation> {
if (copyProperty) {
val notCompileAnnotationsCopied = original.annotations.filterNot {
val annotationClassId = it.toAnnotationClassId(session) ?: return@filterNot true
excludes.any { ex -> annotationClassId == ex }
}

addAll(notCompileAnnotationsCopied)
}

// add includes
includes
.filter { it.includeProperty }
.forEach { include ->
val classId = include.classId
val includeAnnotation = buildAnnotation {
argumentMapping = buildAnnotationArgumentMapping()
annotationTypeRef = buildResolvedTypeRef {
type = classId.createConeType(session)
}
}
add(includeAnnotation)
}
}

return functionAnnotationList to propertyAnnotationList
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sealed class AbstractSuspendTransformFunctionDescriptor(
private val originFunction: SimpleFunctionDescriptor,
functionName: Name,
annotations: Annotations,
internal val propertyAnnotations: Annotations,
val propertyAnnotations: Annotations,
private val userData: SuspendTransformUserData,
val transformer: Transformer
) : SimpleFunctionDescriptorImpl(
Expand Down Expand Up @@ -92,7 +92,7 @@ sealed class AbstractSuspendTransformFunctionDescriptor(
return SimpleSuspendTransformPropertyDescriptor(
classDescriptor,
this,
annotations,
propertyAnnotations,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,14 @@ private fun copyAnnotations(
return AnnotationDescriptorImpl(type, valueArguments, descriptor.source)
}

val (copyFunction, excludes, includes) = CopyAnnotationsData(
val (copyFunction, copyProperty, excludes, includes) = CopyAnnotationsData(
transformer.copyAnnotationsToSyntheticFunction,
transformer.copyAnnotationsToSyntheticProperty,
transformer.copyAnnotationExcludes.map { it.toClassId() },
transformer.syntheticFunctionIncludeAnnotations.map { it.toInfo() }
)

val annotationsList = mutableListOf<AnnotationDescriptor>()

annotationsList.apply {
val functionAnnotationsList = buildList<AnnotationDescriptor> {
if (copyFunction) {
val notCompileAnnotationsCopied = originFunction.annotations.filterNotCompileAnnotations().filterNot {
val annotationClassId = it.annotationClass?.classId ?: return@filterNot true
Expand All @@ -269,7 +268,35 @@ private fun copyAnnotations(
}
}

return Annotations.create(annotationsList) to Annotations.EMPTY
val propertyAnnotationsList = buildList<AnnotationDescriptor> {
if (copyProperty) {
val notCompileAnnotationsCopied = originFunction.annotations.filterNotCompileAnnotations().filterNot {
val annotationClassId = it.annotationClass?.classId ?: return@filterNot true
excludes.any { ex -> annotationClassId == ex }
}
addAll(notCompileAnnotationsCopied)
}

// try add @Generated(by = ...)
findAnnotation(
generatedAnnotationClassId,
mutableMapOf(Name.identifier("by") to StringArrayValue(originFunction.toGeneratedByDescriptorInfo()))
)?.also(::add)

// add includes
includes
.filter { it.includeProperty }
.forEach { include ->
val classId = include.classId
val unsafeFqName = classId.asSingleFqName().toUnsafe()
if (!include.repeatable && this.any { it.fqName?.toUnsafe() == unsafeFqName }) {
return@forEach
}
findAnnotation(classId)?.also(::add)
}
}

return Annotations.create(functionAnnotationsList) to Annotations.create(propertyAnnotationsList)
}

private class StringArrayValue(values: List<StringValue>) : ArrayValue(values, { module ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import org.jetbrains.kotlin.name.ClassId

data class CopyAnnotationsData(
val copyFunction: Boolean,
val copyProperty: Boolean,
val excludes: List<ClassId>,
val includes: List<IncludeAnnotationInfo>
)

data class IncludeAnnotationInfo(
val classId: ClassId,
val repeatable: Boolean
val repeatable: Boolean,
val includeProperty: Boolean,
)

fun IncludeAnnotation.toInfo(): love.forte.plugin.suspendtrans.utils.IncludeAnnotationInfo {
return IncludeAnnotationInfo(classInfo.toClassId(), repeatable)
fun IncludeAnnotation.toInfo(): IncludeAnnotationInfo {
return IncludeAnnotationInfo(classInfo.toClassId(), repeatable, includeProperty)
}
3 changes: 2 additions & 1 deletion samples/sample-jvm/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension
import org.jetbrains.kotlin.js.translate.context.Namer.kotlin

plugins {
`java-library`
Expand All @@ -16,7 +17,7 @@ buildscript {
}
dependencies {
//this.implementation()
classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.8.0-beta1")
classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.9.0-beta1")
}
}

Expand Down