Skip to content

Commit c8f310f

Browse files
committed
FIX the fk type parameter! ... maybe?
1 parent 64686c1 commit c8f310f

File tree

6 files changed

+223
-138
lines changed

6 files changed

+223
-138
lines changed

buildSrc/src/main/kotlin/IProject.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object IProject : ProjectDetail() {
1010
const val HOMEPAGE = "https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin"
1111

1212
// Remember the libs.versions.toml!
13-
val ktVersion = "2.0.21"
13+
val ktVersion = "2.0.20"
1414
val pluginVersion = "0.9.4"
1515

1616
override val version: String = "$ktVersion-$pluginVersion"

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

+190-97
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ import org.jetbrains.kotlin.platform.konan.isNative
5555
import org.jetbrains.kotlin.types.ConstantValueKind
5656
import java.util.concurrent.ConcurrentHashMap
5757

58+
private data class CopiedTypeParameterPair(
59+
val original: FirTypeParameter,
60+
val copied: FirTypeParameter
61+
)
5862

5963
/**
6064
*
@@ -150,114 +154,55 @@ class SuspendTransformFirTransformer(
150154
// The error: Duplicate IR node
151155
// [IR VALIDATION] JvmIrValidationBeforeLoweringPhase: Duplicate IR node: TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false of FUN GENERATED[...]
152156
// TODO copy to value parameters, receiver and return type?
153-
val originalTypeParameterCache = mutableMapOf<FirTypeParameter, FirTypeParameter>()
154-
typeParameters.replaceAll {
155-
buildTypeParameterCopy(it) {
156-
containingDeclarationSymbol = newFunSymbol // it.containingDeclarationSymbol
157+
val originalTypeParameterCache = mutableListOf<CopiedTypeParameterPair>()
158+
typeParameters.replaceAll {
159+
buildTypeParameterCopy(it) {
160+
containingDeclarationSymbol = newFunSymbol // it.containingDeclarationSymbol
157161
// symbol = it.symbol // FirTypeParameterSymbol()
158-
symbol = FirTypeParameterSymbol()
159-
}.also { new ->
160-
originalTypeParameterCache[it] = new
161-
162-
}
163-
}
162+
symbol = FirTypeParameterSymbol()
163+
}.also { new ->
164+
originalTypeParameterCache.add(CopiedTypeParameterPair(it, new))
165+
}
166+
}
164167

165-
// TODO
166168
valueParameters.replaceAll { vp ->
167169
buildValueParameterCopy(vp) {
168170
symbol = FirValueParameterSymbol(vp.symbol.name)
169171

170-
val cachedTypeParameter = originalTypeParameterCache.entries.find { (k, v) ->
171-
k.toConeType() == vp.returnTypeRef.coneTypeOrNull
172-
}
173-
val newReturnTypeRef = if (cachedTypeParameter != null) {
174-
returnTypeRef.withReplacedConeType(cachedTypeParameter.value.toConeType())
175-
} else {
176-
println("returnTypeRef: $returnTypeRef")
177-
returnTypeRef.coneType.typeArguments.forEach {
178-
println("returnTypeRef.coneType.typeArguments: $it")
179-
}
172+
val copiedConeType = vp.returnTypeRef.coneTypeOrNull
173+
?.copyWithTypeParameters(originalTypeParameterCache)
180174

181-
returnTypeRef
175+
if (copiedConeType != null) {
176+
returnTypeRef = returnTypeRef.withReplacedConeType(copiedConeType)
182177
}
183-
184-
returnTypeRef = newReturnTypeRef
185178
}
186179
}
187180

188-
// valueParameters.replaceAll { vp ->
189-
// buildValueParameterCopy(vp) {
190-
// //println("find: ${originalTypeParameterCache[vp.returnTypeRef]}")
191-
// val cachedTypeParameter = originalTypeParameterCache.entries.find { (k, v) ->
192-
// k.toConeType() == vp.returnTypeRef.coneTypeOrNull
193-
// }
194-
// println("cache conetype: $cachedTypeParameter")
195-
//
196-
// println("returnTypeRef1: $returnTypeRef")
197-
//
198-
// val stack = ArrayDeque<Any>()
199-
//
200-
// fun resolveTypeCopy() {
201-
//
202-
// }
203-
//
204-
// val type = returnTypeRef.coneTypeOrNull
205-
// if (type != null && type.typeArguments.isNotEmpty()) {
206-
// for (subArguments in type.typeArguments) {
207-
//
208-
// }
209-
// }
210-
//
211-
// returnTypeRef.accept(object : FirVisitorVoid() {
212-
// override fun visitElement(element: FirElement) {
213-
// println("visitElement($element)")
214-
// element.acceptChildren(this)
215-
// }
216-
//
217-
// override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
218-
// println("visitResolvedTypeRef(${resolvedTypeRef})")
219-
// resolvedTypeRef.type.typeArguments.forEach {
220-
// it.type?.typeArguments
221-
// }
222-
// super.visitResolvedTypeRef(resolvedTypeRef)
223-
// }
224-
//
225-
// override fun visitValueParameter(valueParameter: FirValueParameter) {
226-
// println("visitValueParameter($valueParameter)")
227-
// super.visitValueParameter(valueParameter)
228-
// }
229-
//
230-
// override fun visitTypeParameter(typeParameter: FirTypeParameter) {
231-
// println("visitTypeParameter($typeParameter)")
232-
// super.visitTypeParameter(typeParameter)
233-
// }
234-
//
235-
// override fun visitTypeParameterRef(typeParameterRef: FirTypeParameterRef) {
236-
// println("visitTypeParameterRef($typeParameterRef)")
237-
// super.visitTypeParameterRef(typeParameterRef)
238-
// }
239-
// })
240-
//
241-
// if (cachedTypeParameter != null) {
242-
// returnTypeRef = returnTypeRef.withReplacedConeType(cachedTypeParameter.value.toConeType())
243-
// }
244-
//
245-
// println("returnTypeRef2: $returnTypeRef")
246-
// symbol = FirValueParameterSymbol(vp.symbol.name)
247-
// }
248-
// }
181+
receiverParameter?.also { receiverParameter ->
182+
receiverParameter.typeRef.coneTypeOrNull
183+
?.copyWithTypeParameters(originalTypeParameterCache)
184+
?.also { foundCopied ->
185+
this.receiverParameter = buildReceiverParameterCopy(receiverParameter) {
186+
typeRef = typeRef.withReplacedConeType(foundCopied)
187+
}
188+
}
189+
}
249190

250-
// valueParameters.replaceAll { vp ->
251-
// buildValueParameterCopy(vp) {
252-
// containingFunctionSymbol = newFunSymbol
253-
// }
254-
// }
191+
192+
val coneTypeOrNull = returnTypeRef.coneTypeOrNull
193+
if (coneTypeOrNull != null) {
194+
returnTypeRef = returnTypeRef.withReplacedConeType(
195+
coneTypeOrNull
196+
.copyWithTypeParameters(originalTypeParameterCache)
197+
?: coneTypeOrNull,
198+
)
199+
}
255200

256201
annotations.clear()
257202
annotations.addAll(functionAnnotations)
258203
body = null
259204

260-
val returnType = resolveReturnType(originFunc, funData)
205+
val returnType = resolveReturnType(originFunc, funData, returnTypeRef)
261206

262207
returnTypeRef = returnType
263208

@@ -343,7 +288,8 @@ class SuspendTransformFirTransformer(
343288
)
344289
)
345290

346-
val returnType = resolveReturnType(original, funData)
291+
292+
val returnType = resolveReturnType(original, funData, original.returnTypeRef)
347293

348294
val p1 = buildProperty {
349295
symbol = pSymbol
@@ -589,8 +535,12 @@ class SuspendTransformFirTransformer(
589535
session
590536
)?.firstOrNull()
591537

592-
private fun resolveReturnType(original: FirSimpleFunction, funData: FunData): FirTypeRef {
593-
val resultConeType = resolveReturnConeType(original, funData)
538+
private fun resolveReturnType(
539+
original: FirSimpleFunction,
540+
funData: FunData,
541+
returnTypeRef: FirTypeRef
542+
): FirTypeRef {
543+
val resultConeType = resolveReturnConeType(original, funData, returnTypeRef)
594544

595545
return if (resultConeType is ConeErrorType) {
596546
buildErrorTypeRef {
@@ -604,15 +554,19 @@ class SuspendTransformFirTransformer(
604554
}
605555
}
606556

607-
private fun resolveReturnConeType(original: FirSimpleFunction, funData: FunData): ConeKotlinType {
557+
private fun resolveReturnConeType(
558+
original: FirSimpleFunction,
559+
funData: FunData,
560+
returnTypeRef: FirTypeRef
561+
): ConeKotlinType {
608562
val transformer = funData.transformer
609563
val returnType = transformer.transformReturnType
610-
?: return original.symbol.resolvedReturnType
564+
?: return returnTypeRef.coneType // OrNull // original.symbol.resolvedReturnType
611565

612566
var typeArguments: Array<ConeTypeProjection> = emptyArray()
613567

614568
if (transformer.transformReturnTypeGeneric) {
615-
typeArguments = arrayOf(ConeKotlinTypeProjectionOut(original.returnTypeRef.coneType))
569+
typeArguments = arrayOf(ConeKotlinTypeProjectionOut(returnTypeRef.coneType))
616570
}
617571

618572
val resultConeType = returnType.toClassId().createConeType(
@@ -892,6 +846,144 @@ class SuspendTransformFirTransformer(
892846

893847
private infix fun FirTypeRef?.notSameAs(otherSuper: FirTypeRef?): Boolean = !(this sameAs otherSuper)
894848

849+
850+
private fun ConeKotlinType.copyWithTypeParameters(
851+
parameters: List<CopiedTypeParameterPair>,
852+
): ConeKotlinType? {
853+
fun findCopied(target: ConeKotlinType) = parameters.find { (original, _) ->
854+
original.toConeType() == target
855+
}?.copied
856+
857+
when (this) {
858+
is ConeDynamicType -> {
859+
//println("Dynamic type: $this")
860+
}
861+
862+
is ConeFlexibleType -> {
863+
//println("Flexible type: $this")
864+
}
865+
866+
// var typeArguments: Array<ConeTypeProjection> = emptyArray()
867+
//
868+
// if (transformer.transformReturnTypeGeneric) {
869+
// typeArguments = arrayOf(ConeKotlinTypeProjectionOut(original.returnTypeRef.coneType))
870+
// }
871+
872+
is ConeClassLikeType -> {
873+
if (typeArguments.isNotEmpty()) {
874+
875+
fun mapProjection(projection: ConeTypeProjection): ConeTypeProjection? {
876+
return when (projection) {
877+
// is ConeFlexibleType -> {
878+
// }
879+
is ConeCapturedType -> {
880+
val lowerType = projection.lowerType?.let { lowerType ->
881+
findCopied(lowerType)
882+
}?.toConeType()
883+
884+
if (lowerType == null) {
885+
projection.copy(
886+
lowerType = lowerType
887+
)
888+
} else {
889+
null
890+
}
891+
}
892+
893+
is ConeDefinitelyNotNullType -> {
894+
findCopied(projection.original)
895+
?.toConeType()
896+
?.let { projection.copy(it) }
897+
}
898+
// is ConeIntegerConstantOperatorType -> TODO()
899+
// is ConeIntegerLiteralConstantType -> TODO()
900+
is ConeIntersectionType -> {
901+
val upperBoundForApproximation =
902+
projection.upperBoundForApproximation
903+
?.let { findCopied(it) }
904+
?.toConeType()
905+
906+
var anyIntersectedTypes = false
907+
908+
val intersectedTypes = projection.intersectedTypes.map { ktype ->
909+
findCopied(ktype)
910+
?.toConeType()
911+
?.also { anyIntersectedTypes = true }
912+
?: ktype
913+
}
914+
915+
if (upperBoundForApproximation != null || anyIntersectedTypes) {
916+
ConeIntersectionType(
917+
intersectedTypes,
918+
upperBoundForApproximation
919+
)
920+
} else {
921+
null
922+
}
923+
}
924+
// is ConeLookupTagBasedType -> TODO()
925+
// is ConeStubTypeForTypeVariableInSubtyping -> TODO()
926+
// is ConeTypeVariableType -> {
927+
// TODO()
928+
// }
929+
is ConeKotlinTypeConflictingProjection -> {
930+
findCopied(projection.type)
931+
?.toConeType()
932+
?.let { projection.copy(it) }
933+
}
934+
935+
is ConeKotlinTypeProjectionIn -> {
936+
findCopied(projection.type)
937+
?.toConeType()
938+
?.let { projection.copy(it) }
939+
}
940+
941+
is ConeKotlinTypeProjectionOut -> {
942+
findCopied(projection.type)
943+
?.toConeType()
944+
?.let { projection.copy(it) }
945+
}
946+
947+
is ConeTypeParameterType -> {
948+
findCopied(projection)?.toConeType()
949+
}
950+
951+
ConeStarProjection -> projection
952+
// Other unknowns
953+
else -> null
954+
}
955+
}
956+
957+
val typeArguments: Array<ConeTypeProjection> = typeArguments.map { projection ->
958+
mapProjection(projection) ?: projection
959+
}.toTypedArray()
960+
961+
return classId?.createConeType(
962+
session = session,
963+
typeArguments = typeArguments,
964+
nullable = isNullable
965+
)
966+
// typeArguments.forEach { projection ->
967+
// projection.type?.copyWithTypeParameters(parameters)
968+
// }
969+
}
970+
971+
return null
972+
}
973+
974+
is ConeTypeParameterType -> {
975+
return parameters.find { (original, _) ->
976+
original.toConeType() == this
977+
}?.copied?.toConeType() ?: this
978+
}
979+
980+
else -> {
981+
982+
}
983+
}
984+
return this
985+
// this.fullyExpandedClassId().createConeType()
986+
}
895987
}
896988

897989

@@ -912,3 +1004,4 @@ private val FirSimpleFunction.syntheticModifier: Modality?
9121004
modality == Modality.ABSTRACT -> Modality.OPEN
9131005
else -> status.modality
9141006
}
1007+

compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.asm.txt

-2
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,6 @@ public final class FooInterface3Impl : java/lang/Object, FooInterface3 {
293293

294294
public Bar data2Blocking(java.lang.Object value)
295295

296-
public Bar data2Blocking(java.lang.Object value)
297-
298296
public Foo data2Blocking(java.lang.Object value)
299297

300298
public java.lang.Object data3(int $this$data3, kotlin.coroutines.Continuation $completion)

0 commit comments

Comments
 (0)