@@ -55,6 +55,10 @@ import org.jetbrains.kotlin.platform.konan.isNative
55
55
import org.jetbrains.kotlin.types.ConstantValueKind
56
56
import java.util.concurrent.ConcurrentHashMap
57
57
58
+ private data class CopiedTypeParameterPair (
59
+ val original : FirTypeParameter ,
60
+ val copied : FirTypeParameter
61
+ )
58
62
59
63
/* *
60
64
*
@@ -150,114 +154,55 @@ class SuspendTransformFirTransformer(
150
154
// The error: Duplicate IR node
151
155
// [IR VALIDATION] JvmIrValidationBeforeLoweringPhase: Duplicate IR node: TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false of FUN GENERATED[...]
152
156
// 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
157
161
// 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
+ }
164
167
165
- // TODO
166
168
valueParameters.replaceAll { vp ->
167
169
buildValueParameterCopy(vp) {
168
170
symbol = FirValueParameterSymbol (vp.symbol.name)
169
171
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)
180
174
181
- returnTypeRef
175
+ if (copiedConeType != null ) {
176
+ returnTypeRef = returnTypeRef.withReplacedConeType(copiedConeType)
182
177
}
183
-
184
- returnTypeRef = newReturnTypeRef
185
178
}
186
179
}
187
180
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
+ }
249
190
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
+ }
255
200
256
201
annotations.clear()
257
202
annotations.addAll(functionAnnotations)
258
203
body = null
259
204
260
- val returnType = resolveReturnType(originFunc, funData)
205
+ val returnType = resolveReturnType(originFunc, funData, returnTypeRef )
261
206
262
207
returnTypeRef = returnType
263
208
@@ -343,7 +288,8 @@ class SuspendTransformFirTransformer(
343
288
)
344
289
)
345
290
346
- val returnType = resolveReturnType(original, funData)
291
+
292
+ val returnType = resolveReturnType(original, funData, original.returnTypeRef)
347
293
348
294
val p1 = buildProperty {
349
295
symbol = pSymbol
@@ -589,8 +535,12 @@ class SuspendTransformFirTransformer(
589
535
session
590
536
)?.firstOrNull()
591
537
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)
594
544
595
545
return if (resultConeType is ConeErrorType ) {
596
546
buildErrorTypeRef {
@@ -604,15 +554,19 @@ class SuspendTransformFirTransformer(
604
554
}
605
555
}
606
556
607
- private fun resolveReturnConeType (original : FirSimpleFunction , funData : FunData ): ConeKotlinType {
557
+ private fun resolveReturnConeType (
558
+ original : FirSimpleFunction ,
559
+ funData : FunData ,
560
+ returnTypeRef : FirTypeRef
561
+ ): ConeKotlinType {
608
562
val transformer = funData.transformer
609
563
val returnType = transformer.transformReturnType
610
- ? : return original.symbol.resolvedReturnType
564
+ ? : return returnTypeRef.coneType // OrNull // original.symbol.resolvedReturnType
611
565
612
566
var typeArguments: Array <ConeTypeProjection > = emptyArray()
613
567
614
568
if (transformer.transformReturnTypeGeneric) {
615
- typeArguments = arrayOf(ConeKotlinTypeProjectionOut (original. returnTypeRef.coneType))
569
+ typeArguments = arrayOf(ConeKotlinTypeProjectionOut (returnTypeRef.coneType))
616
570
}
617
571
618
572
val resultConeType = returnType.toClassId().createConeType(
@@ -892,6 +846,144 @@ class SuspendTransformFirTransformer(
892
846
893
847
private infix fun FirTypeRef?.notSameAs (otherSuper : FirTypeRef ? ): Boolean = ! (this sameAs otherSuper)
894
848
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
+ }
895
987
}
896
988
897
989
@@ -912,3 +1004,4 @@ private val FirSimpleFunction.syntheticModifier: Modality?
912
1004
modality == Modality .ABSTRACT -> Modality .OPEN
913
1005
else -> status.modality
914
1006
}
1007
+
0 commit comments