From 7bea468a2c7a0687e781ec3e275a79f4e7d2bd97 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Fri, 4 Apr 2025 14:38:32 +0300 Subject: [PATCH 1/2] Add missing AccessApiOverload --- .../kotlin/org/jetbrains/kotlinx/dataframe/api/split.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/split.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/split.kt index 5f9161f47f..bbb1ba0457 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/split.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/split.kt @@ -142,11 +142,13 @@ internal fun Split.toDataFrame(): DataFrame = // region into +@AccessApiOverload public fun SplitWithTransform.into( firstName: ColumnAccessor<*>, vararg otherNames: ColumnAccessor<*>, ): DataFrame = into(listOf(firstName.name()) + otherNames.map { it.name() }) +@AccessApiOverload public fun SplitWithTransform.into( firstName: KProperty<*>, vararg otherNames: KProperty<*>, @@ -183,6 +185,7 @@ public fun Split>.into( public fun Split>.into(firstCol: String, secondCol: String): DataFrame = by { listOf(it.first, it.second) }.into(firstCol, secondCol) +@AccessApiOverload public inline fun Split>.into( firstCol: ColumnAccessor, secondCol: ColumnAccessor, @@ -208,11 +211,13 @@ public fun SplitWithTransform.inward( extraNamesGenerator: ColumnNamesGenerator? = null, ): DataFrame = inward(names.toList(), extraNamesGenerator) +@AccessApiOverload public fun SplitWithTransform.inward( firstName: ColumnAccessor<*>, vararg otherNames: ColumnAccessor<*>, ): DataFrame = inward(listOf(firstName.name()) + otherNames.map { it.name() }) +@AccessApiOverload public fun SplitWithTransform.inward( firstName: KProperty<*>, vararg otherNames: KProperty<*>, @@ -232,6 +237,7 @@ public fun , R> Split.inward( public fun Split>.inward(firstCol: String, secondCol: String): DataFrame = by { listOf(it.first, it.second) }.inward(firstCol, secondCol) +@AccessApiOverload public inline fun Split>.inward( firstCol: ColumnAccessor, secondCol: ColumnAccessor, From 1d73a6daa63ddd1387cfe4211de411e4517566b3 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Fri, 4 Apr 2025 14:40:32 +0300 Subject: [PATCH 2/2] [Compiler plugin] Support convert shortcuts --- core/api/core.api | 55 +++- .../kotlinx/dataframe/annotations/Plugin.kt | 8 + .../kotlinx/dataframe/api/convert.kt | 238 ++++++++++++++++-- .../dataframe/plugin/impl/api/convert.kt | 40 +++ .../kotlinx/dataframe/plugin/interpret.kt | 5 +- .../dataframe/plugin/loadInterpreter.kt | 6 + .../kotlinx/dataframe/plugin/utils/Names.kt | 2 + .../testData/box/convertToShortcuts.kt | 21 ++ ...DataFrameBlackBoxCodegenTestGenerated.java | 6 + 9 files changed, 351 insertions(+), 30 deletions(-) create mode 100644 plugins/kotlin-dataframe/testData/box/convertToShortcuts.kt diff --git a/core/api/core.api b/core/api/core.api index 2acda50a99..11825cb5b8 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -405,6 +405,11 @@ public abstract interface annotation class org/jetbrains/kotlinx/dataframe/annot public abstract fun name ()Ljava/lang/String; } +public abstract interface annotation class org/jetbrains/kotlinx/dataframe/annotations/Converter : java/lang/annotation/Annotation { + public abstract fun klass ()Ljava/lang/Class; + public abstract fun nullable ()Z +} + public abstract interface annotation class org/jetbrains/kotlinx/dataframe/annotations/CsvOptions : java/lang/annotation/Annotation { public abstract fun delimiter ()C } @@ -1713,41 +1718,67 @@ public final class org/jetbrains/kotlinx/dataframe/api/ConvertKt { public static final fun toDoubleTAny (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toFloat (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toFloatTAny (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static final fun toIFrame (Lorg/jetbrains/kotlinx/dataframe/api/Convert;ZLjava/lang/Integer;Ljava/lang/Integer;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static synthetic fun toIFrame$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;ZLjava/lang/Integer;Ljava/lang/Integer;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static final fun toImg (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/Integer;Ljava/lang/Integer;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static synthetic fun toImg$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/Integer;Ljava/lang/Integer;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static final fun toInstant (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toIframeFromUrl (Lorg/jetbrains/kotlinx/dataframe/api/Convert;ZLjava/lang/Integer;Ljava/lang/Integer;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toIframeFromUrl$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;ZLjava/lang/Integer;Ljava/lang/Integer;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toIframeFromUrlNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;ZLjava/lang/Integer;Ljava/lang/Integer;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toIframeFromUrlNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;ZLjava/lang/Integer;Ljava/lang/Integer;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toImgFromUrl (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/Integer;Ljava/lang/Integer;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toImgFromUrl$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/Integer;Ljava/lang/Integer;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toImgFromUrlNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/Integer;Ljava/lang/Integer;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toImgFromUrlNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/Integer;Ljava/lang/Integer;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toInstantFromString (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toInstantFromStringNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toInt (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toIntTAny (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalDate (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static final fun toLocalDate (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static synthetic fun toLocalDate$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateFromString (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateFromString$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateFromStringNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateFromStringNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalDateFromTInt (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static synthetic fun toLocalDateFromTInt$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateFromTIntNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateFromTIntNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalDateFromTLong (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static synthetic fun toLocalDateFromTLong$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateFromTLongNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateFromTLongNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalDateTime (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static final fun toLocalDateTime (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static synthetic fun toLocalDateTime$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateTimeFromString (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateTimeFromString$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateTimeFromStringNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateTimeFromStringNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalDateTimeFromTInstant (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static synthetic fun toLocalDateTimeFromTInstant$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateTimeFromTInstantNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateTimeFromTInstantNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalDateTimeFromTInt (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static synthetic fun toLocalDateTimeFromTInt$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateTimeFromTIntNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateTimeFromTIntNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalDateTimeFromTLong (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static synthetic fun toLocalDateTimeFromTLong$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalDateTimeFromTLongNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalDateTimeFromTLongNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalTime (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static final fun toLocalTime (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static synthetic fun toLocalTime$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalTimeFromString (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalTimeFromString$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalTimeFromStringNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalTimeFromStringNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Ljava/lang/String;Ljava/util/Locale;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalTimeFromTInt (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static synthetic fun toLocalTimeFromTInt$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalTimeFromTIntNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalTimeFromTIntNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLocalTimeFromTLong (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static synthetic fun toLocalTimeFromTLong$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toLocalTimeFromTLongNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static synthetic fun toLocalTimeFromTLongNullable$default (Lorg/jetbrains/kotlinx/dataframe/api/Convert;Lkotlinx/datetime/TimeZone;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLong (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toLongTAny (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toStr (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; public static final fun toStrTAny (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; - public static final fun toURL (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toUrlFromString (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; + public static final fun toUrlFromStringNullable (Lorg/jetbrains/kotlinx/dataframe/api/Convert;)Lorg/jetbrains/kotlinx/dataframe/DataFrame; } public abstract interface class org/jetbrains/kotlinx/dataframe/api/ConvertSchemaDsl { diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/annotations/Plugin.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/annotations/Plugin.kt index 4c336dad7c..42f4c8eecf 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/annotations/Plugin.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/annotations/Plugin.kt @@ -1,5 +1,7 @@ package org.jetbrains.kotlinx.dataframe.annotations +import kotlin.reflect.KClass + @Target(AnnotationTarget.CLASS) public annotation class HasSchema(val schemaArg: Int) @@ -46,3 +48,9 @@ internal annotation class Check */ @Target(AnnotationTarget.FUNCTION) internal annotation class AccessApiOverload + +/** + * Provides argument to `ToSpecificType` interpreter - to what type compiler plugin should convert selected columns + */ +@Target(AnnotationTarget.FUNCTION) +public annotation class Converter(val klass: KClass<*>, val nullable: Boolean = false) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt index 69075f2f6c..3b7c08f3aa 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlinx.dataframe.DataRow import org.jetbrains.kotlinx.dataframe.RowColumnExpression import org.jetbrains.kotlinx.dataframe.RowValueExpression import org.jetbrains.kotlinx.dataframe.annotations.AccessApiOverload +import org.jetbrains.kotlinx.dataframe.annotations.Converter import org.jetbrains.kotlinx.dataframe.annotations.HasSchema import org.jetbrains.kotlinx.dataframe.annotations.Interpretable import org.jetbrains.kotlinx.dataframe.annotations.Refine @@ -284,13 +285,38 @@ public fun DataColumn.convertToBoolean(): DataColumn = c // region convert URL -public fun Convert.toIFrame( +@JvmName("toIframeFromUrlNullable") +@Refine +@Converter(IFRAME::class, nullable = true) +@Interpretable("ToSpecificType") +public fun Convert.toIFrame( + border: Boolean = false, + width: Int? = null, + height: Int? = null, +): DataFrame = to { it.map { url -> url?.let { IFRAME(url.toString(), border, width, height) } } } + +@JvmName("toIframeFromUrl") +@Refine +@Converter(IFRAME::class, nullable = false) +@Interpretable("ToSpecificType") +public fun Convert.toIFrame( border: Boolean = false, width: Int? = null, height: Int? = null, ): DataFrame = to { it.map { IFRAME(it.toString(), border, width, height) } } -public fun Convert.toImg(width: Int? = null, height: Int? = null): DataFrame = +@JvmName("toImgFromUrlNullable") +@Refine +@Converter(IMG::class, nullable = true) +@Interpretable("ToSpecificType") +public fun Convert.toImg(width: Int? = null, height: Int? = null): DataFrame = + to { it.map { url -> url?.let { IMG(url.toString(), width, height) } } } + +@JvmName("toImgFromUrl") +@Refine +@Converter(IMG::class, nullable = false) +@Interpretable("ToSpecificType") +public fun Convert.toImg(width: Int? = null, height: Int? = null): DataFrame = to { it.map { IMG(it.toString(), width, height) } } // endregion @@ -302,7 +328,17 @@ public fun DataColumn.convertToURL(): DataColumn = map { URL(it) } @JvmName("convertToURLFromStringNullable") public fun DataColumn.convertToURL(): DataColumn = map { it?.let { URL(it) } } -public fun Convert.toURL(): DataFrame = to { it.convertToURL() } +@JvmName("toUrlFromStringNullable") +@Refine +@Converter(URL::class, nullable = true) +@Interpretable("ToSpecificType") +public fun Convert.toURL(): DataFrame = to { it.convertToURL() } + +@JvmName("toUrlFromString") +@Refine +@Converter(URL::class, nullable = false) +@Interpretable("ToSpecificType") +public fun Convert.toURL(): DataFrame = to { it.convertToURL() } // endregion @@ -313,7 +349,17 @@ public fun DataColumn.convertToInstant(): DataColumn = map { In @JvmName("convertToInstantFromStringNullable") public fun DataColumn.convertToInstant(): DataColumn = map { it?.let { Instant.parse(it) } } -public fun Convert.toInstant(): DataFrame = to { it.convertToInstant() } +@JvmName("toInstantFromStringNullable") +@Refine +@Converter(Instant::class, nullable = true) +@Interpretable("ToSpecificType") +public fun Convert.toInstant(): DataFrame = to { it.convertToInstant() } + +@JvmName("toInstantFromString") +@Refine +@Converter(Instant::class, nullable = false) +@Interpretable("ToSpecificType") +public fun Convert.toInstant(): DataFrame = to { it.convertToInstant() } // endregion @@ -352,17 +398,51 @@ public fun DataColumn.convertToLocalDate( return map { it?.let { converter(it.trim()) ?: error("Can't convert `$it` to LocalDate") } } } +@JvmName("toLocalDateFromTLongNullable") +@Refine +@Converter(LocalDate::class, nullable = true) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDate(zone: TimeZone = defaultTimeZone): DataFrame = + to { it.convertToLocalDate(zone) } + @JvmName("toLocalDateFromTLong") -public fun Convert.toLocalDate(zone: TimeZone = defaultTimeZone): DataFrame = +@Refine +@Converter(LocalDate::class, nullable = false) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDate(zone: TimeZone = defaultTimeZone): DataFrame = to { it.convertToLocalDate(zone) } @JvmName("toLocalDateFromTInt") -public fun Convert.toLocalDate(zone: TimeZone = defaultTimeZone): DataFrame = +@Refine +@Converter(LocalDate::class, nullable = true) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDate(zone: TimeZone = defaultTimeZone): DataFrame = to { it.convertToLocalDate(zone) } -public fun Convert.toLocalDate(pattern: String? = null, locale: Locale? = null): DataFrame = +@JvmName("toLocalDateFromTIntNullable") +@Refine +@Converter(LocalDate::class, nullable = false) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDate(zone: TimeZone = defaultTimeZone): DataFrame = + to { it.convertToLocalDate(zone) } + +@JvmName("toLocalDateFromStringNullable") +@Refine +@Converter(LocalDate::class, nullable = true) +@Interpretable("ToSpecificTypePattern") +public fun Convert.toLocalDate(pattern: String? = null, locale: Locale? = null): DataFrame = + to { it.convertToLocalDate(pattern, locale) } + +@JvmName("toLocalDateFromString") +@Refine +@Converter(LocalDate::class, nullable = false) +@Interpretable("ToSpecificTypePattern") +public fun Convert.toLocalDate(pattern: String? = null, locale: Locale? = null): DataFrame = to { it.convertToLocalDate(pattern, locale) } +@Refine +@Converter(LocalDate::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toLocalDate(): DataFrame = to { it.convertTo() } // endregion @@ -402,17 +482,51 @@ public fun DataColumn.convertToLocalTime( return map { it?.let { converter(it.trim()) ?: error("Can't convert `$it` to LocalTime") } } } +@JvmName("toLocalTimeFromTLongNullable") +@Refine +@Converter(LocalTime::class, nullable = true) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalTime(zone: TimeZone = defaultTimeZone): DataFrame = + to { it.convertToLocalTime(zone) } + @JvmName("toLocalTimeFromTLong") -public fun Convert.toLocalTime(zone: TimeZone = defaultTimeZone): DataFrame = +@Refine +@Converter(LocalTime::class, nullable = false) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalTime(zone: TimeZone = defaultTimeZone): DataFrame = + to { it.convertToLocalTime(zone) } + +@JvmName("toLocalTimeFromTIntNullable") +@Refine +@Converter(LocalTime::class, nullable = true) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalTime(zone: TimeZone = defaultTimeZone): DataFrame = to { it.convertToLocalTime(zone) } @JvmName("toLocalTimeFromTInt") -public fun Convert.toLocalTime(zone: TimeZone = defaultTimeZone): DataFrame = +@Refine +@Converter(LocalTime::class, nullable = false) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalTime(zone: TimeZone = defaultTimeZone): DataFrame = to { it.convertToLocalTime(zone) } -public fun Convert.toLocalTime(pattern: String? = null, locale: Locale? = null): DataFrame = +@JvmName("toLocalTimeFromStringNullable") +@Refine +@Converter(LocalTime::class, nullable = true) +@Interpretable("ToSpecificTypePattern") +public fun Convert.toLocalTime(pattern: String? = null, locale: Locale? = null): DataFrame = to { it.convertToLocalTime(pattern, locale) } +@JvmName("toLocalTimeFromString") +@Refine +@Converter(LocalTime::class, nullable = false) +@Interpretable("ToSpecificTypePattern") +public fun Convert.toLocalTime(pattern: String? = null, locale: Locale? = null): DataFrame = + to { it.convertToLocalTime(pattern, locale) } + +@Refine +@Converter(LocalTime::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toLocalTime(): DataFrame = to { it.convertTo() } // endregion @@ -460,65 +574,155 @@ public fun DataColumn.convertToLocalDateTime( return map { it?.let { converter(it.trim()) ?: error("Can't convert `$it` to LocalDateTime") } } } +@JvmName("toLocalDateTimeFromTLongNullable") +@Refine +@Converter(LocalDateTime::class, nullable = true) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = + to { it.convertToLocalDateTime(zone) } + @JvmName("toLocalDateTimeFromTLong") -public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = +@Refine +@Converter(LocalDateTime::class, nullable = false) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = + to { it.convertToLocalDateTime(zone) } + +@JvmName("toLocalDateTimeFromTInstantNullable") +@Refine +@Converter(LocalDateTime::class, nullable = true) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = to { it.convertToLocalDateTime(zone) } @JvmName("toLocalDateTimeFromTInstant") -public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = +@Refine +@Converter(LocalDateTime::class, nullable = false) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = + to { it.convertToLocalDateTime(zone) } + +@JvmName("toLocalDateTimeFromTIntNullable") +@Refine +@Converter(LocalDateTime::class, nullable = true) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = to { it.convertToLocalDateTime(zone) } @JvmName("toLocalDateTimeFromTInt") -public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = +@Refine +@Converter(LocalDateTime::class, nullable = false) +@Interpretable("ToSpecificTypeZone") +public fun Convert.toLocalDateTime(zone: TimeZone = defaultTimeZone): DataFrame = to { it.convertToLocalDateTime(zone) } -public fun Convert.toLocalDateTime( - pattern: String? = null, - locale: Locale? = null, -): DataFrame = to { it.convertToLocalDateTime(pattern, locale) } +@JvmName("toLocalDateTimeFromStringNullable") +@Refine +@Converter(LocalDateTime::class, nullable = true) +@Interpretable("ToSpecificTypePattern") +public fun Convert.toLocalDateTime(pattern: String? = null, locale: Locale? = null): DataFrame = + to { it.convertToLocalDateTime(pattern, locale) } +@JvmName("toLocalDateTimeFromString") +@Refine +@Converter(LocalDateTime::class, nullable = false) +@Interpretable("ToSpecificTypePattern") +public fun Convert.toLocalDateTime(pattern: String? = null, locale: Locale? = null): DataFrame = + to { it.convertToLocalDateTime(pattern, locale) } + +@Refine +@Converter(LocalDateTime::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toLocalDateTime(): DataFrame = to { it.convertTo() } // endregion @JvmName("toIntTAny") +@Refine +@Converter(Int::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toInt(): DataFrame = to() +@Refine +@Converter(Int::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toInt(): DataFrame = to() @JvmName("toLongTAny") +@Refine +@Converter(Long::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toLong(): DataFrame = to() +@Refine +@Converter(Long::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toLong(): DataFrame = to() @JvmName("toStrTAny") +@Refine +@Converter(String::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toStr(): DataFrame = to() +@Refine +@Converter(String::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toStr(): DataFrame = to() @JvmName("toDoubleTAny") +@Refine +@Converter(Double::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toDouble(): DataFrame = to() +@Refine +@Converter(Double::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toDouble(): DataFrame = to() @JvmName("toFloatTAny") +@Refine +@Converter(Float::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toFloat(): DataFrame = to() +@Refine +@Converter(Float::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toFloat(): DataFrame = to() @JvmName("toBigDecimalTAny") +@Refine +@Converter(BigDecimal::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toBigDecimal(): DataFrame = to() +@Refine +@Converter(BigDecimal::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toBigDecimal(): DataFrame = to() @JvmName("toBigIntegerTAny") +@Refine +@Converter(BigInteger::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toBigInteger(): DataFrame = to() +@Refine +@Converter(BigInteger::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toBigInteger(): DataFrame = to() @JvmName("toBooleanTAny") +@Refine +@Converter(Boolean::class, nullable = false) +@Interpretable("ToSpecificType") public fun Convert.toBoolean(): DataFrame = to() +@Refine +@Converter(Boolean::class, nullable = true) +@Interpretable("ToSpecificType") public fun Convert.toBoolean(): DataFrame = to() public fun Convert>>.toDataFrames(containsColumns: Boolean = false): DataFrame = diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/api/convert.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/api/convert.kt index ed28bef266..264abff040 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/api/convert.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/impl/api/convert.kt @@ -1,11 +1,22 @@ package org.jetbrains.kotlinx.dataframe.plugin.impl.api +import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId +import org.jetbrains.kotlin.fir.declarations.getBooleanArgument +import org.jetbrains.kotlin.fir.declarations.getKClassArgument +import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.references.toResolvedFunctionSymbol +import org.jetbrains.kotlin.fir.types.ConeNullability +import org.jetbrains.kotlin.fir.types.typeContext +import org.jetbrains.kotlin.fir.types.withNullability +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlinx.dataframe.api.Infer import org.jetbrains.kotlinx.dataframe.plugin.extensions.KotlinTypeFacade +import org.jetbrains.kotlinx.dataframe.plugin.extensions.wrap import org.jetbrains.kotlinx.dataframe.plugin.impl.Absent import org.jetbrains.kotlinx.dataframe.plugin.impl.AbstractInterpreter import org.jetbrains.kotlinx.dataframe.plugin.impl.AbstractSchemaModificationInterpreter import org.jetbrains.kotlinx.dataframe.plugin.impl.Arguments +import org.jetbrains.kotlinx.dataframe.plugin.impl.Interpreter import org.jetbrains.kotlinx.dataframe.plugin.impl.PluginDataFrameSchema import org.jetbrains.kotlinx.dataframe.plugin.impl.Present import org.jetbrains.kotlinx.dataframe.plugin.impl.SimpleCol @@ -17,6 +28,7 @@ import org.jetbrains.kotlinx.dataframe.plugin.impl.enum import org.jetbrains.kotlinx.dataframe.plugin.impl.ignore import org.jetbrains.kotlinx.dataframe.plugin.impl.simpleColumnOf import org.jetbrains.kotlinx.dataframe.plugin.impl.type +import org.jetbrains.kotlinx.dataframe.plugin.utils.Names internal class Convert0 : AbstractInterpreter() { val Arguments.columns: ColumnsResolver by arg() @@ -140,3 +152,31 @@ internal class To0 : AbstractInterpreter() { return convertImpl(receiver.schema, receiver.columns, typeArg0) } } + +internal abstract class AbstractToSpecificType : AbstractInterpreter() { + val Arguments.functionCall: FirFunctionCall by arg(lens = Interpreter.Id) + val Arguments.receiver: ConvertApproximation by arg() + + override fun Arguments.interpret(): PluginDataFrameSchema { + val converterAnnotation = functionCall.calleeReference.toResolvedFunctionSymbol()?.getAnnotationByClassId(Names.CONVERTER_ANNOTATION, session) + val to = converterAnnotation?.getKClassArgument(Name.identifier("klass"), session) + val nullable = converterAnnotation?.getBooleanArgument(Name.identifier("nullable"), session) + return if (to != null && nullable != null) { + val targetType = to.withNullability(ConeNullability.create(nullable), session.typeContext) + convertImpl(receiver.schema, receiver.columns, targetType.wrap()) + } else { + PluginDataFrameSchema.EMPTY + } + } +} + +internal class ToSpecificType : AbstractToSpecificType() + +internal class ToSpecificTypeZone : AbstractToSpecificType() { + val Arguments.zone by ignore() +} + +internal class ToSpecificTypePattern : AbstractToSpecificType() { + val Arguments.pattern by ignore() + val Arguments.locale by ignore() +} 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 02327652be..c8dd2c18c6 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 @@ -92,7 +92,7 @@ fun KotlinTypeFacade.interpret( ): Interpreter.Success? { val refinedArguments: RefinedArguments = functionCall.collectArgumentExpressions() - val defaultArguments = processor.expectedArguments.filter { it.defaultValue is Present }.map { it.name }.toSet() + val defaultArguments = processor.expectedArguments.filter { it.defaultValue is Present }.map { it.name }.toSet() + THIS_CALL val actualValueArguments = refinedArguments.associateBy { it.name.identifier }.toSortedMap() val conflictingKeys = additionalArguments.keys intersect actualValueArguments.keys if (conflictingKeys.isNotEmpty()) { @@ -139,6 +139,7 @@ fun KotlinTypeFacade.interpret( val arguments = mutableMapOf>() arguments += additionalArguments arguments += typeArguments + arguments[THIS_CALL] = Interpreter.Success(functionCall) val interpretationResults = refinedArguments.refinedArguments.mapNotNull { val name = it.name.identifier val expectedArgument = expectedArgsMap[name] ?: error("$processor $name") @@ -567,6 +568,8 @@ internal fun FirExpression.getSchema(session: FirSession): ObjectWithSchema? { } } +private const val THIS_CALL = "functionCall" + internal class ObjectWithSchema(val schemaArg: Int, val typeRef: ConeKotlinType) internal val ConeKotlinType.canHaveLiteralInitializer get() = isPrimitiveOrNullablePrimitive || isString || isNullableString diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/loadInterpreter.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/loadInterpreter.kt index c00bc58e5f..0f7de344aa 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/loadInterpreter.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/loadInterpreter.kt @@ -200,6 +200,9 @@ import org.jetbrains.kotlinx.dataframe.plugin.impl.api.Take2 import org.jetbrains.kotlinx.dataframe.plugin.impl.api.TakeLast0 import org.jetbrains.kotlinx.dataframe.plugin.impl.api.TakeLast1 import org.jetbrains.kotlinx.dataframe.plugin.impl.api.TakeLast2 +import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToSpecificType +import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToSpecificTypePattern +import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ToSpecificTypeZone import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ValueCols0 import org.jetbrains.kotlinx.dataframe.plugin.impl.api.ValueCols1 import org.jetbrains.kotlinx.dataframe.plugin.impl.api.WithoutNulls0 @@ -290,6 +293,9 @@ internal inline fun String.load(): T { "Convert2" -> Convert2() "Convert6" -> Convert6() "To0" -> To0() + "ToSpecificType" -> ToSpecificType() + "ToSpecificTypeZone" -> ToSpecificTypeZone() + "ToSpecificTypePattern" -> ToSpecificTypePattern() "With0" -> With0() "PerRowCol" -> PerRowCol() "Explode0" -> Explode0() diff --git a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/utils/Names.kt b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/utils/Names.kt index 9c44475793..e97c105718 100644 --- a/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/utils/Names.kt +++ b/plugins/kotlin-dataframe/src/org/jetbrains/kotlinx/dataframe/plugin/utils/Names.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlinx.dataframe.annotations.ColumnName +import org.jetbrains.kotlinx.dataframe.annotations.Converter import org.jetbrains.kotlinx.dataframe.annotations.Order import org.jetbrains.kotlinx.dataframe.annotations.ScopeProperty import kotlin.reflect.KClass @@ -54,6 +55,7 @@ object Names { get() = FqName("org.jetbrains.kotlinx.dataframe.annotations.Interpretable") private val annotationsPackage = FqName("org.jetbrains.kotlinx.dataframe.annotations") val ORDER_ANNOTATION = ClassId(annotationsPackage, Name.identifier(Order::class.simpleName!!)) + val CONVERTER_ANNOTATION = ClassId(annotationsPackage, Name.identifier(Converter::class.simpleName!!)) val ORDER_ARGUMENT = Name.identifier(Order::order.name) val SCOPE_PROPERTY_ANNOTATION = ClassId(annotationsPackage, Name.identifier(ScopeProperty::class.simpleName!!)) val COLUMN_NAME_ANNOTATION = ClassId(annotationsPackage, Name.identifier(ColumnName::class.simpleName!!)) diff --git a/plugins/kotlin-dataframe/testData/box/convertToShortcuts.kt b/plugins/kotlin-dataframe/testData/box/convertToShortcuts.kt new file mode 100644 index 0000000000..265096909d --- /dev/null +++ b/plugins/kotlin-dataframe/testData/box/convertToShortcuts.kt @@ -0,0 +1,21 @@ +import org.jetbrains.kotlinx.dataframe.* +import org.jetbrains.kotlinx.dataframe.annotations.* +import org.jetbrains.kotlinx.dataframe.api.* +import org.jetbrains.kotlinx.dataframe.io.* +import kotlinx.datetime.* + +fun box(): String { + val daysToStandardMillis = 24 * 60 * 60 * 1000L * 366 + val df = dataFrameOf("a")(60L * 1000L + daysToStandardMillis).convert { a }.toLocalDateTime(TimeZone.UTC) + val localDateTime: LocalDateTime = df.a[0] + + val df1 = dataFrameOf("a")(60L * 1000L + daysToStandardMillis, null).convert { a }.toLocalDateTime(TimeZone.UTC) + val localDateTime1: LocalDateTime? = df1.a[0] + + val df2 = dataFrameOf("a")(123).convert { a }.toStr() + val str: String = df2.a[0] + + val df3 = dataFrameOf("a")(123, null).convert { a }.toStr() + df3.compareSchemas(strict = true) + return "OK" +} diff --git a/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameBlackBoxCodegenTestGenerated.java b/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameBlackBoxCodegenTestGenerated.java index 8ed87bfd2e..79a2f6aa91 100644 --- a/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameBlackBoxCodegenTestGenerated.java +++ b/plugins/kotlin-dataframe/tests-gen/org/jetbrains/kotlin/fir/dataframe/DataFrameBlackBoxCodegenTestGenerated.java @@ -89,6 +89,12 @@ public void testConvertToDataFrame() { runTest("testData/box/convertToDataFrame.kt"); } + @Test + @TestMetadata("convertToShortcuts.kt") + public void testConvertToShortcuts() { + runTest("testData/box/convertToShortcuts.kt"); + } + @Test @TestMetadata("convert_to.kt") public void testConvert_to() {