@@ -37,7 +37,7 @@ import kotlin.reflect.jvm.isAccessible
37
37
import kotlin.reflect.jvm.javaField
38
38
import kotlin.reflect.typeOf
39
39
40
- internal val valueTypes = setOf (
40
+ private val valueTypes = setOf (
41
41
String ::class ,
42
42
Boolean ::class ,
43
43
kotlin.time.Duration ::class ,
@@ -186,21 +186,21 @@ internal fun convertToDataFrame(
186
186
class ValueClassConverter (val unbox : Method , val box : Method )
187
187
188
188
val valueClassConverter = (it.returnType.classifier as ? KClass <* >)?.let { kClass ->
189
- if (! kClass.isValue) null else {
190
- val constructor = requireNotNull(kClass.primaryConstructor) {
191
- " value class $kClass is expected to have primary constructor, but couldn't obtain it"
192
- }
193
- val parameter = constructor .parameters.singleOrNull()
194
- ? : error(" conversion of value class $kClass with multiple parameters in constructor is not yet supported" )
195
- // there's no need to unwrap if underlying field is nullable
196
- if (parameter.type.isMarkedNullable) return @let null
197
- // box and unbox impl methods are part of binary API of value classes
198
- // https://youtrack.jetbrains.com/issue/KT-50518/Boxing-Unboxing-methods-for-JvmInline-value-classes-should-be-public-accessible
199
- val unbox = kClass.java.getMethod(" unbox-impl" )
200
- val box = kClass.java.methods.single { it.name == " box-impl" }
201
- val valueClassConverter = ValueClassConverter (unbox, box)
202
- valueClassConverter
189
+ if (! kClass.isValue) return @let null
190
+
191
+ val constructor = requireNotNull(kClass.primaryConstructor) {
192
+ " value class $kClass is expected to have primary constructor, but couldn't obtain it"
203
193
}
194
+ val parameter = constructor .parameters.singleOrNull()
195
+ ? : error(" conversion of value class $kClass with multiple parameters in constructor is not yet supported" )
196
+ // there's no need to unwrap if underlying field is nullable
197
+ if (parameter.type.isMarkedNullable) return @let null
198
+ // box and unbox impl methods are part of binary API of value classes
199
+ // https://youtrack.jetbrains.com/issue/KT-50518/Boxing-Unboxing-methods-for-JvmInline-value-classes-should-be-public-accessible
200
+ val unbox = kClass.java.getMethod(" unbox-impl" )
201
+ val box = kClass.java.methods.single { it.name == " box-impl" }
202
+ val valueClassConverter = ValueClassConverter (unbox, box)
203
+ valueClassConverter
204
204
}
205
205
(property as ? KProperty <* >)?.javaField?.isAccessible = true
206
206
property.isAccessible = true
@@ -245,84 +245,99 @@ internal fun convertToDataFrame(
245
245
typeOf<Any >()
246
246
}
247
247
}
248
- val kclass = (returnType.classifier as KClass <* >)
248
+ val kClass = returnType.classifier as KClass <* >
249
+
250
+ val shouldCreateValueCol = (
251
+ maxDepth <= 0 &&
252
+ ! returnType.shouldBeConvertedToFrameColumn() &&
253
+ ! returnType.shouldBeConvertedToColumnGroup()
254
+ ) ||
255
+ kClass == Any ::class ||
256
+ kClass in preserveClasses ||
257
+ property in preserveProperties ||
258
+ kClass.isValueType
259
+
260
+ val shouldCreateFrameCol = kClass == DataFrame ::class && ! nullable
261
+ val shouldCreateColumnGroup = kClass == DataRow ::class
262
+
249
263
when {
250
264
hasExceptions -> DataColumn .createWithTypeInference(it.columnName, values, nullable)
251
265
252
- kclass == Any ::class ||
253
- preserveClasses.contains(kclass) ||
254
- preserveProperties.contains(property) ||
255
- (maxDepth <= 0 && ! returnType.shouldBeConvertedToFrameColumn() && ! returnType.shouldBeConvertedToColumnGroup()) ||
256
- kclass.isValueType ->
266
+ shouldCreateValueCol ->
257
267
DataColumn .createValueColumn(
258
268
name = it.columnName,
259
269
values = values,
260
270
type = returnType.withNullability(nullable),
261
271
)
262
272
263
- kclass == DataFrame :: class && ! nullable ->
273
+ shouldCreateFrameCol ->
264
274
DataColumn .createFrameColumn(
265
275
name = it.columnName,
266
276
groups = values as List <AnyFrame >
267
277
)
268
278
269
- kclass == DataRow :: class ->
279
+ shouldCreateColumnGroup ->
270
280
DataColumn .createColumnGroup(
271
281
name = it.columnName,
272
282
df = (values as List <AnyRow >).concat(),
273
283
)
274
284
275
- kclass.isSubclassOf(Iterable ::class ) -> {
276
- val elementType = returnType.projectUpTo(Iterable ::class ).arguments.firstOrNull()?.type
277
- if (elementType == null ) {
278
- DataColumn .createValueColumn(it.columnName, values, returnType.withNullability(nullable))
279
- } else {
280
- val elementClass = (elementType.classifier as ? KClass <* >)
281
-
282
- when {
283
- elementClass == null -> {
284
- val listValues = values.map {
285
- (it as ? Iterable <* >)?.asList()
286
- }
285
+ kClass.isSubclassOf(Iterable ::class ) ->
286
+ when (val elementType = returnType.projectUpTo(Iterable ::class ).arguments.firstOrNull()?.type) {
287
+ null ->
288
+ DataColumn .createValueColumn(
289
+ name = it.columnName,
290
+ values = values,
291
+ type = returnType.withNullability(nullable),
292
+ )
293
+
294
+ else -> {
295
+ val elementClass = elementType.classifier as ? KClass <* >
296
+ when {
297
+ elementClass == null -> {
298
+ val listValues = values.map {
299
+ (it as ? Iterable <* >)?.asList()
300
+ }
287
301
288
- DataColumn .createWithTypeInference(it.columnName, listValues)
289
- }
302
+ DataColumn .createWithTypeInference(it.columnName, listValues)
303
+ }
290
304
291
- elementClass.isValueType -> {
292
- val listType = getListType(elementType).withNullability(nullable)
293
- val listValues = values.map {
294
- (it as ? Iterable <* >)?.asList()
305
+ elementClass.isValueType -> {
306
+ val listType = getListType(elementType).withNullability(nullable)
307
+ val listValues = values.map {
308
+ (it as ? Iterable <* >)?.asList()
309
+ }
310
+ DataColumn .createValueColumn(it.columnName, listValues, listType)
295
311
}
296
- DataColumn .createValueColumn(it.columnName, listValues, listType)
297
- }
298
312
299
- else -> {
300
- val frames = values.map {
301
- if (it == null ) {
302
- DataFrame .empty()
303
- } else {
304
- require(it is Iterable <* >)
305
- convertToDataFrame(
306
- data = it,
307
- clazz = elementClass,
308
- roots = emptyList(),
309
- excludes = excludes,
310
- preserveClasses = preserveClasses,
311
- preserveProperties = preserveProperties,
312
- maxDepth = maxDepth - 1 ,
313
- )
313
+ else -> {
314
+ val frames = values.map {
315
+ if (it == null ) {
316
+ DataFrame .empty()
317
+ } else {
318
+ require(it is Iterable <* >)
319
+ convertToDataFrame(
320
+ data = it,
321
+ clazz = elementClass,
322
+ roots = emptyList(),
323
+ excludes = excludes,
324
+ preserveClasses = preserveClasses,
325
+ preserveProperties = preserveProperties,
326
+ maxDepth = maxDepth - 1 ,
327
+ )
328
+ }
314
329
}
330
+ DataColumn .createFrameColumn(it.columnName, frames)
315
331
}
316
- DataColumn .createFrameColumn(it.columnName, frames)
317
332
}
318
333
}
319
334
}
320
- }
335
+
321
336
322
337
else -> {
323
338
val df = convertToDataFrame(
324
339
data = values,
325
- clazz = kclass ,
340
+ clazz = kClass ,
326
341
roots = emptyList(),
327
342
excludes = excludes,
328
343
preserveClasses = preserveClasses,
0 commit comments