diff --git a/core/api/core.api b/core/api/core.api index bb76090655..59644d8a84 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -1672,14 +1672,18 @@ public final class org/jetbrains/kotlinx/dataframe/api/CountKt { public static synthetic fun count$default (Lorg/jetbrains/kotlinx/dataframe/api/Grouped;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; } -public abstract class org/jetbrains/kotlinx/dataframe/api/CreateDataFrameDsl : org/jetbrains/kotlinx/dataframe/api/TraversePropertiesDsl { +public abstract class org/jetbrains/kotlinx/dataframe/api/CreateDataFrameDsl { public fun ()V public abstract fun add (Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;Lorg/jetbrains/kotlinx/dataframe/columns/ColumnPath;)V public static synthetic fun add$default (Lorg/jetbrains/kotlinx/dataframe/api/CreateDataFrameDsl;Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;Lorg/jetbrains/kotlinx/dataframe/columns/ColumnPath;ILjava/lang/Object;)V + public final fun exclude ([Lkotlin/reflect/KCallable;)V + public final fun exclude ([Lkotlin/reflect/KClass;)V public abstract fun getSource ()Ljava/lang/Iterable; public final fun into (Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;Ljava/lang/String;)V public final fun into (Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;Lorg/jetbrains/kotlinx/dataframe/columns/ColumnPath;)V public abstract fun invoke (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun preserve ([Lkotlin/reflect/KCallable;)V + public final fun preserve ([Lkotlin/reflect/KClass;)V public abstract fun properties ([Lkotlin/reflect/KCallable;ILkotlin/jvm/functions/Function1;)V public static synthetic fun properties$default (Lorg/jetbrains/kotlinx/dataframe/api/CreateDataFrameDsl;[Lkotlin/reflect/KCallable;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt index f1d35d3b8f..8d49808c40 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlinx.dataframe.impl.columnName import org.jetbrains.kotlinx.dataframe.impl.columns.createColumnGuessingType import org.jetbrains.kotlinx.dataframe.index import org.jetbrains.kotlinx.dataframe.util.DEPRECATED_ACCESS_API +import org.jetbrains.kotlinx.dataframe.util.TRAVERSE_PROPERTIES_DSL import kotlin.reflect.KCallable import kotlin.reflect.KClass import kotlin.reflect.KProperty @@ -153,6 +154,24 @@ public fun Iterable>>.toDataFrameFromPairs(): DataFr ColumnPath(it.first) to createColumnGuessingType(it.first, it.second.asList()) }.toDataFrameFromPairs() +/** + * [DslMarker] to prevent fucntions from [CreateDataFrameDsl] being used inside [TraversePropertiesDsl]. + * This prevents notations like: + * ```kt + * list.toDataFrame { + * "colA" from { ... } + * properties { + * preserve() + * "colB" from { ... } // ERROR, cannot be called in this context an implicit receiver. + * } + * } + * ``` + */ +@DslMarker +@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS, AnnotationTarget.TYPE, AnnotationTarget.FUNCTION) +public annotation class CreateDataFrameDslMarker + +@CreateDataFrameDslMarker public interface TraversePropertiesDsl { /** @@ -188,7 +207,11 @@ public interface TraversePropertiesDsl { @Interpretable("PreserveT") public inline fun TraversePropertiesDsl.preserve(): Unit = preserve(T::class) -public abstract class CreateDataFrameDsl : TraversePropertiesDsl { +@Deprecated(TRAVERSE_PROPERTIES_DSL, level = DeprecationLevel.ERROR) +public inline fun CreateDataFrameDsl<*>.preserve(): Unit = Unit + +@CreateDataFrameDslMarker +public abstract class CreateDataFrameDsl { public abstract val source: Iterable @@ -207,6 +230,18 @@ public abstract class CreateDataFrameDsl : TraversePropertiesDsl { body: (TraversePropertiesDsl.() -> Unit)? = null, ) + @Deprecated(TRAVERSE_PROPERTIES_DSL, level = DeprecationLevel.ERROR) + public fun exclude(vararg classes: KClass<*>): Unit = Unit + + @Deprecated(TRAVERSE_PROPERTIES_DSL, level = DeprecationLevel.ERROR) + public fun exclude(vararg properties: KCallable<*>): Unit = Unit + + @Deprecated(TRAVERSE_PROPERTIES_DSL, level = DeprecationLevel.ERROR) + public fun preserve(vararg classes: KClass<*>): Unit = Unit + + @Deprecated(TRAVERSE_PROPERTIES_DSL, level = DeprecationLevel.ERROR) + public fun preserve(vararg properties: KCallable<*>): Unit = Unit + public inline fun expr(infer: Infer = Infer.Nulls, noinline expression: (T) -> R): DataColumn = source.map { expression(it) }.toColumn(infer = infer) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toDataFrame.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toDataFrame.kt index ce77bfa619..1312af86a9 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toDataFrame.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toDataFrame.kt @@ -111,8 +111,7 @@ internal class CreateDataFrameDslImpl( private val type: KType, private val prefix: ColumnPath = emptyPath(), private val configuration: TraverseConfiguration = TraverseConfiguration(), -) : CreateDataFrameDsl(), - TraversePropertiesDsl by configuration { +) : CreateDataFrameDsl() { internal val columns = mutableListOf>() diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index fed730edcb..a45e22034f 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -176,6 +176,10 @@ internal const val DATAROW_READ = internal const val SUPPORTED_DATAFRAME_FORMAT: String = "SupportedDataFrameFormat is deprecated. $MESSAGE_1_0" +internal const val TRAVERSE_PROPERTIES_DSL = + "Top-level `exclude`/`preserve` calls in `toDataFrame {}` are deprecated. " + + "Move them into each `properties { }` block to configure traversal instead. $MESSAGE_1_0" + // endregion // region WARNING in 1.0, ERROR in 1.1 diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt index 78e11eef64..31db34ef15 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt @@ -190,8 +190,9 @@ class CreateDataFrameTests { ) val res = data.toDataFrame { - preserve() - properties(maxDepth = 2) + properties(maxDepth = 2) { + preserve() + } } res.schema() shouldBe data.toDataFrame(maxDepth = 0).schema()