@@ -25,9 +25,12 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
25
25
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
26
26
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
27
27
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
28
+ import org.jetbrains.kotlin.fir.types.ConeFlexibleType
28
29
import org.jetbrains.kotlin.fir.types.ConeKotlinType
30
+ import org.jetbrains.kotlin.fir.types.ConeNullability
29
31
import org.jetbrains.kotlin.fir.types.ConeStarProjection
30
32
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
33
+ import org.jetbrains.kotlin.fir.types.ConeTypeProjection
31
34
import org.jetbrains.kotlin.fir.types.canBeNull
32
35
import org.jetbrains.kotlin.fir.types.classId
33
36
import org.jetbrains.kotlin.fir.types.coneType
@@ -41,15 +44,18 @@ import org.jetbrains.kotlin.fir.types.resolvedType
41
44
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
42
45
import org.jetbrains.kotlin.fir.types.toSymbol
43
46
import org.jetbrains.kotlin.fir.types.type
47
+ import org.jetbrains.kotlin.fir.types.typeContext
44
48
import org.jetbrains.kotlin.fir.types.upperBoundIfFlexible
45
49
import org.jetbrains.kotlin.fir.types.withArguments
50
+ import org.jetbrains.kotlin.fir.types.withNullability
46
51
import org.jetbrains.kotlin.name.ClassId
47
52
import org.jetbrains.kotlin.name.FqName
48
53
import org.jetbrains.kotlin.name.Name
49
54
import org.jetbrains.kotlin.name.StandardClassIds
50
55
import org.jetbrains.kotlin.name.StandardClassIds.List
51
56
import org.jetbrains.kotlinx.dataframe.codeGen.*
52
57
import org.jetbrains.kotlinx.dataframe.plugin.extensions.KotlinTypeFacade
58
+ import org.jetbrains.kotlinx.dataframe.plugin.extensions.wrap
53
59
import org.jetbrains.kotlinx.dataframe.plugin.impl.AbstractInterpreter
54
60
import org.jetbrains.kotlinx.dataframe.plugin.impl.AbstractSchemaModificationInterpreter
55
61
import org.jetbrains.kotlinx.dataframe.plugin.impl.Arguments
@@ -71,27 +77,31 @@ import java.util.*
71
77
class ToDataFrameDsl : AbstractSchemaModificationInterpreter () {
72
78
val Arguments .receiver: FirExpression ? by arg(lens = Interpreter .Id )
73
79
val Arguments .body by dsl()
80
+ val Arguments .typeArg0: ConeTypeProjection ? by arg(lens = Interpreter .Id )
81
+
74
82
override fun Arguments.interpret (): PluginDataFrameSchema {
75
83
val dsl = CreateDataFrameDslImplApproximation ()
76
- body(dsl, mapOf (" explicitReceiver " to Interpreter .Success (receiver )))
84
+ body(dsl, mapOf (" typeArg0 " to Interpreter .Success (typeArg0 )))
77
85
return PluginDataFrameSchema (dsl.columns)
78
86
}
79
87
}
80
88
81
89
class ToDataFrame : AbstractSchemaModificationInterpreter () {
82
90
val Arguments .receiver: FirExpression ? by arg(lens = Interpreter .Id )
83
91
val Arguments .maxDepth: Number by arg(defaultValue = Present (DEFAULT_MAX_DEPTH ))
92
+ val Arguments .typeArg0: ConeTypeProjection by arg(lens = Interpreter .Id )
84
93
85
94
override fun Arguments.interpret (): PluginDataFrameSchema {
86
- return toDataFrame(maxDepth.toInt(), receiver , TraverseConfiguration ())
95
+ return toDataFrame(maxDepth.toInt(), typeArg0 , TraverseConfiguration ())
87
96
}
88
97
}
89
98
90
99
class ToDataFrameDefault : AbstractSchemaModificationInterpreter () {
91
100
val Arguments .receiver: FirExpression ? by arg(lens = Interpreter .Id )
101
+ val Arguments .typeArg0: ConeTypeProjection by arg(lens = Interpreter .Id )
92
102
93
103
override fun Arguments.interpret (): PluginDataFrameSchema {
94
- return toDataFrame(DEFAULT_MAX_DEPTH , receiver , TraverseConfiguration ())
104
+ return toDataFrame(DEFAULT_MAX_DEPTH , typeArg0 , TraverseConfiguration ())
95
105
}
96
106
}
97
107
@@ -109,14 +119,14 @@ private const val DEFAULT_MAX_DEPTH = 0
109
119
110
120
class Properties0 : AbstractInterpreter <Unit >() {
111
121
val Arguments .dsl: CreateDataFrameDslImplApproximation by arg()
112
- val Arguments .explicitReceiver: FirExpression ? by arg()
113
122
val Arguments .maxDepth: Int by arg()
114
123
val Arguments .body by dsl()
124
+ val Arguments .typeArg0: ConeTypeProjection by arg(lens = Interpreter .Id )
115
125
116
126
override fun Arguments.interpret () {
117
127
dsl.configuration.maxDepth = maxDepth
118
128
body(dsl.configuration.traverseConfiguration, emptyMap())
119
- val schema = toDataFrame(dsl.configuration.maxDepth, explicitReceiver , dsl.configuration.traverseConfiguration)
129
+ val schema = toDataFrame(dsl.configuration.maxDepth, typeArg0 , dsl.configuration.traverseConfiguration)
120
130
dsl.columns.addAll(schema.columns())
121
131
}
122
132
}
@@ -172,8 +182,8 @@ class Exclude1 : AbstractInterpreter<Unit>() {
172
182
@OptIn(SymbolInternals ::class )
173
183
internal fun KotlinTypeFacade.toDataFrame (
174
184
maxDepth : Int ,
175
- explicitReceiver : FirExpression ? ,
176
- traverseConfiguration : TraverseConfiguration
185
+ arg : ConeTypeProjection ,
186
+ traverseConfiguration : TraverseConfiguration ,
177
187
): PluginDataFrameSchema {
178
188
fun ConeKotlinType.isValueType () =
179
189
this .isArrayTypeOrNullableArrayType ||
@@ -197,7 +207,7 @@ internal fun KotlinTypeFacade.toDataFrame(
197
207
val preserveClasses = traverseConfiguration.preserveClasses.mapNotNullTo(mutableSetOf ()) { it.classId }
198
208
val preserveProperties = traverseConfiguration.preserveProperties.mapNotNullTo(mutableSetOf ()) { it.calleeReference.toResolvedPropertySymbol() }
199
209
200
- fun convert (classLike : ConeKotlinType , depth : Int ): List <SimpleCol > {
210
+ fun convert (classLike : ConeKotlinType , depth : Int , makeNullable : Boolean ): List <SimpleCol > {
201
211
val symbol = classLike.toRegularClassSymbol(session) ? : return emptyList()
202
212
val scope = symbol.unsubstitutedScope(session, ScopeSession (), false , FirResolvePhase .STATUS )
203
213
val declarations = if (symbol.fir is FirJavaClass ) {
@@ -260,7 +270,7 @@ internal fun KotlinTypeFacade.toDataFrame(
260
270
261
271
val keepSubtree = depth >= maxDepth && ! fieldKind.shouldBeConvertedToColumnGroup && ! fieldKind.shouldBeConvertedToFrameColumn
262
272
if (keepSubtree || returnType.isValueType() || returnType.classId in preserveClasses || it in preserveProperties) {
263
- SimpleDataColumn (name, TypeApproximation (returnType))
273
+ SimpleDataColumn (name, TypeApproximation (returnType.withNullability( ConeNullability .create(makeNullable), session.typeContext) ))
264
274
} else if (
265
275
returnType.isSubtypeOf(StandardClassIds .Iterable .constructClassLikeType(arrayOf(ConeStarProjection )), session) ||
266
276
returnType.isSubtypeOf(StandardClassIds .Iterable .constructClassLikeType(arrayOf(ConeStarProjection ), isNullable = true ), session)
@@ -271,30 +281,28 @@ internal fun KotlinTypeFacade.toDataFrame(
271
281
else -> session.builtinTypes.nullableAnyType.type
272
282
}
273
283
if (type.isValueType()) {
274
- SimpleDataColumn (name,
275
- TypeApproximation (
276
- List .constructClassLikeType(
277
- arrayOf(type),
278
- returnType.isNullable
279
- )
280
- )
281
- )
284
+ val columnType = List .constructClassLikeType(arrayOf(type), returnType.isNullable)
285
+ .withNullability(ConeNullability .create(makeNullable), session.typeContext)
286
+ .wrap()
287
+ SimpleDataColumn (name, columnType)
282
288
} else {
283
- SimpleFrameColumn (name, convert(type, depth + 1 ))
289
+ SimpleFrameColumn (name, convert(type, depth + 1 , makeNullable = false ))
284
290
}
285
291
} else {
286
- SimpleColumnGroup (name, convert(returnType, depth + 1 ))
292
+ SimpleColumnGroup (name, convert(returnType, depth + 1 , returnType.isNullable || makeNullable ))
287
293
}
288
294
}
289
295
}
290
296
291
- val receiver = explicitReceiver ? : return PluginDataFrameSchema .EMPTY
292
- val arg = receiver.resolvedType.typeArguments.firstOrNull() ? : return PluginDataFrameSchema .EMPTY
293
297
return when {
294
298
arg.isStarProjection -> PluginDataFrameSchema .EMPTY
295
299
else -> {
296
- val classLike = arg.type as ? ConeClassLikeType ? : return PluginDataFrameSchema .EMPTY
297
- val columns = convert(classLike, 0 )
300
+ val classLike = when (val type = arg.type) {
301
+ is ConeClassLikeType -> type
302
+ is ConeFlexibleType -> type.upperBound
303
+ else -> null
304
+ } ? : return PluginDataFrameSchema .EMPTY
305
+ val columns = convert(classLike, 0 , makeNullable = classLike.isNullable)
298
306
PluginDataFrameSchema (columns)
299
307
}
300
308
}
0 commit comments