All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlinx.jupyter.api.FieldsHandlingEx.kt Maven / Gradle / Ivy

There is a newer version: 0.12.0-335
Show newest version
package org.jetbrains.kotlinx.jupyter.api

import java.lang.reflect.Field
import kotlin.reflect.KProperty
import kotlin.reflect.jvm.javaField

class FieldInfo(
    val kotlinProperty: KProperty<*>?,
    val javaField: Field,
)

val FieldInfo.name: VariableName get() = kotlinProperty?.name ?: javaField.name
val FieldInfo.isCellResult: Boolean get() = kotlinProperty == null && name.startsWith("res")

private fun KProperty<*>.toFieldInfo() =
    FieldInfo(this, javaField ?: throw IllegalArgumentException("Property $this should have backing field"))

fun interface FieldHandlerExecutionEx : FieldHandlerExecution {
    fun execute(
        host: KotlinKernelHost,
        value: T,
        fieldInfo: FieldInfo,
    ): FieldValue?

    override fun execute(
        host: KotlinKernelHost,
        value: T,
        property: KProperty<*>,
    ) {
        execute(host, value, property.toFieldInfo())
    }
}

interface FieldHandlerEx : FieldHandler {
    /**
     * Tells if this handler accepts the given property
     * Called for each variable in the cells executed by users,
     * except those names are starting from [TEMP_PROPERTY_PREFIX]
     * or those that have been already consumed by another handler
     *
     * @param value Property value
     * @param fieldInfo Property runtime information
     */
    fun accepts(
        value: Any?,
        fieldInfo: FieldInfo,
    ): Boolean

    override fun accepts(
        value: Any?,
        property: KProperty<*>,
    ): Boolean {
        return accepts(value, property.toFieldInfo())
    }

    /**
     * Execution to handle conversion.
     * Should not throw if [accepts] returns true
     * Called for each property for which [accepts] returned true
     */
    override val execution: FieldHandlerExecutionEx<*>
}

class ResultFieldUpdateHandler(
    val updateCondition: (value: Any?, field: Field) -> Boolean,
    updateAction: (host: KotlinKernelHost, value: Any?, field: Field) -> VariableName?,
) : FieldHandlerEx {
    override val execution: FieldHandlerExecutionEx =
        FieldHandlerExecutionEx { host, value, fieldInfo ->
            val field = fieldInfo.javaField
            val tempField = updateAction(host, value, field)
            if (tempField != null) {
                val fieldName = field.name
                host.execute("val $fieldName = $tempField; $fieldName")
            } else {
                null
            }
        }

    override fun accepts(
        value: Any?,
        fieldInfo: FieldInfo,
    ): Boolean {
        if (!fieldInfo.isCellResult) return false
        return updateCondition(value, fieldInfo.javaField)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy