Skip to content

Commit 47d623c

Browse files
committed
[Compiler plugin] Lower frontend generated implicit receivers
1 parent 90220d5 commit 47d623c

File tree

4 files changed

+48
-7
lines changed

4 files changed

+48
-7
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/aggregation/AggregateDsl.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.jetbrains.kotlinx.dataframe.aggregation
22

33
import org.jetbrains.kotlinx.dataframe.DataFrame
4+
import org.jetbrains.kotlinx.dataframe.annotations.HasSchema
45
import org.jetbrains.kotlinx.dataframe.annotations.Interpretable
56
import org.jetbrains.kotlinx.dataframe.api.ColumnSelectionDsl
67
import org.jetbrains.kotlinx.dataframe.api.pathOf
@@ -11,6 +12,7 @@ import org.jetbrains.kotlinx.dataframe.impl.columnName
1112
import kotlin.reflect.KProperty
1213
import kotlin.reflect.typeOf
1314

15+
@HasSchema(schemaArg = 0)
1416
public abstract class AggregateDsl<out T> :
1517
DataFrame<T>,
1618
ColumnSelectionDsl<T> {

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

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConst
2929
import org.jetbrains.kotlin.ir.expressions.IrErrorCallExpression
3030
import org.jetbrains.kotlin.ir.expressions.IrExpression
3131
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
32+
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
3233
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
3334
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
3435
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
@@ -40,6 +41,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
4041
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
4142
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
4243
import org.jetbrains.kotlin.ir.types.IrSimpleType
44+
import org.jetbrains.kotlin.ir.types.IrType
4345
import org.jetbrains.kotlin.ir.types.classFqName
4446
import org.jetbrains.kotlin.ir.types.classOrFail
4547
import org.jetbrains.kotlin.ir.types.classifierOrNull
@@ -218,16 +220,33 @@ private class DataFrameFileLowering(val context: IrPluginContext) : FileLowering
218220
return declaration
219221
}
220222

221-
@OptIn(UnsafeDuringIrConstructionAPI::class)
223+
// org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator#applyReceivers
224+
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
225+
if (isScope(expression.typeOperand)) {
226+
return expression.replaceWithConstructorCall()
227+
}
228+
return super.visitTypeOperator(expression)
229+
}
230+
222231
override fun visitErrorCallExpression(expression: IrErrorCallExpression): IrExpression {
223-
val origin = (expression.type.classifierOrNull?.owner as? IrClass)?.origin ?: return expression
224-
val fromPlugin = origin is IrDeclarationOrigin.GeneratedByPlugin && origin.pluginKey is DataFramePlugin
225-
val scopeReference = expression.type.classFqName?.shortName()?.asString()?.startsWith("Scope") ?: false
226-
if (!(fromPlugin || scopeReference)) {
232+
if (!isScope(expression.type)) {
227233
return expression
228234
}
229-
val constructor = expression.type.getClass()!!.constructors.toList().single()
230-
val type = expression.type
235+
return expression.replaceWithConstructorCall()
236+
}
237+
238+
@OptIn(UnsafeDuringIrConstructionAPI::class)
239+
private fun isScope(type: IrType): Boolean {
240+
val origin = (type.classifierOrNull?.owner as? IrClass)?.origin ?: return false
241+
val fromPlugin = origin is IrDeclarationOrigin.GeneratedByPlugin && origin.pluginKey is DataFramePlugin
242+
val scopeReference = type.classFqName?.shortName()?.asString()?.startsWith("Scope") ?: false
243+
return fromPlugin || scopeReference
244+
}
245+
246+
@OptIn(UnsafeDuringIrConstructionAPI::class)
247+
private fun IrExpression.replaceWithConstructorCall(): IrConstructorCallImpl {
248+
val constructor = type.getClass()!!.constructors.toList().single()
249+
val type = type
231250
return IrConstructorCallImpl(-1, -1, type, constructor.symbol, 0, 0, 0)
232251
}
233252
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
2+
import org.jetbrains.kotlinx.dataframe.api.*
3+
4+
5+
@DataSchema
6+
data class Record(val a: String, val b: Int)
7+
8+
fun box(): String {
9+
val df = List(10) { Record(it.toString(), it) }.let { dataFrameOf(*it.toTypedArray()) }
10+
val aggregate = df.pivot { b }.aggregate {
11+
this.add("c") { 123 }.c
12+
}
13+
return "OK"
14+
}

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
@@ -436,6 +436,12 @@ public void testUpdate() {
436436
runTest("testData/box/update.kt");
437437
}
438438

439+
@Test
440+
@TestMetadata("wrongReceiver.kt")
441+
public void testWrongReceiver() {
442+
runTest("testData/box/wrongReceiver.kt");
443+
}
444+
439445
@Nested
440446
@TestMetadata("testData/box/colKinds")
441447
@TestDataPath("$PROJECT_ROOT")

0 commit comments

Comments
 (0)