Migration to 1.4

This commit is contained in:
Alexander Nozik 2020-08-31 11:27:44 +03:00
parent b8d775aa30
commit 57b263ec63
22 changed files with 171 additions and 183 deletions

View File

@ -1,13 +1,10 @@
plugins {
val toolsVersion = "0.6.0"
id("kscience.mpp") version toolsVersion apply false
id("kscience.jvm") version toolsVersion apply false
id("kscience.publish") version toolsVersion apply false
id("kscience.publish") apply false
id("org.jetbrains.dokka") version "1.4.0-rc"
id("org.jetbrains.changelog") version "0.4.0"
}
val dataforgeVersion by extra("0.1.9-dev-1")
val dataforgeVersion by extra("0.1.9-dev-2")
val bintrayRepo by extra("dataforge")
val githubProject by extra("dataforge-core")

View File

@ -4,16 +4,20 @@ plugins {
description = "Context and provider definitions"
kscience{
kscience {
useCoroutines()
}
repositories {
maven("https://maven.pkg.github.com/altavir/kotlin-logging")
}
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
api(project(":dataforge-meta"))
api("io.github.microutils:kotlin-logging:1.9.0")
api("io.github.microutils:kotlin-logging:1.9.0-dev-npm")
}
}
val jvmMain by getting {

View File

@ -20,12 +20,12 @@ inline fun <reified R : Any, T : R> Data<T>.upcast(): Data<R> = upcast(R::class)
/**
* Check if node could be safely cast to given class
*/
expect fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean
internal expect fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean
/**
* Check if data could be safely cast to given class
*/
expect fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean
internal expect fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean
fun <R : Any> DataItem<*>.canCast(type: KClass<out R>): Boolean = when (this) {
is DataItem.Node -> node.canCast(type)

View File

@ -5,12 +5,12 @@ import kotlin.reflect.KClass
/**
* Check that node is compatible with given type meaning that each element could be cast to the type
*/
actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean {
internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean {
//Not supported in js yet
return true
}
actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean {
internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean {
//Not supported in js yet
return true
}

View File

@ -8,28 +8,28 @@ import kotlin.reflect.full.isSuperclassOf
/**
* Block the thread and get data content
*/
fun <T : Any> Data<T>.get(): T = runBlocking { await() }
public fun <T : Any> Data<T>.get(): T = runBlocking { await() }
/**
* Check that node is compatible with given type meaning that each element could be cast to the type
*/
actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean =
internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean =
type.isSuperclassOf(type)
actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean =
internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean =
this.type.isSubclassOf(type)
/**
* Cast the node to given type if the cast is possible or return null
*/
fun <R : Any> Data<*>.filterIsInstance(type: KClass<out R>): Data<R>? =
public fun <R : Any> Data<*>.filterIsInstance(type: KClass<out R>): Data<R>? =
if (canCast(type)) cast(type) else null
/**
* Filter a node by data and node type. Resulting node and its subnodes is guaranteed to have border type [type],
* but could contain empty nodes
*/
fun <R : Any> DataNode<*>.filterIsInstance(type: KClass<out R>): DataNode<R> {
public fun <R : Any> DataNode<*>.filterIsInstance(type: KClass<out R>): DataNode<R> {
return when {
canCast(type) -> cast(type)
this is TypeFilteredDataNode -> origin.filterIsInstance(type)

View File

@ -0,0 +1,11 @@
package hep.dataforge.io
import hep.dataforge.meta.DFExperimental
/**
* A fire-and-forget consumer of messages
*/
@DFExperimental
public interface Consumer {
public fun consume(message: Envelope): Unit
}

View File

@ -1,21 +1,12 @@
package hep.dataforge.io
import hep.dataforge.meta.DFExperimental
/**
* An object that could respond to external messages asynchronously
*/
interface Responder {
public interface Responder {
/**
* Send a request and wait for response for this specific request
*/
suspend fun respond(request: Envelope): Envelope
public suspend fun respond(request: Envelope): Envelope
}
/**
* A fire-and-forget consumer of messages
*/
@DFExperimental
interface Consumer {
fun consume(message: Envelope): Unit
}

View File

@ -4,16 +4,13 @@ import hep.dataforge.names.Name
import hep.dataforge.names.NameToken
import hep.dataforge.names.asName
import hep.dataforge.names.plus
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlin.collections.HashSet
import kotlin.collections.forEach
import kotlin.collections.mapValues
import kotlin.collections.removeAll
import kotlin.collections.set
//TODO add validator to configuration
@ -24,15 +21,15 @@ public data class MetaListener(
)
public interface ObservableMeta : Meta {
fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit)
fun removeListener(owner: Any?)
public fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit)
public fun removeListener(owner: Any?)
}
/**
* Mutable meta representing object state
*/
@Serializable
class Config : AbstractMutableMeta<Config>(), ObservableMeta {
public class Config : AbstractMutableMeta<Config>(), ObservableMeta {
private val listeners = HashSet<MetaListener>()
@ -78,10 +75,11 @@ class Config : AbstractMutableMeta<Config>(), ObservableMeta {
override fun empty(): Config = Config()
@OptIn(ExperimentalSerializationApi::class)
@Serializer(Config::class)
companion object ConfigSerializer : KSerializer<Config> {
public companion object ConfigSerializer : KSerializer<Config> {
fun empty(): Config = Config()
public fun empty(): Config = Config()
override val descriptor: SerialDescriptor get() = MetaSerializer.descriptor
override fun deserialize(decoder: Decoder): Config {
@ -94,9 +92,9 @@ class Config : AbstractMutableMeta<Config>(), ObservableMeta {
}
}
operator fun Config.get(token: NameToken): MetaItem<Config>? = items[token]
public operator fun Config.get(token: NameToken): MetaItem<Config>? = items[token]
fun Meta.asConfig(): Config = this as? Config ?: Config().also { builder ->
public fun Meta.asConfig(): Config = this as? Config ?: Config().also { builder ->
this.items.mapValues { entry ->
val item = entry.value
builder[entry.key.asName()] = when (item) {

View File

@ -14,21 +14,21 @@ import kotlin.reflect.KProperty
* It is not possible to know if some property is declared by provider just by looking on [Configurable],
* this information should be provided externally.
*/
interface Configurable : Described, MutableItemProvider {
public interface Configurable : Described, MutableItemProvider {
/**
* Backing config
*/
val config: Config
public val config: Config
/**
* Default meta item provider
*/
fun getDefaultItem(name: Name): MetaItem<*>? = null
public fun getDefaultItem(name: Name): MetaItem<*>? = null
/**
* Check if property with given [name] could be assigned to [item]
*/
fun validateItem(name: Name, item: MetaItem<*>?): Boolean {
public fun validateItem(name: Name, item: MetaItem<*>?): Boolean {
val descriptor = descriptor?.get(name)
return descriptor?.validateItem(item) ?: true
}
@ -53,40 +53,32 @@ interface Configurable : Described, MutableItemProvider {
}
}
/**
* Reset the property to its default value
*/
@Deprecated("To be removed since unused", ReplaceWith("setItem(name, null)"))
fun Configurable.resetProperty(name: Name) {
setItem(name, null)
}
public fun Configurable.getItem(key: String): MetaItem<*>? = getItem(key.toName())
fun Configurable.getItem(key: String) = getItem(key.toName())
public fun Configurable.setItem(name: Name, value: Value?): Unit = setItem(name, value?.let { MetaItem.ValueItem(value) })
public fun Configurable.setItem(name: Name, meta: Meta?): Unit = setItem(name, meta?.let { MetaItem.NodeItem(meta) })
fun Configurable.setItem(name: Name, value: Value?) = setItem(name, value?.let { MetaItem.ValueItem(value) })
fun Configurable.setItem(name: Name, meta: Meta?) = setItem(name, meta?.let { MetaItem.NodeItem(meta) })
public fun Configurable.setItem(key: String, item: MetaItem<*>?): Unit = setItem(key.toName(), item)
fun Configurable.setItem(key: String, item: MetaItem<*>?) = setItem(key.toName(), item)
public fun Configurable.setItem(key: String, value: Value?): Unit = setItem(key, value?.let { MetaItem.ValueItem(value) })
public fun Configurable.setItem(key: String, meta: Meta?): Unit = setItem(key, meta?.let { MetaItem.NodeItem(meta) })
fun Configurable.setItem(key: String, value: Value?) = setItem(key, value?.let { MetaItem.ValueItem(value) })
fun Configurable.setItem(key: String, meta: Meta?) = setItem(key, meta?.let { MetaItem.NodeItem(meta) })
fun <T : Configurable> T.configure(meta: Meta): T = this.apply { config.update(meta) }
public fun <T : Configurable> T.configure(meta: Meta): T = this.apply { config.update(meta) }
@DFBuilder
inline fun <T : Configurable> T.configure(action: Config.() -> Unit): T = apply { config.apply(action) }
public inline fun <T : Configurable> T.configure(action: Config.() -> Unit): T = apply { config.apply(action) }
/* Node delegates */
fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> =
public fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> =
config.node(key)
fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item(key).convert(
public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item(key).convert(
reader = { it.node },
writer = { it?.let { MetaItem.NodeItem(it) } }
)
fun <T : Configurable> Configurable.spec(
public fun <T : Configurable> Configurable.spec(
spec: Specification<T>, key: Name? = null
): ReadWriteProperty<Any?, T?> = object : ReadWriteProperty<Any?, T?> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
@ -100,7 +92,7 @@ fun <T : Configurable> Configurable.spec(
}
}
fun <T : Configurable> Configurable.spec(
public fun <T : Configurable> Configurable.spec(
spec: Specification<T>, default: T, key: Name? = null
): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T {

View File

@ -19,7 +19,7 @@ open class ItemDelegate(
}
}
fun ItemProvider.item(key: Name? = null): ItemDelegate = ItemDelegate(this, key)
public fun ItemProvider.item(key: Name? = null): ItemDelegate = ItemDelegate(this, key)
//TODO add caching for sealed nodes
@ -29,62 +29,62 @@ fun ItemProvider.item(key: Name? = null): ItemDelegate = ItemDelegate(this, key)
/**
* A property delegate that uses custom key
*/
fun ItemProvider.value(key: Name? = null): ReadOnlyProperty<Any?, Value?> =
public fun ItemProvider.value(key: Name? = null): ReadOnlyProperty<Any?, Value?> =
item(key).convert(MetaConverter.value)
fun ItemProvider.string(key: Name? = null): ReadOnlyProperty<Any?, String?> =
public fun ItemProvider.string(key: Name? = null): ReadOnlyProperty<Any?, String?> =
item(key).convert(MetaConverter.string)
fun ItemProvider.boolean(key: Name? = null): ReadOnlyProperty<Any?, Boolean?> =
public fun ItemProvider.boolean(key: Name? = null): ReadOnlyProperty<Any?, Boolean?> =
item(key).convert(MetaConverter.boolean)
fun ItemProvider.number(key: Name? = null): ReadOnlyProperty<Any?, Number?> =
public fun ItemProvider.number(key: Name? = null): ReadOnlyProperty<Any?, Number?> =
item(key).convert(MetaConverter.number)
fun ItemProvider.double(key: Name? = null): ReadOnlyProperty<Any?, Double?> =
public fun ItemProvider.double(key: Name? = null): ReadOnlyProperty<Any?, Double?> =
item(key).convert(MetaConverter.double)
fun ItemProvider.float(key: Name? = null): ReadOnlyProperty<Any?, Float?> =
public fun ItemProvider.float(key: Name? = null): ReadOnlyProperty<Any?, Float?> =
item(key).convert(MetaConverter.float)
fun ItemProvider.int(key: Name? = null): ReadOnlyProperty<Any?, Int?> =
public fun ItemProvider.int(key: Name? = null): ReadOnlyProperty<Any?, Int?> =
item(key).convert(MetaConverter.int)
fun ItemProvider.long(key: Name? = null): ReadOnlyProperty<Any?, Long?> =
public fun ItemProvider.long(key: Name? = null): ReadOnlyProperty<Any?, Long?> =
item(key).convert(MetaConverter.long)
fun ItemProvider.node(key: Name? = null): ReadOnlyProperty<Any?, Meta?> =
public fun ItemProvider.node(key: Name? = null): ReadOnlyProperty<Any?, Meta?> =
item(key).convert(MetaConverter.meta)
fun ItemProvider.string(default: String, key: Name? = null): ReadOnlyProperty<Any?, String> =
public fun ItemProvider.string(default: String, key: Name? = null): ReadOnlyProperty<Any?, String> =
item(key).convert(MetaConverter.string) { default }
fun ItemProvider.boolean(default: Boolean, key: Name? = null): ReadOnlyProperty<Any?, Boolean> =
public fun ItemProvider.boolean(default: Boolean, key: Name? = null): ReadOnlyProperty<Any?, Boolean> =
item(key).convert(MetaConverter.boolean) { default }
fun ItemProvider.number(default: Number, key: Name? = null): ReadOnlyProperty<Any?, Number> =
public fun ItemProvider.number(default: Number, key: Name? = null): ReadOnlyProperty<Any?, Number> =
item(key).convert(MetaConverter.number) { default }
fun ItemProvider.double(default: Double, key: Name? = null): ReadOnlyProperty<Any?, Double> =
public fun ItemProvider.double(default: Double, key: Name? = null): ReadOnlyProperty<Any?, Double> =
item(key).convert(MetaConverter.double) { default }
fun ItemProvider.float(default: Float, key: Name? = null): ReadOnlyProperty<Any?, Float> =
public fun ItemProvider.float(default: Float, key: Name? = null): ReadOnlyProperty<Any?, Float> =
item(key).convert(MetaConverter.float) { default }
fun ItemProvider.int(default: Int, key: Name? = null): ReadOnlyProperty<Any?, Int> =
public fun ItemProvider.int(default: Int, key: Name? = null): ReadOnlyProperty<Any?, Int> =
item(key).convert(MetaConverter.int) { default }
fun ItemProvider.long(default: Long, key: Name? = null): ReadOnlyProperty<Any?, Long> =
public fun ItemProvider.long(default: Long, key: Name? = null): ReadOnlyProperty<Any?, Long> =
item(key).convert(MetaConverter.long) { default }
inline fun <reified E : Enum<E>> ItemProvider.enum(default: E, key: Name? = null): ReadOnlyProperty<Any?, E> =
public inline fun <reified E : Enum<E>> ItemProvider.enum(default: E, key: Name? = null): ReadOnlyProperty<Any?, E> =
item(key).convert(MetaConverter.enum()) { default }
fun ItemProvider.string(key: Name? = null, default: () -> String): ReadOnlyProperty<Any?, String> =
public fun ItemProvider.string(key: Name? = null, default: () -> String): ReadOnlyProperty<Any?, String> =
item(key).convert(MetaConverter.string, default)
fun ItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadOnlyProperty<Any?, Boolean> =
public fun ItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadOnlyProperty<Any?, Boolean> =
item(key).convert(MetaConverter.boolean, default)
fun ItemProvider.number(key: Name? = null, default: () -> Number): ReadOnlyProperty<Any?, Number> =
public fun ItemProvider.number(key: Name? = null, default: () -> Number): ReadOnlyProperty<Any?, Number> =
item(key).convert(MetaConverter.number, default)

View File

@ -15,7 +15,7 @@ import kotlinx.serialization.json.*
/**
* @param descriptor reserved for custom serialization in future
*/
fun Value.toJson(descriptor: ValueDescriptor? = null): JsonElement {
public fun Value.toJson(descriptor: ValueDescriptor? = null): JsonElement {
return if (isList()) {
JsonArray(list.map { it.toJson() })
} else {
@ -82,11 +82,11 @@ private fun Meta.toJsonWithIndex(descriptor: NodeDescriptor?, indexValue: String
return JsonObject(elementMap)
}
fun Meta.toJson(descriptor: NodeDescriptor? = null): JsonObject = toJsonWithIndex(descriptor, null)
public fun Meta.toJson(descriptor: NodeDescriptor? = null): JsonObject = toJsonWithIndex(descriptor, null)
fun JsonObject.toMeta(descriptor: NodeDescriptor? = null): JsonMeta = JsonMeta(this, descriptor)
public fun JsonObject.toMeta(descriptor: NodeDescriptor? = null): JsonMeta = JsonMeta(this, descriptor)
fun JsonPrimitive.toValue(descriptor: ValueDescriptor?): Value {
public fun JsonPrimitive.toValue(descriptor: ValueDescriptor?): Value {
return when (this) {
JsonNull -> Null
else -> {
@ -99,7 +99,7 @@ fun JsonPrimitive.toValue(descriptor: ValueDescriptor?): Value {
}
}
fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem<JsonMeta> = when (this) {
public fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem<JsonMeta> = when (this) {
is JsonPrimitive -> {
val value = this.toValue(descriptor as? ValueDescriptor)
MetaItem.ValueItem(value)
@ -129,7 +129,7 @@ fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem<JsonMet
/**
* A meta wrapping json object
*/
class JsonMeta(val json: JsonObject, val descriptor: NodeDescriptor? = null) : MetaBase() {
public class JsonMeta(private val json: JsonObject, private val descriptor: NodeDescriptor? = null) : MetaBase() {
private fun buildItems(): Map<NameToken, MetaItem<JsonMeta>> {
val map = LinkedHashMap<NameToken, MetaItem<JsonMeta>>()
@ -173,10 +173,10 @@ class JsonMeta(val json: JsonObject, val descriptor: NodeDescriptor? = null) : M
override val items: Map<NameToken, MetaItem<JsonMeta>> by lazy(::buildItems)
companion object {
public companion object {
/**
* A key representing top-level json array of nodes, which could not be directly represented by a meta node
*/
const val JSON_ARRAY_KEY = "@jsonArray"
public const val JSON_ARRAY_KEY: String = "@jsonArray"
}
}

View File

@ -7,9 +7,9 @@ import hep.dataforge.names.NameToken
* A meta laminate consisting of multiple immutable meta layers. For mutable front layer, use [Scheme].
* If [layers] list contains a [Laminate] it is flat-mapped.
*/
class Laminate(layers: List<Meta>) : MetaBase() {
public class Laminate(layers: List<Meta>) : MetaBase() {
val layers: List<Meta> = layers.flatMap {
public val layers: List<Meta> = layers.flatMap {
if (it is Laminate) {
it.layers
} else {
@ -17,7 +17,7 @@ class Laminate(layers: List<Meta>) : MetaBase() {
}
}
constructor(vararg layers: Meta?) : this(layers.filterNotNull())
public constructor(vararg layers: Meta?) : this(layers.filterNotNull())
override val items: Map<NameToken, MetaItem<Meta>> by lazy {
layers.map { it.items.keys }.flatten().associateWith { key ->
@ -28,21 +28,21 @@ class Laminate(layers: List<Meta>) : MetaBase() {
/**
* Generate sealed meta using [mergeRule]
*/
fun merge(): SealedMeta {
public fun merge(): SealedMeta {
val items = layers.map { it.items.keys }.flatten().associateWith { key ->
layers.asSequence().map { it.items[key] }.filterNotNull().merge()
}
return SealedMeta(items)
}
companion object {
public companion object {
/**
* The default rule which always uses the first found item in sequence alongside with its children.
*
* TODO add picture
*/
val replaceRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.first().seal() }
public val replaceRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.first().seal() }
private fun Sequence<MetaItem<*>>.merge(): MetaItem<SealedMeta> {
return when {
@ -76,14 +76,14 @@ class Laminate(layers: List<Meta>) : MetaBase() {
* The values a replaced but meta children are joined
* TODO add picture
*/
val mergeRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.merge() }
public val mergeRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.merge() }
}
}
/**
* Performance optimized version of get method
*/
fun Laminate.getFirst(name: Name): MetaItem<*>? {
public fun Laminate.getFirst(name: Name): MetaItem<*>? {
layers.forEach { layer ->
layer[name]?.let { return it }
}
@ -93,11 +93,11 @@ fun Laminate.getFirst(name: Name): MetaItem<*>? {
/**
* Create a new [Laminate] adding given layer to the top
*/
fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers)
public fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers)
/**
* Create a new [Laminate] adding given layer to the bottom
*/
fun Laminate.withBottom(meta: Meta): Laminate = Laminate(layers + meta)
public fun Laminate.withBottom(meta: Meta): Laminate = Laminate(layers + meta)
//TODO add custom rules for Laminate merge

View File

@ -5,6 +5,7 @@ import hep.dataforge.meta.MetaItem.NodeItem
import hep.dataforge.meta.MetaItem.ValueItem
import hep.dataforge.names.*
import hep.dataforge.values.*
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
@ -19,18 +20,19 @@ import kotlinx.serialization.encoding.Encoder
* * a [NodeItem] (node)
*/
@Serializable
sealed class MetaItem<out M : Meta> {
public sealed class MetaItem<out M : Meta> {
abstract override fun equals(other: Any?): Boolean
abstract override fun hashCode(): Int
@Serializable
class ValueItem(val value: Value) : MetaItem<Nothing>() {
public class ValueItem(public val value: Value) : MetaItem<Nothing>() {
override fun toString(): String = value.toString()
@OptIn(ExperimentalSerializationApi::class)
@Serializer(ValueItem::class)
companion object : KSerializer<ValueItem> {
public companion object : KSerializer<ValueItem> {
override val descriptor: SerialDescriptor get() = ValueSerializer.descriptor
override fun deserialize(decoder: Decoder): ValueItem = ValueItem(ValueSerializer.deserialize(decoder))
@ -50,12 +52,13 @@ sealed class MetaItem<out M : Meta> {
}
@Serializable
class NodeItem<M : Meta>(@Serializable(MetaSerializer::class) val node: M) : MetaItem<M>() {
public class NodeItem<M : Meta>(@Serializable(MetaSerializer::class) public val node: M) : MetaItem<M>() {
//Fixing serializer for node could cause class cast problems, but it should not since Meta descendants are not serializeable
override fun toString(): String = node.toString()
@OptIn(ExperimentalSerializationApi::class)
@Serializer(NodeItem::class)
companion object : KSerializer<NodeItem<out Meta>> {
public companion object : KSerializer<NodeItem<out Meta>> {
override val descriptor: SerialDescriptor get() = MetaSerializer.descriptor
override fun deserialize(decoder: Decoder): NodeItem<*> = NodeItem(MetaSerializer.deserialize(decoder))
@ -70,8 +73,8 @@ sealed class MetaItem<out M : Meta> {
override fun hashCode(): Int = node.hashCode()
}
companion object {
fun of(arg: Any?): MetaItem<*> {
public companion object {
public fun of(arg: Any?): MetaItem<*> {
return when (arg) {
null -> ValueItem(Null)
is MetaItem<*> -> arg
@ -82,19 +85,19 @@ sealed class MetaItem<out M : Meta> {
}
}
fun Value.asMetaItem() = ValueItem(this)
fun <M:Meta> M.asMetaItem() = NodeItem(this)
public fun Value.asMetaItem(): ValueItem = ValueItem(this)
public fun <M:Meta> M.asMetaItem(): NodeItem<M> = NodeItem(this)
/**
* The object that could be represented as [Meta]. Meta provided by [toMeta] method should fully represent object state.
* Meaning that two states with the same meta are equal.
*/
interface MetaRepr {
fun toMeta(): Meta
public interface MetaRepr {
public fun toMeta(): Meta
}
interface ItemProvider{
fun getItem(name: Name): MetaItem<*>?
public interface ItemProvider{
public fun getItem(name: Name): MetaItem<*>?
}
/**
@ -104,11 +107,11 @@ interface ItemProvider{
*
* * Same name siblings are supported via elements with the same [Name] but different queries
*/
interface Meta : MetaRepr, ItemProvider {
public interface Meta : MetaRepr, ItemProvider {
/**
* Top level items of meta tree
*/
val items: Map<NameToken, MetaItem<*>>
public val items: Map<NameToken, MetaItem<*>>
override fun getItem(name: Name): MetaItem<*>? {
if (name.isEmpty()) return NodeItem(this)
@ -129,15 +132,15 @@ interface Meta : MetaRepr, ItemProvider {
override fun toString(): String
companion object {
const val TYPE = "meta"
public companion object {
public const val TYPE: String = "meta"
/**
* A key for single value node
*/
const val VALUE_KEY = "@value"
public const val VALUE_KEY: String = "@value"
val EMPTY: Meta = object: MetaBase() {
public val EMPTY: Meta = object: MetaBase() {
override val items: Map<NameToken, MetaItem<*>> = emptyMap()
}
}
@ -150,19 +153,19 @@ interface Meta : MetaRepr, ItemProvider {
*
* If [name] is empty return current [Meta] as a [NodeItem]
*/
operator fun Meta?.get(name: Name): MetaItem<*>? = this?.getItem(name)
public operator fun Meta?.get(name: Name): MetaItem<*>? = this?.getItem(name)
operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
public operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
/**
* Parse [Name] from [key] using full name notation and pass it to [Meta.get]
*/
operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName())
public operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName())
/**
* Get a sequence of [Name]-[Value] pairs
*/
fun Meta.values(): Sequence<Pair<Name, Value>> {
public fun Meta.values(): Sequence<Pair<Name, Value>> {
return items.asSequence().flatMap { (key, item) ->
when (item) {
is ValueItem -> sequenceOf(key.asName() to item.value)
@ -174,7 +177,7 @@ fun Meta.values(): Sequence<Pair<Name, Value>> {
/**
* Get a sequence of all [Name]-[MetaItem] pairs for all items including nodes
*/
fun Meta.sequence(): Sequence<Pair<Name, MetaItem<*>>> {
public fun Meta.sequence(): Sequence<Pair<Name, MetaItem<*>>> {
return sequence {
items.forEach { (key, item) ->
yield(key.asName() to item)
@ -187,33 +190,33 @@ fun Meta.sequence(): Sequence<Pair<Name, MetaItem<*>>> {
}
}
operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = sequence().iterator()
public operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = sequence().iterator()
/**
* A meta node that ensures that all of its descendants has at least the same type
*/
interface MetaNode<out M : MetaNode<M>> : Meta {
public interface MetaNode<out M : MetaNode<M>> : Meta {
override val items: Map<NameToken, MetaItem<M>>
}
/**
* The same as [Meta.get], but with specific node type
*/
operator fun <M : MetaNode<M>> M?.get(name: Name): MetaItem<M>? = if( this == null) {
public operator fun <M : MetaNode<M>> M?.get(name: Name): MetaItem<M>? = if( this == null) {
null
} else {
@Suppress("UNCHECKED_CAST", "ReplaceGetOrSet")
(this as Meta).get(name) as MetaItem<M>? // Do not change
}
operator fun <M : MetaNode<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()]
public operator fun <M : MetaNode<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()]
operator fun <M : MetaNode<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()]
public operator fun <M : MetaNode<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()]
/**
* Equals, hashcode and to string for any meta
*/
abstract class MetaBase : Meta {
public abstract class MetaBase : Meta {
override fun equals(other: Any?): Boolean = if (other is Meta) {
this.items == other.items
@ -229,24 +232,24 @@ abstract class MetaBase : Meta {
/**
* Equals and hash code implementation for meta node
*/
abstract class AbstractMetaNode<M : MetaNode<M>> : MetaNode<M>, MetaBase()
public abstract class AbstractMetaNode<M : MetaNode<M>> : MetaNode<M>, MetaBase()
/**
* The meta implementation which is guaranteed to be immutable.
*
* If the argument is possibly mutable node, it is copied on creation
*/
class SealedMeta internal constructor(
public class SealedMeta internal constructor(
override val items: Map<NameToken, MetaItem<SealedMeta>>
) : AbstractMetaNode<SealedMeta>()
/**
* Generate sealed node from [this]. If it is already sealed return it as is
*/
fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta(items.mapValues { entry -> entry.value.seal() })
public fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta(items.mapValues { entry -> entry.value.seal() })
@Suppress("UNCHECKED_CAST")
fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) {
public fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) {
is ValueItem -> this
is NodeItem -> NodeItem(node.seal())
}
@ -254,32 +257,32 @@ fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) {
/**
* Unsafe methods to access values and nodes directly from [MetaItem]
*/
val MetaItem<*>?.value: Value?
public val MetaItem<*>?.value: Value?
get() = (this as? ValueItem)?.value
?: (this?.node?.get(VALUE_KEY) as? ValueItem)?.value
val MetaItem<*>?.string get() = value?.string
val MetaItem<*>?.boolean get() = value?.boolean
val MetaItem<*>?.number get() = value?.number
val MetaItem<*>?.double get() = number?.toDouble()
val MetaItem<*>?.float get() = number?.toFloat()
val MetaItem<*>?.int get() = number?.toInt()
val MetaItem<*>?.long get() = number?.toLong()
val MetaItem<*>?.short get() = number?.toShort()
public val MetaItem<*>?.string: String? get() = value?.string
public val MetaItem<*>?.boolean: Boolean? get() = value?.boolean
public val MetaItem<*>?.number: Number? get() = value?.number
public val MetaItem<*>?.double: Double? get() = number?.toDouble()
public val MetaItem<*>?.float: Float? get() = number?.toFloat()
public val MetaItem<*>?.int: Int? get() = number?.toInt()
public val MetaItem<*>?.long: Long? get() = number?.toLong()
public val MetaItem<*>?.short: Short? get() = number?.toShort()
inline fun <reified E : Enum<E>> MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) {
public inline fun <reified E : Enum<E>> MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) {
this.value.value as E
} else {
string?.let { enumValueOf<E>(it) }
}
val MetaItem<*>.stringList get() = value?.list?.map { it.string }
public val MetaItem<*>.stringList: List<String>? get() = value?.list?.map { it.string }
val <M : Meta> MetaItem<M>?.node: M?
public val <M : Meta> MetaItem<M>?.node: M?
get() = when (this) {
null -> null
is ValueItem -> null//error("Trying to interpret value meta item as node item")
is NodeItem -> node
}
fun Meta.isEmpty() = this === Meta.EMPTY || this.items.isEmpty()
public fun Meta.isEmpty(): Boolean = this === Meta.EMPTY || this.items.isEmpty()

View File

@ -4,19 +4,19 @@ plugins {
kotlin {
sourceSets {
val commonMain by getting {
commonMain {
dependencies {
api(project(":dataforge-workspace"))
implementation(kotlin("scripting-common"))
}
}
val jvmMain by getting {
jvmMain{
dependencies {
implementation(kotlin("scripting-jvm-host"))
implementation(kotlin("scripting-jvm"))
}
}
val jvmTest by getting {
jvmTest {
dependencies {
implementation("ch.qos.logback:logback-classic:1.2.3")
}

View File

@ -1,4 +0,0 @@
package hep.dataforge.scripting
internal object Placeholder {
}

View File

@ -13,15 +13,18 @@ import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
import kotlin.script.experimental.jvm.jvm
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
object Builders {
public object Builders {
fun buildWorkspace(source: SourceCode, context: Context = Global): Workspace {
private fun buildWorkspace(source: SourceCode, context: Context = Global): Workspace {
val builder = SimpleWorkspaceBuilder(context)
val workspaceScriptConfiguration = ScriptCompilationConfiguration {
baseClass(Any::class)
// baseClass(Any::class)
implicitReceivers(WorkspaceBuilder::class)
defaultImports("hep.dataforge.workspace.*")
defaultImports(
"hep.dataforge.meta.*",
"hep.dataforge.workspace.*"
)
jvm {
dependenciesFromCurrentContext(wholeClasspath = true)
}
@ -49,7 +52,7 @@ object Builders {
return builder.build()
}
fun buildWorkspace(file: File): Workspace = buildWorkspace(file.toScriptSource())
public fun buildWorkspace(file: File): Workspace = buildWorkspace(file.toScriptSource())
fun buildWorkspace(string: String): Workspace = buildWorkspace(string.toScriptSource())
public fun buildWorkspace(string: String): Workspace = buildWorkspace(string.toScriptSource())
}

View File

@ -4,7 +4,7 @@ plugins {
kotlin {
sourceSets {
val commonMain by getting{
commonMain{
dependencies {
api(project(":dataforge-context"))
api(project(":dataforge-data"))

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

2
gradlew vendored
View File

@ -130,7 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath

21
gradlew.bat vendored
View File

@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell

View File

@ -5,12 +5,20 @@ pluginManagement {
gradlePluginPortal()
maven("https://dl.bintray.com/kotlin/kotlin-eap")
maven("https://dl.bintray.com/kotlin/kotlinx")
maven("https://dl.bintray.com/mipt-npm/scientifik")
maven("https://dl.bintray.com/mipt-npm/kscience")
maven("https://dl.bintray.com/mipt-npm/dev")
}
val toolsVersion = "0.6.0"
val kotlinVersion = "1.4.0"
plugins {
kotlin("jvm") version kotlinVersion
id("scientifik.mpp") version toolsVersion
id("scientifik.jvm") version toolsVersion
id("scientifik.js") version toolsVersion
id("scientifik.publish") version toolsVersion
}
resolutionStrategy {
eachPlugin {