Skip to content

Commit 2d31cd6

Browse files
committed
[Compiler plugin] fillNulls { }.with { }
`with` used to have C? in UpdateExpression return type position, and so it was always inferred as nullable. Even for fillNulls { }.with { 123 }
1 parent 874abff commit 2d31cd6

File tree

6 files changed

+55
-1
lines changed

6 files changed

+55
-1
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ private interface CommonFillNullsFunctionDoc
6969
* @include [SelectingColumns.Dsl.WithExample] {@include [SetFillNullsOperationArg]}
7070
* @include [Update.DslParam]
7171
*/
72+
@Interpretable("FillNulls0")
7273
public fun <T, C> DataFrame<T>.fillNulls(columns: ColumnsSelector<T, C?>): Update<T, C?> =
7374
update(columns).where { it == null }
7475

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import org.jetbrains.kotlinx.dataframe.DataFrameExpression
88
import org.jetbrains.kotlinx.dataframe.DataRow
99
import org.jetbrains.kotlinx.dataframe.RowColumnExpression
1010
import org.jetbrains.kotlinx.dataframe.RowValueFilter
11+
import org.jetbrains.kotlinx.dataframe.annotations.Interpretable
12+
import org.jetbrains.kotlinx.dataframe.annotations.Refine
1113
import org.jetbrains.kotlinx.dataframe.api.Update.Grammar
1214
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
1315
import org.jetbrains.kotlinx.dataframe.columns.ColumnReference
@@ -273,7 +275,9 @@ public typealias UpdateExpression<T, C, R> = AddDataRow<T>.(C) -> R
273275
* - {@include [SeeAlsoPerRowCol]}
274276
* @param [expression] The {@include [ExpressionsGivenRow.RowValueExpressionLink]} to update the rows with.
275277
*/
276-
public fun <T, C> Update<T, C>.with(expression: UpdateExpression<T, C, C?>): DataFrame<T> =
278+
@Refine
279+
@Interpretable("UpdateWith0")
280+
public fun <T, C, R : C?> Update<T, C>.with(expression: UpdateExpression<T, C, R>): DataFrame<T> =
277281
updateImpl { row, _, value ->
278282
expression(row, value)
279283
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.jetbrains.kotlinx.dataframe.plugin.impl.api
2+
3+
import org.jetbrains.kotlinx.dataframe.plugin.impl.AbstractInterpreter
4+
import org.jetbrains.kotlinx.dataframe.plugin.impl.AbstractSchemaModificationInterpreter
5+
import org.jetbrains.kotlinx.dataframe.plugin.impl.Arguments
6+
import org.jetbrains.kotlinx.dataframe.plugin.impl.PluginDataFrameSchema
7+
import org.jetbrains.kotlinx.dataframe.plugin.impl.dataFrame
8+
import org.jetbrains.kotlinx.dataframe.plugin.impl.type
9+
10+
class FillNulls0 : AbstractInterpreter<FillNullsApproximation>() {
11+
val Arguments.receiver: PluginDataFrameSchema by dataFrame()
12+
val Arguments.columns: ColumnsResolver by arg()
13+
14+
override fun Arguments.interpret(): FillNullsApproximation {
15+
return FillNullsApproximation(receiver, columns)
16+
}
17+
}
18+
19+
class FillNullsApproximation(val schema: PluginDataFrameSchema, val columns: ColumnsResolver)
20+
21+
class UpdateWith0 : AbstractSchemaModificationInterpreter() {
22+
val Arguments.receiver: FillNullsApproximation by arg()
23+
val Arguments.expression: TypeApproximation by type()
24+
25+
override fun Arguments.interpret(): PluginDataFrameSchema {
26+
return convertImpl(receiver.schema, receiver.columns.resolve(receiver.schema).map { it.path.path }, expression)
27+
}
28+
}

plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/loadInterpreter.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ColsOf0
7373
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ColsOf1
7474
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.DataFrameBuilderInvoke0
7575
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.DataFrameOf0
76+
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.FillNulls0
7677
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.FrameCols0
7778
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ReadExcel
7879
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToDataFrame
7980
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToDataFrameColumn
8081
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToDataFrameDefault
8182
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToDataFrameDsl
8283
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToDataFrameFrom
84+
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.UpdateWith0
8385

8486
internal fun FirFunctionCall.loadInterpreter(session: FirSession): Interpreter<*>? {
8587
val symbol =
@@ -186,6 +188,8 @@ internal inline fun <reified T> String.load(): T {
186188
"ToDataFrameColumn" -> ToDataFrameColumn()
187189
"StringColumns" -> ToDataFrameColumn()
188190
"ReadExcel" -> ReadExcel()
191+
"FillNulls0" -> FillNulls0()
192+
"UpdateWith0" -> UpdateWith0()
189193
else -> error("$this")
190194
} as T
191195
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import org.jetbrains.kotlinx.dataframe.*
2+
import org.jetbrains.kotlinx.dataframe.annotations.*
3+
import org.jetbrains.kotlinx.dataframe.api.*
4+
import org.jetbrains.kotlinx.dataframe.io.*
5+
6+
fun box(): String {
7+
val df = dataFrameOf("a", "b")(1, null, null, "")
8+
val df1 = df.fillNulls { b }.with { "empty" }
9+
val b: DataColumn<String> = df1.b
10+
return "OK"
11+
}

plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameBlackBoxCodegenTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ public void testExtractPluginSchemaWithUnfold() {
136136
runTest("testData/box/extractPluginSchemaWithUnfold.kt");
137137
}
138138

139+
@Test
140+
@TestMetadata("fillNulls.kt")
141+
public void testFillNulls() {
142+
runTest("testData/box/fillNulls.kt");
143+
}
144+
139145
@Test
140146
@TestMetadata("flexibleReturnType.kt")
141147
public void testFlexibleReturnType() {

0 commit comments

Comments
 (0)