Skip to content

Commit

Permalink
Try to support K2
Browse files Browse the repository at this point in the history
  • Loading branch information
ForteScarlet committed Jan 25, 2024
1 parent 3ab334f commit a82de5a
Show file tree
Hide file tree
Showing 19 changed files with 632 additions and 245 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/IProject.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,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, 7, 0) - version("beta1")
override val version: Version = version(0, 7, 0) - version("dev2")

override val homepage: String get() = HOMEPAGE

Expand Down
8 changes: 8 additions & 0 deletions compiler/suspend-transform-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ compileKotlin.kotlinOptions.freeCompilerArgs += listOf(
"-opt-in=org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI",
)

tasks.withType(KotlinCompile::class.java).configureEach {
// see https://youtrack.jetbrains.com/issue/KTIJ-21563
// see https://youtrack.jetbrains.com/issue/KT-57297
// kotlinOptions {
// languageVersion = "1.9"
// apiVersion = "1.9"
// }
}

repositories {
maven {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
Expand Down Expand Up @@ -122,10 +123,10 @@ class SuspendTransformFirTransformer(

origin = SuspendTransformPluginKey(
data = SuspendTransformUserDataFir(
originSymbol = symbol.asOriginSymbol(
typeParameters = typeParameters,
valueParameters = valueParameters,
returnType.coneTypeOrNull?.classId
originSymbol = originFunc.symbol.asOriginSymbol(
typeParameters = originFunc.typeParameters,
valueParameters = originFunc.valueParameters,
originFunc.returnTypeRef.coneTypeOrNull?.classId
),
asProperty = false,
transformer = funData.transformer
Expand Down Expand Up @@ -161,67 +162,113 @@ class SuspendTransformFirTransformer(
val (functionAnnotations, propertyAnnotations) =
copyAnnotations(original, funData)

val p = buildProperty {
// val p = createMemberProperty()
// owner = owner,
// key = SuspendTransformPluginKey(
// data = SuspendTransformUserDataFir(
// originSymbol = original.symbol.asOriginSymbol(
// typeParameters = original.typeParameters,
// valueParameters = original.valueParameters,
// original.returnTypeRef.coneTypeOrNull?.classId
// ),
// asProperty = true,
// transformer = funData.transformer
// )
// ),
// name = callableId.callableName,
// returnTypeProvider = { resolveReturnConeType(original, funData) },
// isVal = true,
// hasBackingField = false,
// ) {
// modality = original.syntheticModifier ?: Modality.FINAL
// // TODO receiver?
//// val receiverType = original.receiverParameter?.typeRef?.coneTypeOrNull
//// if (receiverType != null) {
//// extensionReceiverType(receiverType)
//// }
// }

val pSymbol = FirPropertySymbol(callableId)
val pKey = SuspendTransformPluginKey(
data = SuspendTransformUserDataFir(
originSymbol = original.symbol.asOriginSymbol(
typeParameters = original.typeParameters,
valueParameters = original.valueParameters,
original.returnTypeRef.coneTypeOrNull?.classId
),
asProperty = true,
transformer = funData.transformer
)
)

val returnType = resolveReturnType(original, funData)

val p1 = buildProperty {
symbol = pSymbol
name = callableId.callableName
symbol = FirPropertySymbol(callableId)
source = original.source
resolvePhase = original.resolvePhase
moduleData = original.moduleData
origin = original.origin
origin = pKey.origin
attributes = original.attributes.copy()
status = original.status.copy(
isSuspend = false,
isFun = false,
isInner = false,
// modality = if (original.status.isOverride) Modality.OPEN else original.status.modality,
modality = original.syntheticModifier,
)
returnTypeRef = original.returnTypeRef
deprecationsProvider = original.deprecationsProvider
isVar = false
isLocal = false
returnTypeRef = returnType
deprecationsProvider = UnresolvedDeprecationProvider //original.deprecationsProvider
containerSource = original.containerSource
dispatchReceiverType = original.dispatchReceiverType
contextReceivers.addAll(original.contextReceivers)
// annotations
annotations.addAll(propertyAnnotations)
typeParameters.addAll(original.typeParameters)
resolvePhase = FirResolvePhase.BODY_RESOLVE
backingField = null
bodyResolveState = FirPropertyBodyResolveState.NOTHING_RESOLVED

getter = buildPropertyAccessor {
propertySymbol = pSymbol
symbol = FirPropertyAccessorSymbol()
source = original.source
resolvePhase = original.resolvePhase
isGetter = true
resolvePhase = FirResolvePhase.BODY_RESOLVE
moduleData = original.moduleData

// annotations
annotations.addAll(functionAnnotations)

val returnType = resolveReturnType(original, funData)

returnTypeRef = returnType

origin = SuspendTransformPluginKey(
data = SuspendTransformUserDataFir(
originSymbol = symbol.asOriginSymbol(
typeParameters = typeParameters,
valueParameters = valueParameters,
returnType.coneTypeOrNull?.classId
),
asProperty = true,
transformer = funData.transformer
)
).origin

attributes = original.attributes.copy()
status = original.status
origin = pKey.origin

// attributes = original.attributes.copy()
status = original.status.copy(
isSuspend = false,
isFun = false,
isInner = false,
modality = original.syntheticModifier,
// visibility = [email protected]
)
returnTypeRef = original.returnTypeRef
deprecationsProvider = original.deprecationsProvider
containerSource = original.containerSource
dispatchReceiverType = original.dispatchReceiverType
contextReceivers.addAll(original.contextReceivers)
// deprecationsProvider = original.deprecationsProvider
// containerSource = original.containerSource
// dispatchReceiverType = original.dispatchReceiverType
// contextReceivers.addAll(original.contextReceivers)
valueParameters.addAll(original.valueParameters)
body = original.body
contractDescription = original.contractDescription
annotations.addAll(original.annotations) // TODO
// body = null
// contractDescription = original.contractDescription
// annotations
annotations.addAll(functionAnnotations)
typeParameters.addAll(original.typeParameters)
}
}

propList.add(p.symbol)
propList.add(p1.symbol)
}
}

Expand Down Expand Up @@ -275,7 +322,6 @@ class SuspendTransformFirTransformer(

declaredScope.processAllFunctions { func ->
if (!func.isSuspend) return@processAllFunctions
// if (!func.visibility.isPublicAPI) return@processAllFunctions

val functionName = func.name.asString()
suspendTransformConfiguration.transformers.asSequence()
Expand All @@ -294,7 +340,11 @@ class SuspendTransformFirTransformer(
).firstOrNull()
?: continue

// TODO 读不到注解的参数?

// 读不到注解的参数?
// 必须使用 anno.getXxxArgument(Name(argument name)),
// 使用 argumentMapping.mapping 获取不到结果
// println("RAW AnnoData: ${anno.argumentMapping.mapping}")

val annoData = TransformAnnotationData.of(
firAnnotation = anno,
Expand All @@ -316,15 +366,29 @@ class SuspendTransformFirTransformer(
}

private fun resolveReturnType(original: FirSimpleFunction, funData: FunData): FirTypeRef {
val originalReturnTypeRef = original.returnTypeRef
val resultConeType = resolveReturnConeType(original, funData)

return if (resultConeType is ConeErrorType) {
buildErrorTypeRef {
diagnostic = resultConeType.diagnostic
type = resultConeType
}
} else {
buildResolvedTypeRef {
type = resultConeType
}
}
}

private fun resolveReturnConeType(original: FirSimpleFunction, funData: FunData): ConeKotlinType {
val transformer = funData.transformer
val returnType = transformer.transformReturnType
?: return originalReturnTypeRef
?: return original.symbol.resolvedReturnType

var typeArguments: Array<ConeTypeProjection> = emptyArray()

if (transformer.transformReturnTypeGeneric) {
typeArguments = arrayOf(ConeKotlinTypeProjectionOut(originalReturnTypeRef.coneType))
typeArguments = arrayOf(ConeKotlinTypeProjectionOut(original.returnTypeRef.coneType))
}

val resultConeType = returnType.toClassId().createConeType(
Expand All @@ -333,12 +397,9 @@ class SuspendTransformFirTransformer(
nullable = returnType.nullable
)

return buildResolvedTypeRef {
type = resultConeType
}
return resultConeType
}


/**
* @return function annotations `to` property annotations.
*/
Expand Down Expand Up @@ -366,7 +427,7 @@ class SuspendTransformFirTransformer(
}

// try add @Generated(by = ...)
runCatching {
// runCatching {
// val generatedAnnotation = buildAnnotation {
// annotationTypeRef = buildResolvedTypeRef {
// type = generatedAnnotationClassId.createConeType(session)
Expand All @@ -376,16 +437,14 @@ class SuspendTransformFirTransformer(
// }
// }
// add(generatedAnnotation)
}.getOrElse { e ->
// Where is log?
e.printStackTrace()
}
// }.getOrElse { e ->
// // Where is log?
// e.printStackTrace()
// }

// add includes
includes.forEach { include ->
val classId = include.classId
println("!!!include: $include")
println("!!!include: $classId")
val includeAnnotation = buildAnnotation {
argumentMapping = buildAnnotationArgumentMapping()
annotationTypeRef = buildResolvedTypeRef {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,26 @@ class SuspendTransformTransformer(
@OptIn(ObsoleteDescriptorBasedAPI::class)
override fun visitPropertyNew(declaration: IrProperty): IrStatement {
val getter = declaration.getter ?: return super.visitPropertyNew(declaration)
resolveFunctionBodyByDescriptor(getter, declaration.descriptor)
resolveFunctionBodyByDescriptor(getter, declaration.descriptor, declaration)

return super.visitPropertyNew(declaration)
}

@OptIn(ObsoleteDescriptorBasedAPI::class)
private fun resolveFunctionBodyByDescriptor(declaration: IrFunction, descriptor: CallableDescriptor): IrFunction? {
private fun resolveFunctionBodyByDescriptor(
declaration: IrFunction,
descriptor: CallableDescriptor,
property: IrProperty? = null
): IrFunction? {
// K2
val pluginKey = (declaration.origin as? IrDeclarationOrigin.GeneratedByPlugin)
?.pluginKey as? SuspendTransformPluginKey
val pluginKey = if (property != null) {
// from property
(property.origin as? IrDeclarationOrigin.GeneratedByPlugin)
?.pluginKey as? SuspendTransformPluginKey
} else {
(declaration.origin as? IrDeclarationOrigin.GeneratedByPlugin)
?.pluginKey as? SuspendTransformPluginKey
}

// K1 ?
val userData = descriptor.getUserData(SuspendTransformUserDataKey)
Expand All @@ -76,9 +86,15 @@ class SuspendTransformTransformer(

resolveFunctionBody(
declaration,
{ f -> pluginKey.data.originSymbol.checkSame(f).also { println("Check result: $it: ($f(${f.name}) same ${pluginKey.data.originSymbol})") } },
{ f ->
pluginKey.data.originSymbol.checkSame(f)
},
callableFunction
)?.also { generatedOriginFunction ->
if (property != null) {
// NO! BACKING! FIELD!
property.backingField = null
}
postProcessGenerateOriginFunction(
generatedOriginFunction,
pluginKey.data.transformer.originFunctionIncludeAnnotations
Expand Down Expand Up @@ -145,7 +161,7 @@ class SuspendTransformTransformer(

if (originFunctions.size != 1) {
val message =
"Transform function $function (${function.name}) 's originFunctions.size should be 1, but ${originFunctions.size} (findIn = ${(parent as? IrDeclaration)?.descriptor}, originFunctions = $originFunctions)"
"Synthetic function $function (${function.name}) 's originFunctions.size should be 1, but ${originFunctions.size} (findIn = ${(parent as? IrDeclaration)?.descriptor}, originFunctions = $originFunctions)"

val location = when (val sourceLocation =
function.getSourceLocation(runCatching { function.fileEntry }.getOrNull())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import love.forte.plugin.suspendtrans.toJvmBlockingAnnotationName
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.fir.declarations.getBooleanArgument
import org.jetbrains.kotlin.fir.declarations.getStringArgument
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.irCall
Expand Down Expand Up @@ -96,15 +98,12 @@ data class TransformAnnotationData(
defaultAsProperty: Boolean,
): TransformAnnotationData {

val baseName = firAnnotation.argumentMapping.mapping[Name.identifier(annotationBaseNamePropertyName)]
?.accept(AbstractFirAnnotationArgumentVoidDataVisitor.nullableString, null)
val baseName = firAnnotation.getStringArgument(Name.identifier(annotationBaseNamePropertyName))
?.takeIf { it.isNotEmpty() }

val suffix = firAnnotation.argumentMapping.mapping[Name.identifier(annotationSuffixPropertyName)]
?.accept(AbstractFirAnnotationArgumentVoidDataVisitor.nullableString, null)
val suffix = firAnnotation.getStringArgument(Name.identifier(annotationSuffixPropertyName))

val rawAsProperty = firAnnotation.argumentMapping.mapping[Name.identifier(annotationAsPropertyPropertyName)]
?.accept(AbstractFirAnnotationArgumentVoidDataVisitor.nullableBoolean, null)
val rawAsProperty = firAnnotation.getBooleanArgument(Name.identifier(annotationAsPropertyPropertyName))

val functionName = "${baseName ?: defaultBaseName}${suffix ?: defaultSuffix}"

Expand Down
Loading

0 comments on commit a82de5a

Please sign in to comment.