@@ -55,6 +55,10 @@ import org.jetbrains.kotlin.platform.konan.isNative
5555import org.jetbrains.kotlin.types.ConstantValueKind
5656import 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+
0 commit comments