Skip to content

Commit 3091224

Browse files
authored
Merge pull request #597 from Kotlin/nullable-properties-fix/0
generate "nullable properties" only where needed
2 parents 341365f + fe65715 commit 3091224

File tree

6 files changed

+150
-180
lines changed

6 files changed

+150
-180
lines changed

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/codeGen/CodeGeneratorImpl.kt

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,26 @@ internal open class ExtensionsCodeGeneratorImpl(
249249
return "${visibility}val$typeParameters $typeName.$name: $propertyType @JvmName(\"${renderStringLiteral(jvmName)}\") get() = $getter as $propertyType"
250250
}
251251

252-
protected fun generateExtensionProperties(marker: IsolatedMarker): Code {
252+
/**
253+
* nullable properties can be needed when *DECLARED* schema is referenced with nullability:
254+
* ```
255+
* @DataSchema
256+
* data class Schema(val i: Int)
257+
*
258+
* @DataSchema
259+
* data class A(
260+
* val prop: Schema?
261+
* )
262+
* ```
263+
* When converted `listOf<A>().toDataFrame(maxDepth=2)` actual schema is
264+
* ```
265+
* prop:
266+
* i: Int?
267+
* ```
268+
* So this sudden `i: Int?` must be somehow handled.
269+
* However, REPL code generator will not create such a situation. Nullable properties are not needed then
270+
*/
271+
protected fun generateExtensionProperties(marker: IsolatedMarker, withNullable: Boolean = true): Code {
253272
val markerName = marker.name
254273
val markerType = "$markerName${marker.typeArguments}"
255274
val visibility = renderTopLevelDeclarationVisibility(marker)
@@ -278,7 +297,6 @@ internal open class ExtensionsCodeGeneratorImpl(
278297

279298
declarations.addAll(
280299
listOf(
281-
// non nullable
282300
generatePropertyCode(
283301
marker = marker,
284302
shortMarkerName = shortMarkerName,
@@ -296,29 +314,33 @@ internal open class ExtensionsCodeGeneratorImpl(
296314
propertyType = fieldType,
297315
getter = getter,
298316
visibility = visibility,
299-
),
300-
301-
// nullable
302-
generatePropertyCode(
303-
marker = marker,
304-
shortMarkerName = nullableShortMarkerName,
305-
typeName = nullableDfTypename,
306-
name = name.quotedIfNeeded,
307-
propertyType = nullableColumnType,
308-
getter = getter,
309-
visibility = visibility,
310-
),
311-
generatePropertyCode(
312-
marker = marker,
313-
shortMarkerName = nullableShortMarkerName,
314-
typeName = nullableRowTypename,
315-
name = name.quotedIfNeeded,
316-
propertyType = nullableFieldType,
317-
getter = getter,
318-
visibility = visibility,
319-
),
317+
)
320318
)
321319
)
320+
if (withNullable) {
321+
declarations.addAll(
322+
listOf(
323+
generatePropertyCode(
324+
marker = marker,
325+
shortMarkerName = nullableShortMarkerName,
326+
typeName = nullableDfTypename,
327+
name = name.quotedIfNeeded,
328+
propertyType = nullableColumnType,
329+
getter = getter,
330+
visibility = visibility,
331+
),
332+
generatePropertyCode(
333+
marker = marker,
334+
shortMarkerName = nullableShortMarkerName,
335+
typeName = nullableRowTypename,
336+
name = name.quotedIfNeeded,
337+
propertyType = nullableFieldType,
338+
getter = getter,
339+
visibility = visibility,
340+
)
341+
)
342+
)
343+
}
322344
}
323345
return declarations.joinToString("\n")
324346
}
@@ -421,7 +443,7 @@ internal class CodeGeneratorImpl(typeRendering: TypeRenderingStrategy = FullyQua
421443
context.generatedMarkers.forEach { itMarker ->
422444
declarations.add(generateInterface(itMarker, fields, readDfMethod.takeIf { marker == itMarker }))
423445
if (extensionProperties) {
424-
declarations.add(generateExtensionProperties(itMarker))
446+
declarations.add(generateExtensionProperties(itMarker, withNullable = false))
425447
}
426448
}
427449
val code = createCodeWithConverter(declarations.joinToString("\n\n"), marker.name)

0 commit comments

Comments
 (0)