diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/FirDataFrameComponentRegistrar.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/FirDataFrameComponentRegistrar.kt index 68f4accc73..778ce06892 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/FirDataFrameComponentRegistrar.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/FirDataFrameComponentRegistrar.kt @@ -65,6 +65,7 @@ class FirDataFrameExtensionRegistrar( private val path: String?, val schemasDirectory: String?, val isTest: Boolean, + val dumpSchemas: Boolean, ) : FirExtensionRegistrar() { @OptIn(FirExtensionApiInternals::class) override fun ExtensionRegistrarContext.configurePlugin() { @@ -76,7 +77,7 @@ class FirDataFrameExtensionRegistrar( +::TokenGenerator +::DataRowSchemaSupertype +{ it: FirSession -> - ExpressionAnalysisAdditionalChecker(it, jsonCache(it), schemasDirectory, isTest) + ExpressionAnalysisAdditionalChecker(it, jsonCache(it), schemasDirectory, isTest, dumpSchemas) } } @@ -93,7 +94,9 @@ class FirDataFrameComponentRegistrar : CompilerPluginRegistrar() { override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) { val schemasDirectory = configuration.get(SCHEMAS) val path = configuration.get(PATH) - FirExtensionRegistrarAdapter.registerExtension(FirDataFrameExtensionRegistrar(path, schemasDirectory, isTest = false)) + FirExtensionRegistrarAdapter.registerExtension( + FirDataFrameExtensionRegistrar(path, schemasDirectory, isTest = false, dumpSchemas = true) + ) IrGenerationExtension.registerExtension(IrBodyFiller(path, schemasDirectory)) } diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/ExpressionAnalysisAdditionalChecker.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/ExpressionAnalysisAdditionalChecker.kt index 59533e4aee..d3ccb5fb85 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/ExpressionAnalysisAdditionalChecker.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/ExpressionAnalysisAdditionalChecker.kt @@ -5,7 +5,13 @@ package org.jetbrains.kotlinx.dataframe.plugin.extensions +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.diagnostics.AbstractSourceElementPositioningStrategy +import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1DelegateProvider import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1 +import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies import org.jetbrains.kotlin.diagnostics.error1 import org.jetbrains.kotlin.diagnostics.reportOn @@ -13,18 +19,24 @@ import org.jetbrains.kotlin.diagnostics.warning1 import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirPropertyChecker +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirSimpleFunctionChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker +import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirPropertyAccessExpressionChecker import org.jetbrains.kotlin.fir.analysis.extensions.FirAdditionalCheckersExtension import org.jetbrains.kotlin.fir.caches.FirCache -import org.jetbrains.kotlinx.dataframe.plugin.impl.api.flatten -import org.jetbrains.kotlinx.dataframe.plugin.pluginDataFrameSchema +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.hasAnnotation import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.isSubtypeOf @@ -38,18 +50,34 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlinx.dataframe.plugin.impl.PluginDataFrameSchema +import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleColumnGroup import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleDataColumn -import org.jetbrains.kotlinx.dataframe.plugin.impl.type +import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleFrameColumn +import org.jetbrains.kotlinx.dataframe.plugin.impl.api.flatten +import org.jetbrains.kotlinx.dataframe.plugin.pluginDataFrameSchema import org.jetbrains.kotlinx.dataframe.plugin.utils.Names +import org.jetbrains.kotlinx.dataframe.plugin.utils.isDataFrame +import org.jetbrains.kotlinx.dataframe.plugin.utils.isDataRow +import org.jetbrains.kotlinx.dataframe.plugin.utils.isGroupBy class ExpressionAnalysisAdditionalChecker( session: FirSession, cache: FirCache, schemasDirectory: String?, isTest: Boolean, + dumpSchemas: Boolean ) : FirAdditionalCheckersExtension(session) { override val expressionCheckers: ExpressionCheckers = object : ExpressionCheckers() { - override val functionCallCheckers: Set = setOf(Checker(cache, schemasDirectory, isTest)) + override val functionCallCheckers: Set = setOfNotNull( + Checker(cache, schemasDirectory, isTest), FunctionCallSchemaReporter.takeIf { dumpSchemas } + ) + override val propertyAccessExpressionCheckers: Set = setOfNotNull( + PropertyAccessSchemaReporter.takeIf { dumpSchemas } + ) + } + override val declarationCheckers: DeclarationCheckers = object : DeclarationCheckers() { + override val propertyCheckers: Set = setOfNotNull(PropertySchemaReporter.takeIf { dumpSchemas }) + override val simpleFunctionCheckers: Set = setOfNotNull(FunctionDeclarationSchemaReporter.takeIf { dumpSchemas }) } } @@ -132,3 +160,105 @@ private class Checker( } } } + +private data object PropertySchemaReporter : FirPropertyChecker(mppKind = MppCheckerKind.Common) { + val SCHEMA by info1(SourceElementPositioningStrategies.DECLARATION_NAME) + + override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { + context.sessionContext { + declaration.returnTypeRef.coneType.let { type -> + reportSchema(reporter, declaration.source, SCHEMA, type, context) + } + } + } +} + +private data object FunctionCallSchemaReporter : FirFunctionCallChecker(mppKind = MppCheckerKind.Common) { + val SCHEMA by info1(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) + + override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) { + if (expression.calleeReference.name in setOf(Name.identifier("let"), Name.identifier("run"))) return + val initializer = expression.resolvedType + context.sessionContext { + reportSchema(reporter, expression.source, SCHEMA, initializer, context) + } + } +} + +private data object PropertyAccessSchemaReporter : FirPropertyAccessExpressionChecker(mppKind = MppCheckerKind.Common) { + val SCHEMA by info1(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) + + override fun check( + expression: FirPropertyAccessExpression, + context: CheckerContext, + reporter: DiagnosticReporter + ) { + val initializer = expression.resolvedType + context.sessionContext { + reportSchema(reporter, expression.source, SCHEMA, initializer, context) + } + } +} + +private data object FunctionDeclarationSchemaReporter : FirSimpleFunctionChecker(mppKind = MppCheckerKind.Common) { + val SCHEMA by info1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + + override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) { + val type = declaration.returnTypeRef.coneType + context.sessionContext { + reportSchema(reporter, declaration.source, SCHEMA, type, context) + } + } +} + +private fun SessionContext.reportSchema( + reporter: DiagnosticReporter, + source: KtSourceElement?, + factory: KtDiagnosticFactory1, + type: ConeKotlinType, + context: CheckerContext, +) { + val expandedType = type.fullyExpandedType(session) + var schema: PluginDataFrameSchema? = null + when { + expandedType.isDataFrame(session) -> { + schema = expandedType.typeArguments.getOrNull(0)?.let { + pluginDataFrameSchema(it) + } + } + + expandedType.isDataRow(session) -> { + schema = expandedType.typeArguments.getOrNull(0)?.let { + pluginDataFrameSchema(it) + } + } + + expandedType.isGroupBy(session) -> { + val keys = expandedType.typeArguments.getOrNull(0) + val grouped = expandedType.typeArguments.getOrNull(1) + if (keys != null && grouped != null) { + val keysSchema = pluginDataFrameSchema(keys) + val groupedSchema = pluginDataFrameSchema(grouped) + schema = PluginDataFrameSchema( + listOf( + SimpleColumnGroup("keys", keysSchema.columns()), + SimpleFrameColumn("groups", groupedSchema.columns()) + ) + ) + } + } + } + if (schema != null && source != null) { + reporter.reportOn(source, factory, "\n" + schema.toString(), context) + } +} + +fun CheckerContext.sessionContext(f: SessionContext.() -> Unit) { + SessionContext(session).f() +} + +inline fun info1( + positioningStrategy: AbstractSourceElementPositioningStrategy = SourceElementPositioningStrategies.DEFAULT +): DiagnosticFactory1DelegateProvider { + return DiagnosticFactory1DelegateProvider(Severity.INFO, positioningStrategy, P::class) +} diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/FunctionCallTransformer.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/FunctionCallTransformer.kt index 25bd79c5f5..0a65aaa2a1 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/FunctionCallTransformer.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/FunctionCallTransformer.kt @@ -81,7 +81,6 @@ import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleDataColumn import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleColumnGroup import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleFrameColumn import org.jetbrains.kotlinx.dataframe.plugin.impl.api.GroupBy -import org.jetbrains.kotlinx.dataframe.plugin.impl.api.createPluginDataFrameSchema import kotlin.math.abs @OptIn(FirExtensionApiInternals::class) @@ -321,6 +320,7 @@ class FunctionCallTransformer( val receiverType = explicitReceiver?.resolvedType val returnType = call.resolvedType val scopeFunction = if (explicitReceiver != null) findLet() else findRun() + val originalSource = call.calleeReference.source // original call is inserted later call.transformCalleeReference(object : FirTransformer() { @@ -328,7 +328,6 @@ class FunctionCallTransformer( return if (element is FirResolvedNamedReference) { @Suppress("UNCHECKED_CAST") buildResolvedNamedReference { - source = call.calleeReference.source this.name = element.name resolvedSymbol = originalSymbol } as E @@ -430,7 +429,8 @@ class FunctionCallTransformer( } val newCall1 = buildFunctionCall { - source = call.source + // source = call.source makes IDE navigate to `let` declaration + source = null this.coneTypeOrNull = returnType if (receiverType != null) { typeArguments += buildTypeProjectionWithVariance { @@ -455,7 +455,7 @@ class FunctionCallTransformer( linkedMapOf(argument to scopeFunction.valueParameterSymbols[0].fir) ) calleeReference = buildResolvedNamedReference { - source = call.calleeReference.source + source = originalSource this.name = scopeFunction.name resolvedSymbol = scopeFunction } diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/KotlinTypeFacade.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/KotlinTypeFacade.kt index 75d1d37800..307575490e 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/KotlinTypeFacade.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/extensions/KotlinTypeFacade.kt @@ -27,8 +27,7 @@ import kotlin.reflect.KType import kotlin.reflect.KTypeProjection import kotlin.reflect.KVariance -interface KotlinTypeFacade { - val session: FirSession +interface KotlinTypeFacade : SessionContext { val resolutionPath: String? get() = null val cache: FirCache val schemasDirectory: String? @@ -99,6 +98,14 @@ interface KotlinTypeFacade { } } +interface SessionContext { + val session: FirSession +} + +fun SessionContext(session: FirSession) = object : SessionContext { + override val session: FirSession = session +} + private val List = "List".collectionsId() private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean?): Boolean { diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/SimpleCol.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/SimpleCol.kt index 5a88dee41e..1a181adbdc 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/SimpleCol.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/SimpleCol.kt @@ -1,11 +1,10 @@ -@file:Suppress("INVISIBLE_REFERENCE", "CANNOT_OVERRIDE_INVISIBLE_MEMBER") - package org.jetbrains.kotlinx.dataframe.plugin.impl import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClassId import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeNullability import org.jetbrains.kotlin.fir.types.isNullable +import org.jetbrains.kotlin.fir.types.renderReadable import org.jetbrains.kotlinx.dataframe.plugin.extensions.KotlinTypeFacade import org.jetbrains.kotlinx.dataframe.plugin.extensions.wrap import org.jetbrains.kotlinx.dataframe.plugin.impl.api.TypeApproximation @@ -18,6 +17,7 @@ data class PluginDataFrameSchema( companion object { val EMPTY = PluginDataFrameSchema(emptyList()) } + fun columns(): List { return columns } @@ -32,16 +32,19 @@ fun PluginDataFrameSchema.add(name: String, type: ConeKotlinType, context: Kotli } private fun List.asString(indent: String = ""): String { + if (isEmpty()) return "$indent" return joinToString("\n") { val col = when (it) { is SimpleFrameColumn -> { - "${it.name}*\n" + it.columns().asString("$indent ") + "${it.name}: *\n" + it.columns().asString("$indent ") } + is SimpleColumnGroup -> { - "${it.name}\n" + it.columns().asString("$indent ") + "${it.name}:\n" + it.columns().asString("$indent ") } + is SimpleDataColumn -> { - "${it.name}: ${it.type}" + "${it.name}: ${it.type.type.renderReadable()}" } } "$indent$col" @@ -127,6 +130,7 @@ private fun KotlinTypeFacade.makeNullable(column: SimpleCol): SimpleCol { is SimpleColumnGroup -> { SimpleColumnGroup(column.name, column.columns().map { makeNullable(it) }) } + is SimpleFrameColumn -> column is SimpleDataColumn -> SimpleDataColumn(column.name, column.type.changeNullability { true }) } diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/interpret.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/interpret.kt index de690d00ba..93de2bebb5 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/interpret.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/interpret.kt @@ -69,6 +69,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlinx.dataframe.annotations.* +import org.jetbrains.kotlinx.dataframe.plugin.extensions.SessionContext import org.jetbrains.kotlinx.dataframe.plugin.impl.data.ColumnPathApproximation import org.jetbrains.kotlinx.dataframe.plugin.impl.data.ColumnWithPathApproximation import org.jetbrains.kotlinx.dataframe.plugin.impl.data.DataFrameCallableId @@ -333,7 +334,7 @@ interface InterpretationErrorReporter { } } -fun KotlinTypeFacade.pluginDataFrameSchema(schemaTypeArg: ConeTypeProjection): PluginDataFrameSchema { +fun SessionContext.pluginDataFrameSchema(schemaTypeArg: ConeTypeProjection): PluginDataFrameSchema { val schema = if (schemaTypeArg.isStarProjection) { PluginDataFrameSchema.EMPTY } else { @@ -343,7 +344,7 @@ fun KotlinTypeFacade.pluginDataFrameSchema(schemaTypeArg: ConeTypeProjection): P return schema } -fun KotlinTypeFacade.pluginDataFrameSchema(coneClassLikeType: ConeClassLikeType): PluginDataFrameSchema { +fun SessionContext.pluginDataFrameSchema(coneClassLikeType: ConeClassLikeType): PluginDataFrameSchema { val symbol = coneClassLikeType.toSymbol(session) as? FirRegularClassSymbol ?: return PluginDataFrameSchema.EMPTY val declarationSymbols = if (symbol.isLocal && symbol.resolvedSuperTypes.firstOrNull() != session.builtinTypes.anyType.type) { val rootSchemaSymbol = symbol.resolvedSuperTypes.first().toSymbol(session) as? FirRegularClassSymbol @@ -407,7 +408,7 @@ private fun KotlinTypeFacade.columnWithPathApproximations(result: FirPropertyAcc } } -private fun KotlinTypeFacade.columnOf(it: FirPropertySymbol, mapping: Map): SimpleCol? { +private fun SessionContext.columnOf(it: FirPropertySymbol, mapping: Map): SimpleCol? { val annotation = it.getAnnotationByClassId(Names.COLUMN_NAME_ANNOTATION, session) val columnName = (annotation?.argumentMapping?.mapping?.get(Names.COLUMN_NAME_ARGUMENT) as? FirLiteralExpression)?.value as? String val name = columnName ?: it.name.identifier @@ -456,14 +457,14 @@ private fun KotlinTypeFacade.columnOf(it: FirPropertySymbol, mapping: Map.classId(): ClassId { val className = fqName.substringAfterLast(".") return ClassId(FqName(packageFqName), Name.identifier(className)) } + +fun ConeKotlinType.isDataFrame(session: FirSession) = + isSubtypeOf(ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(Names.DF_CLASS_ID), arrayOf(ConeStarProjection), isNullable = false), session) + +fun ConeKotlinType.isGroupBy(session: FirSession) = fullyExpandedClassId(session) == Names.GROUP_BY_CLASS_ID + +fun ConeKotlinType.isDataRow(session: FirSession) = fullyExpandedClassId(session) == Names.DATA_ROW_CLASS_ID diff --git a/plugins/kotlin-dataframe/testData/diagnostics/schemaInfo.fir.txt b/plugins/kotlin-dataframe/testData/diagnostics/schemaInfo.fir.txt new file mode 100644 index 0000000000..45d91fb86d --- /dev/null +++ b/plugins/kotlin-dataframe/testData/diagnostics/schemaInfo.fir.txt @@ -0,0 +1,512 @@ +FILE: schemaInfo.kt + @R|org/jetbrains/kotlinx/dataframe/annotations/DataSchema|() public final data class Person : R|kotlin/Any|, R|org/jetbrains/kotlinx/dataframe/api/DataRowSchema| { + public constructor(firstName: R|kotlin/String|, lastName: R|kotlin/String|, age: R|kotlin/Int|, city: R|kotlin/String?|): R|Person| { + super() + } + + public final val firstName: R|kotlin/String| = R|/firstName| + public get(): R|kotlin/String| + + public final val lastName: R|kotlin/String| = R|/lastName| + public get(): R|kotlin/String| + + public final val age: R|kotlin/Int| = R|/age| + public get(): R|kotlin/Int| + + public final val city: R|kotlin/String?| = R|/city| + public get(): R|kotlin/String?| + + public final operator fun component1(): R|kotlin/String| + + public final operator fun component2(): R|kotlin/String| + + public final operator fun component3(): R|kotlin/Int| + + public final operator fun component4(): R|kotlin/String?| + + public final fun copy(firstName: R|kotlin/String| = this@R|/Person|.R|/Person.firstName|, lastName: R|kotlin/String| = this@R|/Person|.R|/Person.lastName|, age: R|kotlin/Int| = this@R|/Person|.R|/Person.age|, city: R|kotlin/String?| = this@R|/Person|.R|/Person.city|): R|Person| + + } + @R|org/jetbrains/kotlinx/dataframe/annotations/DataSchema|() public final data class Group : R|kotlin/Any|, R|org/jetbrains/kotlinx/dataframe/api/DataRowSchema| { + public constructor(id: R|kotlin/String|, participants: R|kotlin/collections/List|): R|Group| { + super() + } + + public final val id: R|kotlin/String| = R|/id| + public get(): R|kotlin/String| + + public final val participants: R|kotlin/collections/List| = R|/participants| + public get(): R|kotlin/collections/List| + + public final operator fun component1(): R|kotlin/String| + + public final operator fun component2(): R|kotlin/collections/List| + + public final fun copy(id: R|kotlin/String| = this@R|/Group|.R|/Group.id|, participants: R|kotlin/collections/List| = this@R|/Group|.R|/Group.participants|): R|Group| + + } + public final fun test(): R|kotlin/Unit| { + lval df: R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_43>| = R|kotlin/collections/listOf|(vararg(R|/Group.Group|(String(1), R|kotlin/collections/listOf|(vararg(R|/Person.Person|(String(Alice), String(Cooper), Int(15), String(London)), R|/Person.Person|(String(Bob), String(Dylan), Int(45), String(Dubai))))), R|/Group.Group|(String(2), R|kotlin/collections/listOf|(vararg(R|/Person.Person|(String(Charlie), String(Daniels), Int(20), String(Moscow)), R|/Person.Person|(String(Charlie), String(Chaplin), Int(40), String(Milan))))))).R|kotlin/let||, R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_43>|>( = fun (it: R|kotlin/collections/List|): R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_43>| { + local abstract class Group_43I : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val id: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val participants: R|org/jetbrains/kotlinx/dataframe/DataFrame</Participants_561>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataFrame</Participants_561>| + + public constructor(): R|/Group_43I| + + } + + local final class Scope0 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_43I>|.id: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_43I>|.id: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_43I>|.participants: R|org/jetbrains/kotlinx/dataframe/DataFrame</Participants_561>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataFrame</Participants_561>| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_43I>|.participants: R|org/jetbrains/kotlinx/dataframe/DataColumn/Participants_561>>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn/Participants_561>>| + + public constructor(): R|/Scope0| + + } + + local abstract class Participants_561 : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(3)) public abstract val city: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val firstName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val lastName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(2)) public abstract val age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public constructor(): R|/Participants_561| + + } + + local final class Scope1 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_561>|.city: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_561>|.city: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_561>|.firstName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_561>|.firstName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_561>|.lastName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_561>|.lastName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_561>|.age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_561>|.age: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public constructor(): R|/Scope1| + + } + + local abstract class Group_43 : R|/Group_43I| { + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope0: R|/Scope0| + public get(): R|/Scope0| + + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope1: R|/Scope1| + public get(): R|/Scope1| + + public constructor(): R|/Group_43| + + } + + ^ R|/it|.R|org/jetbrains/kotlinx/dataframe/api/toDataFrame|(Int(2)) + } + ) + (this@R|/test|, R|/df|).R|/Scope0.participants|.R|SubstitutionOverride/Participants_561>|>|(Int(0)) + (this@R|/test|, R|/df|).R|/Scope0.participants|.R|org/jetbrains/kotlinx/dataframe/api/first|/Participants_561>|>() + (this@R|/test|, R|/df|.R|kotlin/let|/Group_43>|, R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_92>|>( = fun (it: R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_43>|): R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_92>| { + local abstract class Group_92I : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val id: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val participants: R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + + public constructor(): R|/Group_92I| + + } + + local final class Scope0 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_92I>|.id: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_92I>|.id: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_92I>|.participants: R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_92I>|.participants: R|org/jetbrains/kotlinx/dataframe/columns/ColumnGroup</Participants_181>| + public get(): R|org/jetbrains/kotlinx/dataframe/columns/ColumnGroup</Participants_181>| + + public constructor(): R|/Scope0| + + } + + local abstract class Participants_181 : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val city: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val firstName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(2)) public abstract val lastName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(3)) public abstract val age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public constructor(): R|/Participants_181| + + } + + local final class Scope1 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.city: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.city: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.firstName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.firstName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.lastName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.lastName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.age: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public constructor(): R|/Scope1| + + } + + local abstract class Group_92 : R|/Group_92I| { + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope0: R|/Scope0| + public get(): R|/Scope0| + + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope1: R|/Scope1| + public get(): R|/Scope1| + + public constructor(): R|/Group_92| + + } + + ^ R|/it|.R|org/jetbrains/kotlinx/dataframe/api/explode|/Group_43|>( = explode@fun R|org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl</Group_43>|.(it: R|org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl</Group_43>|): R|org/jetbrains/kotlinx/dataframe/columns/ColumnsResolver<*>| { + ^ (this@R|/test|, this@R|special/anonymous|).R|/Scope0.participants| + } + ) + } + )).R|/Scope0.participants| + (this@R|/test|, (this@R|/test|, R|/df|).R|/Scope0.participants|.R|SubstitutionOverride/Participants_561>|>|(Int(0))).R|/Scope1.age| + (this@R|/test|, (this@R|/test|, R|/df|.R|SubstitutionOverride/Group_43>|>|(Int(0))).R|/Scope0.participants|).R|/Scope1.age| + R|/df|.R|kotlin/let|/Group_43>|, R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_92>|>( = fun (it: R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_43>|): R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_92>| { + local abstract class Group_92I : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val id: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val participants: R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + + public constructor(): R|/Group_92I| + + } + + local final class Scope0 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_92I>|.id: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_92I>|.id: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_92I>|.participants: R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_92I>|.participants: R|org/jetbrains/kotlinx/dataframe/columns/ColumnGroup</Participants_181>| + public get(): R|org/jetbrains/kotlinx/dataframe/columns/ColumnGroup</Participants_181>| + + public constructor(): R|/Scope0| + + } + + local abstract class Participants_181 : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val city: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val firstName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(2)) public abstract val lastName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(3)) public abstract val age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public constructor(): R|/Participants_181| + + } + + local final class Scope1 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.city: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.city: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.firstName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.firstName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.lastName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.lastName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Participants_181>|.age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Participants_181>|.age: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public constructor(): R|/Scope1| + + } + + local abstract class Group_92 : R|/Group_92I| { + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope0: R|/Scope0| + public get(): R|/Scope0| + + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope1: R|/Scope1| + public get(): R|/Scope1| + + public constructor(): R|/Group_92| + + } + + ^ R|/it|.R|org/jetbrains/kotlinx/dataframe/api/explode|/Group_43|>( = explode@fun R|org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl</Group_43>|.(it: R|org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl</Group_43>|): R|org/jetbrains/kotlinx/dataframe/columns/ColumnsResolver<*>| { + ^ (this@R|/test|, this@R|special/anonymous|).R|/Scope0.participants| + } + ) + } + ).R|kotlin/let|/Group_92>|, R|org/jetbrains/kotlinx/dataframe/api/GroupBy</Key_92, /Group_92>|>( = fun (it: R|org/jetbrains/kotlinx/dataframe/DataFrame</Group_92>|): R|org/jetbrains/kotlinx/dataframe/api/GroupBy</Key_92, /Group_92>| { + local abstract class Group_92I : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val id: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val participants: R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>| + + public constructor(): R|/Group_92I| + + } + + local final class Scope1 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_92I>|.id: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_92I>|.id: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Group_92I>|.participants: R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Group_92I>|.participants: R|org/jetbrains/kotlinx/dataframe/columns/ColumnGroup</GroupParticipants_461>| + public get(): R|org/jetbrains/kotlinx/dataframe/columns/ColumnGroup</GroupParticipants_461>| + + public constructor(): R|/Scope1| + + } + + local abstract class GroupParticipants_461 : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val city: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val firstName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(2)) public abstract val lastName: R|kotlin/String| + public get(): R|kotlin/String| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(3)) public abstract val age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public constructor(): R|/GroupParticipants_461| + + } + + local final class Scope2 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>|.city: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</GroupParticipants_461>|.city: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>|.firstName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</GroupParticipants_461>|.firstName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>|.lastName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</GroupParticipants_461>|.lastName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</GroupParticipants_461>|.age: R|kotlin/Int| + public get(): R|kotlin/Int| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</GroupParticipants_461>|.age: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public constructor(): R|/Scope2| + + } + + local abstract class Key_92I : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val lastName: R|kotlin/String| + public get(): R|kotlin/String| + + public constructor(): R|/Key_92I| + + } + + local final class Scope0 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Key_92I>|.lastName: R|kotlin/String| + public get(): R|kotlin/String| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Key_92I>|.lastName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public constructor(): R|/Scope0| + + } + + local abstract class Key_92 : R|/Key_92I| { + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope0: R|/Scope0| + public get(): R|/Scope0| + + public constructor(): R|/Key_92| + + } + + local abstract class Group_92 : R|/Group_92I| { + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope2: R|/Scope2| + public get(): R|/Scope2| + + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope1: R|/Scope1| + public get(): R|/Scope1| + + public constructor(): R|/Group_92| + + } + + ^ R|/it|.R|org/jetbrains/kotlinx/dataframe/api/groupBy|/Group_92|>( = groupBy@fun R|org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl</Group_92>|.(it: R|org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl</Group_92>|): R|org/jetbrains/kotlinx/dataframe/columns/ColumnsResolver<*>| { + ^ (this@R|/test|, (this@R|/test|, this@R|special/anonymous|).R|/Scope0.participants|).R|/Scope1.lastName| + } + ) + } + ) + local final fun test(): R|org/jetbrains/kotlinx/dataframe/DataFrame</Invoke_34>| { + ^test R|org/jetbrains/kotlinx/dataframe/api/dataFrameOf|(vararg(String(a), String(b))).R|kotlin/let|/Invoke_34>|>( = fun (it: R|org/jetbrains/kotlinx/dataframe/api/DataFrameBuilder|): R|org/jetbrains/kotlinx/dataframe/DataFrame</Invoke_34>| { + local abstract class Invoke_34I : R|kotlin/Any| { + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(1)) public abstract val b: R|kotlin/Int| + public get(): R|kotlin/Int| + + @R|org/jetbrains/kotlinx/dataframe/annotations/Order|(order = Int(0)) public abstract val a: R|kotlin/Int| + public get(): R|kotlin/Int| + + public constructor(): R|/Invoke_34I| + + } + + local final class Scope0 : R|kotlin/Any| { + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Invoke_34I>|.b: R|kotlin/Int| + public get(): R|kotlin/Int| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Invoke_34I>|.b: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public final val R|org/jetbrains/kotlinx/dataframe/DataRow</Invoke_34I>|.a: R|kotlin/Int| + public get(): R|kotlin/Int| + + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsScope</Invoke_34I>|.a: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + + public constructor(): R|/Scope0| + + } + + local abstract class Invoke_34 : R|/Invoke_34I| { + @R|org/jetbrains/kotlinx/dataframe/annotations/ScopeProperty|() public abstract val scope0: R|/Scope0| + public get(): R|/Scope0| + + public constructor(): R|/Invoke_34| + + } + + ^ R|/it|.R|org/jetbrains/kotlinx/dataframe/api/DataFrameBuilder.invoke|(vararg(Int(1), Int(2))) + } + ) + } + + } +FILE: __GENERATED DECLARATIONS__.kt + public final val R|org/jetbrains/kotlinx/dataframe/DataRow|.firstName: R|kotlin/String| + public get(): R|kotlin/String| + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsContainer|.firstName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + public final val R|org/jetbrains/kotlinx/dataframe/DataRow|.lastName: R|kotlin/String| + public get(): R|kotlin/String| + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsContainer|.lastName: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + public final val R|org/jetbrains/kotlinx/dataframe/DataRow|.age: R|kotlin/Int| + public get(): R|kotlin/Int| + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsContainer|.age: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + public final val R|org/jetbrains/kotlinx/dataframe/DataRow|.city: R|kotlin/String?| + public get(): R|kotlin/String?| + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsContainer|.city: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + public final val R|org/jetbrains/kotlinx/dataframe/DataRow|.id: R|kotlin/String| + public get(): R|kotlin/String| + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsContainer|.id: R|org/jetbrains/kotlinx/dataframe/DataColumn| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn| + public final val R|org/jetbrains/kotlinx/dataframe/DataRow|.participants: R|org/jetbrains/kotlinx/dataframe/DataFrame| + public get(): R|org/jetbrains/kotlinx/dataframe/DataFrame| + public final val R|org/jetbrains/kotlinx/dataframe/ColumnsContainer|.participants: R|org/jetbrains/kotlinx/dataframe/DataColumn>| + public get(): R|org/jetbrains/kotlinx/dataframe/DataColumn>| diff --git a/plugins/kotlin-dataframe/testData/diagnostics/schemaInfo.kt b/plugins/kotlin-dataframe/testData/diagnostics/schemaInfo.kt new file mode 100644 index 0000000000..8a88837ac9 --- /dev/null +++ b/plugins/kotlin-dataframe/testData/diagnostics/schemaInfo.kt @@ -0,0 +1,41 @@ +// DUMP_SCHEMAS +import org.jetbrains.kotlinx.dataframe.* +import org.jetbrains.kotlinx.dataframe.annotations.* +import org.jetbrains.kotlinx.dataframe.api.* +import org.jetbrains.kotlinx.dataframe.io.* + +@DataSchema +data class Person(val firstName: String, val lastName: String, val age: Int, val city: String?) + +@DataSchema +data class Group(val id: String, val participants: List) + +fun test() { + val df = listOf( + Group("1", listOf( + Person("Alice", "Cooper", 15, "London"), + Person("Bob", "Dylan", 45, "Dubai") + )), + Group("2", listOf( + Person("Charlie", "Daniels", 20, "Moscow"), + Person("Charlie", "Chaplin", 40, "Milan"), + )), + ).toDataFrame(maxDepth = 2) + + // For operator get call schema is reported for the whole expression, so on df two schemas are reported + df.participants[0] + + df.participants.first() + + df.explode { participants }.participants + + df.participants[0].age + + // DataRow + df[0].participants.age + + // GroupBy + df.explode { participants }.groupBy { participants.lastName } + + fun test() = dataFrameOf("a", "b")(1, 2) +} diff --git a/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameDiagnosticTestGenerated.java b/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameDiagnosticTestGenerated.java index dfc30eb01d..30ce0be462 100644 --- a/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameDiagnosticTestGenerated.java +++ b/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameDiagnosticTestGenerated.java @@ -32,6 +32,12 @@ public void testHistoryItem() { runTest("testData/diagnostics/HistoryItem.kt"); } + @Test + @TestMetadata("schemaInfo.kt") + public void testSchemaInfo() { + runTest("testData/diagnostics/schemaInfo.kt"); + } + @Test @TestMetadata("selectDuringTyping.kt") public void testSelectDuringTyping() { diff --git a/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/AbstractDataFrameDiagnosticTest.kt b/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/AbstractDataFrameDiagnosticTest.kt index 814fa4f2c5..6675815469 100644 --- a/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/AbstractDataFrameDiagnosticTest.kt +++ b/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/AbstractDataFrameDiagnosticTest.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.dataframe +import org.jetbrains.kotlin.fir.dataframe.services.Directives import org.jetbrains.kotlin.fir.dataframe.services.DataFramePluginAnnotationsProvider import org.jetbrains.kotlin.fir.dataframe.services.ExperimentalExtensionRegistrarConfigurator import org.jetbrains.kotlin.fir.dataframe.services.TemporaryDirectoryManagerImplFixed @@ -54,6 +55,7 @@ abstract class AbstractDataFrameDiagnosticTest : AbstractKotlinCompilerTest() { JvmEnvironmentConfigurationDirectives.JDK_KIND with TestJdkKind.FULL_JDK } + useDirectives(Directives) useConfigurators( ::DataFramePluginAnnotationsProvider, ::ExperimentalExtensionRegistrarConfigurator diff --git a/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/services/ExtensionRegistrarConfigurators.kt b/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/services/ExtensionRegistrarConfigurators.kt index 78b7893ae8..8cbc58cfcd 100644 --- a/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/services/ExtensionRegistrarConfigurators.kt +++ b/plugins/kotlin-dataframe/tests/org/jetbrains/kotlin/fir/dataframe/services/ExtensionRegistrarConfigurators.kt @@ -12,9 +12,11 @@ import org.jetbrains.kotlinx.dataframe.plugin.FirDataFrameExtensionRegistrar import org.jetbrains.kotlinx.dataframe.plugin.PATH import org.jetbrains.kotlinx.dataframe.plugin.extensions.IrBodyFiller import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter +import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.EnvironmentConfigurator import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.moduleStructure class ExperimentalExtensionRegistrarConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) { @@ -26,13 +28,21 @@ class ExperimentalExtensionRegistrarConfigurator(testServices: TestServices) : E module: TestModule, configuration: CompilerConfiguration ) { + val dumpSchemas = testServices.moduleStructure.allDirectives.contains(Directives.DUMP_SCHEMAS) FirExtensionRegistrarAdapter.registerExtension( FirDataFrameExtensionRegistrar( configuration.get(PATH)!!, null, - isTest = true + isTest = true, + dumpSchemas ) ) IrGenerationExtension.registerExtension(IrBodyFiller(configuration.get(PATH), null)) } } + +internal object Directives : SimpleDirectivesContainer() { + val DUMP_SCHEMAS by directive( + description = "Whether checkers should report schemas as info warnings" + ) +}