Skip to content

Commit 0305d65

Browse files
committed
[Compiler plugin] Setup call transformer pipeline to handle (...) -> DataRow functions
1 parent b3b1f64 commit 0305d65

File tree

7 files changed

+44
-7
lines changed

7 files changed

+44
-7
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/json.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ public fun DataFrame.Companion.readJsonStr(
269269
* @param header Optional list of column names. If given, [text] will be read like an object with [header] being the keys.
270270
* @return [DataRow] from the given [text].
271271
*/
272+
@Refine
273+
@Interpretable("DataRowReadJsonStr")
272274
public fun DataRow.Companion.readJsonStr(
273275
@Language("json") text: String,
274276
header: List<String> = emptyList(),

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class FunctionCallTransformer(
106106
fun transformOrNull(call: FirFunctionCall, originalSymbol: FirNamedFunctionSymbol): FirFunctionCall?
107107
}
108108

109-
private val transformers = listOf(GroupByCallTransformer(), DataFrameCallTransformer())
109+
private val transformers = listOf(GroupByCallTransformer(), DataFrameCallTransformer(), DataRowCallTransformer())
110110

111111
override fun intercept(callInfo: CallInfo, symbol: FirNamedFunctionSymbol): CallReturnType? {
112112
val callSiteAnnotations = (callInfo.callSite as? FirAnnotationContainer)?.annotations ?: emptyList()
@@ -156,14 +156,14 @@ class FunctionCallTransformer(
156156
?: call
157157
}
158158

159-
inner class DataFrameCallTransformer : CallTransformer {
159+
inner class DataSchemaLikeCallTransformer(val classId: ClassId) : CallTransformer {
160160
override fun interceptOrNull(callInfo: CallInfo, symbol: FirNamedFunctionSymbol, hash: String): CallReturnType? {
161-
if (symbol.resolvedReturnType.fullyExpandedClassId(session) != Names.DF_CLASS_ID) return null
162-
// possibly null if explicit receiver type is AnyFrame
161+
if (symbol.resolvedReturnType.fullyExpandedClassId(session) != classId) return null
162+
// possibly null if explicit receiver type is typealias
163163
val argument = (callInfo.explicitReceiver?.resolvedType)?.typeArguments?.getOrNull(0)
164164
val newDataFrameArgument = buildNewTypeArgument(argument, callInfo.name, hash)
165165

166-
val lookupTag = ConeClassLikeLookupTagImpl(Names.DF_CLASS_ID)
166+
val lookupTag = ConeClassLikeLookupTagImpl(classId)
167167
val typeRef = buildResolvedTypeRef {
168168
type = ConeClassLikeTypeImpl(
169169
lookupTag,
@@ -182,7 +182,7 @@ class FunctionCallTransformer(
182182

183183
@OptIn(SymbolInternals::class)
184184
override fun transformOrNull(call: FirFunctionCall, originalSymbol: FirNamedFunctionSymbol): FirFunctionCall? {
185-
val callResult = analyzeRefinedCallShape<PluginDataFrameSchema>(call, Names.DF_CLASS_ID, InterpretationErrorReporter.DEFAULT)
185+
val callResult = analyzeRefinedCallShape<PluginDataFrameSchema>(call, classId, InterpretationErrorReporter.DEFAULT)
186186
val (tokens, dataFrameSchema) = callResult ?: return null
187187
val token = tokens[0]
188188
val firstSchema = token.toClassSymbol(session)?.resolvedSuperTypes?.get(0)!!.toRegularClassSymbol(session)?.fir!!
@@ -195,6 +195,10 @@ class FunctionCallTransformer(
195195
}
196196
}
197197

198+
inner class DataFrameCallTransformer : CallTransformer by DataSchemaLikeCallTransformer(Names.DF_CLASS_ID)
199+
200+
inner class DataRowCallTransformer : CallTransformer by DataSchemaLikeCallTransformer(Names.DATA_ROW_CLASS_ID)
201+
198202
inner class GroupByCallTransformer : CallTransformer {
199203
override fun interceptOrNull(
200204
callInfo: CallInfo,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ReturnTypeBasedReceiverInjector(session: FirSession) : FirExpressionResolu
1919
@OptIn(SymbolInternals::class)
2020
override fun addNewImplicitReceivers(functionCall: FirFunctionCall): List<ConeKotlinType> {
2121
val callReturnType = functionCall.resolvedType
22-
return if (callReturnType.classId in setOf(Names.DF_CLASS_ID, Names.GROUP_BY_CLASS_ID)) {
22+
return if (callReturnType.classId in setOf(Names.DF_CLASS_ID, Names.GROUP_BY_CLASS_ID, Names.DATA_ROW_CLASS_ID)) {
2323
val typeArguments = callReturnType.typeArguments
2424
typeArguments
2525
.mapNotNull {

plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/api/read.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.jetbrains.kotlinx.dataframe.plugin.impl.api
33
import kotlinx.serialization.decodeFromString
44
import kotlinx.serialization.json.Json
55
import org.jetbrains.kotlinx.dataframe.DataFrame
6+
import org.jetbrains.kotlinx.dataframe.DataRow
67
import org.jetbrains.kotlinx.dataframe.plugin.impl.AbstractInterpreter
78
import org.jetbrains.kotlinx.dataframe.plugin.impl.Arguments
89
import org.jetbrains.kotlinx.dataframe.plugin.impl.Present
@@ -118,6 +119,15 @@ internal class ReadJsonStr : AbstractInterpreter<PluginDataFrameSchema>() {
118119
}
119120
}
120121

122+
internal class DataRowReadJsonStr : AbstractInterpreter<PluginDataFrameSchema>() {
123+
val Arguments.text: String by arg()
124+
val Arguments.typeClashTactic: JSON.TypeClashTactic by arg(defaultValue = Present(ARRAY_AND_VALUE_COLUMNS))
125+
126+
override fun Arguments.interpret(): PluginDataFrameSchema {
127+
return DataRow.readJsonStr(text, typeClashTactic = typeClashTactic).schema().toPluginDataFrameSchema()
128+
}
129+
}
130+
121131
internal class ReadExcel : AbstractSchemaModificationInterpreter() {
122132
val Arguments.fileOrUrl: String by arg()
123133
val Arguments.sheetName: String? by arg(defaultValue = Present(null))

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ColsOf1
8181
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.DataFrameBuilderInvoke0
8282
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.DataFrameOf0
8383
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.DataFrameOf3
84+
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.DataRowReadJsonStr
8485
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.FillNulls0
8586
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.Flatten0
8687
import org.jetbrains.kotlinx.dataframe.plugin.impl.api.FlattenDefault
@@ -218,6 +219,7 @@ internal inline fun <reified T> String.load(): T {
218219
"DataFrameGroupBy" -> DataFrameGroupBy()
219220
"GroupByInto" -> GroupByInto()
220221
"ReadJsonStr" -> ReadJsonStr()
222+
"DataRowReadJsonStr" -> DataRowReadJsonStr()
221223
"ReadDelimStr" -> ReadDelimStr()
222224
"GroupByToDataFrame" -> GroupByToDataFrame()
223225
"ToDataFrameFrom0" -> ToDataFrameFrom()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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+
const val text = """{"a":"abc", "b":1}"""
7+
8+
fun box(): String {
9+
val row = DataRow.readJsonStr(text)
10+
row.a
11+
row.b
12+
return "OK"
13+
}

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
@@ -352,6 +352,12 @@ public void testReadJsonStr_const() {
352352
runTest("testData/box/readJsonStr_const.kt");
353353
}
354354

355+
@Test
356+
@TestMetadata("readJsonStr_datarow.kt")
357+
public void testReadJsonStr_datarow() {
358+
runTest("testData/box/readJsonStr_datarow.kt");
359+
}
360+
355361
@Test
356362
@TestMetadata("readJsonStr_localProperty.kt")
357363
public void testReadJsonStr_localProperty() {

0 commit comments

Comments
 (0)