diff --git a/build.gradle.kts b/build.gradle.kts index 129a3adc..09240c13 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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") diff --git a/dataforge-context/build.gradle.kts b/dataforge-context/build.gradle.kts index 90a7a7a3..a41e4443 100644 --- a/dataforge-context/build.gradle.kts +++ b/dataforge-context/build.gradle.kts @@ -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 { diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt index 21301dd4..db8b7ab5 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt @@ -20,12 +20,12 @@ inline fun Data.upcast(): Data = upcast(R::class) /** * Check if node could be safely cast to given class */ -expect fun DataNode<*>.canCast(type: KClass): Boolean +internal expect fun DataNode<*>.canCast(type: KClass): Boolean /** * Check if data could be safely cast to given class */ -expect fun Data<*>.canCast(type: KClass): Boolean +internal expect fun Data<*>.canCast(type: KClass): Boolean fun DataItem<*>.canCast(type: KClass): Boolean = when (this) { is DataItem.Node -> node.canCast(type) diff --git a/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt b/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt index 54148bc5..afdb032e 100644 --- a/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt +++ b/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt @@ -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 DataNode<*>.canCast(type: KClass): Boolean { +internal actual fun DataNode<*>.canCast(type: KClass): Boolean { //Not supported in js yet return true } -actual fun Data<*>.canCast(type: KClass): Boolean { +internal actual fun Data<*>.canCast(type: KClass): Boolean { //Not supported in js yet return true } diff --git a/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt b/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt index f354c2f7..e385acc3 100644 --- a/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt +++ b/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt @@ -8,28 +8,28 @@ import kotlin.reflect.full.isSuperclassOf /** * Block the thread and get data content */ -fun Data.get(): T = runBlocking { await() } +public fun Data.get(): T = runBlocking { await() } /** * Check that node is compatible with given type meaning that each element could be cast to the type */ -actual fun DataNode<*>.canCast(type: KClass): Boolean = +internal actual fun DataNode<*>.canCast(type: KClass): Boolean = type.isSuperclassOf(type) -actual fun Data<*>.canCast(type: KClass): Boolean = +internal actual fun Data<*>.canCast(type: KClass): Boolean = this.type.isSubclassOf(type) /** * Cast the node to given type if the cast is possible or return null */ -fun Data<*>.filterIsInstance(type: KClass): Data? = +public fun Data<*>.filterIsInstance(type: KClass): Data? = 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 DataNode<*>.filterIsInstance(type: KClass): DataNode { +public fun DataNode<*>.filterIsInstance(type: KClass): DataNode { return when { canCast(type) -> cast(type) this is TypeFilteredDataNode -> origin.filterIsInstance(type) diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Consumer.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Consumer.kt new file mode 100644 index 00000000..0ef5d327 --- /dev/null +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Consumer.kt @@ -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 +} \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt index c0214e7b..2710ffa9 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt @@ -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 -} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt index 376663d0..89d944a7 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt @@ -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(), ObservableMeta { +public class Config : AbstractMutableMeta(), ObservableMeta { private val listeners = HashSet() @@ -78,10 +75,11 @@ class Config : AbstractMutableMeta(), ObservableMeta { override fun empty(): Config = Config() + @OptIn(ExperimentalSerializationApi::class) @Serializer(Config::class) - companion object ConfigSerializer : KSerializer { + public companion object ConfigSerializer : KSerializer { - 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(), ObservableMeta { } } -operator fun Config.get(token: NameToken): MetaItem? = items[token] +public operator fun Config.get(token: NameToken): MetaItem? = 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) { diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt index a984b897..9fd6cdb3 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt @@ -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.configure(meta: Meta): T = this.apply { config.update(meta) } +public fun T.configure(meta: Meta): T = this.apply { config.update(meta) } @DFBuilder -inline fun T.configure(action: Config.() -> Unit): T = apply { config.apply(action) } +public inline fun T.configure(action: Config.() -> Unit): T = apply { config.apply(action) } /* Node delegates */ -fun Configurable.config(key: Name? = null): ReadWriteProperty = +public fun Configurable.config(key: Name? = null): ReadWriteProperty = config.node(key) -fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty = item(key).convert( +public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty = item(key).convert( reader = { it.node }, writer = { it?.let { MetaItem.NodeItem(it) } } ) -fun Configurable.spec( +public fun Configurable.spec( spec: Specification, key: Name? = null ): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Any?, property: KProperty<*>): T? { @@ -100,7 +92,7 @@ fun Configurable.spec( } } -fun Configurable.spec( +public fun Configurable.spec( spec: Specification, default: T, key: Name? = null ): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Any?, property: KProperty<*>): T { diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt index cffedd82..830f4a2c 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt @@ -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 = +public fun ItemProvider.value(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.value) -fun ItemProvider.string(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.string(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.string) -fun ItemProvider.boolean(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.boolean(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.boolean) -fun ItemProvider.number(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.number(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.number) -fun ItemProvider.double(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.double(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.double) -fun ItemProvider.float(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.float(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.float) -fun ItemProvider.int(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.int(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.int) -fun ItemProvider.long(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.long(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.long) -fun ItemProvider.node(key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.node(key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.meta) -fun ItemProvider.string(default: String, key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.string(default: String, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.string) { default } -fun ItemProvider.boolean(default: Boolean, key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.boolean(default: Boolean, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.boolean) { default } -fun ItemProvider.number(default: Number, key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.number(default: Number, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.number) { default } -fun ItemProvider.double(default: Double, key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.double(default: Double, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.double) { default } -fun ItemProvider.float(default: Float, key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.float(default: Float, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.float) { default } -fun ItemProvider.int(default: Int, key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.int(default: Int, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.int) { default } -fun ItemProvider.long(default: Long, key: Name? = null): ReadOnlyProperty = +public fun ItemProvider.long(default: Long, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.long) { default } -inline fun > ItemProvider.enum(default: E, key: Name? = null): ReadOnlyProperty = +public inline fun > ItemProvider.enum(default: E, key: Name? = null): ReadOnlyProperty = item(key).convert(MetaConverter.enum()) { default } -fun ItemProvider.string(key: Name? = null, default: () -> String): ReadOnlyProperty = +public fun ItemProvider.string(key: Name? = null, default: () -> String): ReadOnlyProperty = item(key).convert(MetaConverter.string, default) -fun ItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadOnlyProperty = +public fun ItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadOnlyProperty = item(key).convert(MetaConverter.boolean, default) -fun ItemProvider.number(key: Name? = null, default: () -> Number): ReadOnlyProperty = +public fun ItemProvider.number(key: Name? = null, default: () -> Number): ReadOnlyProperty = item(key).convert(MetaConverter.number, default) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt index 582890cf..debd05c8 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt @@ -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 = when (this) { +public fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem = 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> { val map = LinkedHashMap>() @@ -173,10 +173,10 @@ class JsonMeta(val json: JsonObject, val descriptor: NodeDescriptor? = null) : M override val items: Map> 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" } } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt index 7dec0790..96f42b46 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt @@ -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) : MetaBase() { +public class Laminate(layers: List) : MetaBase() { - val layers: List = layers.flatMap { + public val layers: List = layers.flatMap { if (it is Laminate) { it.layers } else { @@ -17,7 +17,7 @@ class Laminate(layers: List) : MetaBase() { } } - constructor(vararg layers: Meta?) : this(layers.filterNotNull()) + public constructor(vararg layers: Meta?) : this(layers.filterNotNull()) override val items: Map> by lazy { layers.map { it.items.keys }.flatten().associateWith { key -> @@ -28,21 +28,21 @@ class Laminate(layers: List) : 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 = { it.first().seal() } + public val replaceRule: (Sequence>) -> MetaItem = { it.first().seal() } private fun Sequence>.merge(): MetaItem { return when { @@ -76,14 +76,14 @@ class Laminate(layers: List) : MetaBase() { * The values a replaced but meta children are joined * TODO add picture */ - val mergeRule: (Sequence>) -> MetaItem = { it.merge() } + public val mergeRule: (Sequence>) -> MetaItem = { 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 diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt index 25d89860..fdbdab72 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt @@ -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 { +public sealed class MetaItem { abstract override fun equals(other: Any?): Boolean abstract override fun hashCode(): Int @Serializable - class ValueItem(val value: Value) : MetaItem() { + public class ValueItem(public val value: Value) : MetaItem() { override fun toString(): String = value.toString() + @OptIn(ExperimentalSerializationApi::class) @Serializer(ValueItem::class) - companion object : KSerializer { + public companion object : KSerializer { override val descriptor: SerialDescriptor get() = ValueSerializer.descriptor override fun deserialize(decoder: Decoder): ValueItem = ValueItem(ValueSerializer.deserialize(decoder)) @@ -50,12 +52,13 @@ sealed class MetaItem { } @Serializable - class NodeItem(@Serializable(MetaSerializer::class) val node: M) : MetaItem() { + public class NodeItem(@Serializable(MetaSerializer::class) public val node: M) : MetaItem() { //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> { + public companion object : KSerializer> { override val descriptor: SerialDescriptor get() = MetaSerializer.descriptor override fun deserialize(decoder: Decoder): NodeItem<*> = NodeItem(MetaSerializer.deserialize(decoder)) @@ -70,8 +73,8 @@ sealed class MetaItem { 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 { } } -fun Value.asMetaItem() = ValueItem(this) -fun M.asMetaItem() = NodeItem(this) +public fun Value.asMetaItem(): ValueItem = ValueItem(this) +public fun M.asMetaItem(): NodeItem = 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> + public val items: Map> 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> = 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> { +public fun Meta.values(): Sequence> { return items.asSequence().flatMap { (key, item) -> when (item) { is ValueItem -> sequenceOf(key.asName() to item.value) @@ -174,7 +177,7 @@ fun Meta.values(): Sequence> { /** * Get a sequence of all [Name]-[MetaItem] pairs for all items including nodes */ -fun Meta.sequence(): Sequence>> { +public fun Meta.sequence(): Sequence>> { return sequence { items.forEach { (key, item) -> yield(key.asName() to item) @@ -187,33 +190,33 @@ fun Meta.sequence(): Sequence>> { } } -operator fun Meta.iterator(): Iterator>> = sequence().iterator() +public operator fun Meta.iterator(): Iterator>> = sequence().iterator() /** * A meta node that ensures that all of its descendants has at least the same type */ -interface MetaNode> : Meta { +public interface MetaNode> : Meta { override val items: Map> } /** * The same as [Meta.get], but with specific node type */ -operator fun > M?.get(name: Name): MetaItem? = if( this == null) { +public operator fun > M?.get(name: Name): MetaItem? = if( this == null) { null } else { @Suppress("UNCHECKED_CAST", "ReplaceGetOrSet") (this as Meta).get(name) as MetaItem? // Do not change } -operator fun > M?.get(key: String): MetaItem? = this[key.toName()] +public operator fun > M?.get(key: String): MetaItem? = this[key.toName()] -operator fun > M?.get(key: NameToken): MetaItem? = this[key.asName()] +public operator fun > M?.get(key: NameToken): MetaItem? = 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> : MetaNode, MetaBase() +public abstract class AbstractMetaNode> : MetaNode, 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> ) : AbstractMetaNode() /** * 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 = when (this) { +public fun MetaItem<*>.seal(): MetaItem = when (this) { is ValueItem -> this is NodeItem -> NodeItem(node.seal()) } @@ -254,32 +257,32 @@ fun MetaItem<*>.seal(): MetaItem = 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 > MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) { +public inline fun > MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) { this.value.value as E } else { string?.let { enumValueOf(it) } } -val MetaItem<*>.stringList get() = value?.list?.map { it.string } +public val MetaItem<*>.stringList: List? get() = value?.list?.map { it.string } -val MetaItem?.node: M? +public val MetaItem?.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() \ No newline at end of file +public fun Meta.isEmpty(): Boolean = this === Meta.EMPTY || this.items.isEmpty() \ No newline at end of file diff --git a/dataforge-scripting/build.gradle.kts b/dataforge-scripting/build.gradle.kts index 16ab6559..9eb40708 100644 --- a/dataforge-scripting/build.gradle.kts +++ b/dataforge-scripting/build.gradle.kts @@ -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") } diff --git a/dataforge-scripting/src/commonMain/kotlin/hep/dataforge/scripting/Placeholder.kt b/dataforge-scripting/src/commonMain/kotlin/hep/dataforge/scripting/Placeholder.kt deleted file mode 100644 index a09e35c1..00000000 --- a/dataforge-scripting/src/commonMain/kotlin/hep/dataforge/scripting/Placeholder.kt +++ /dev/null @@ -1,4 +0,0 @@ -package hep.dataforge.scripting - -internal object Placeholder { -} \ No newline at end of file diff --git a/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt b/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt index 2df5a183..e8b1d378 100644 --- a/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt +++ b/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt @@ -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()) } \ No newline at end of file diff --git a/dataforge-workspace/build.gradle.kts b/dataforge-workspace/build.gradle.kts index 5d745ff8..0c1972cd 100644 --- a/dataforge-workspace/build.gradle.kts +++ b/dataforge-workspace/build.gradle.kts @@ -4,7 +4,7 @@ plugins { kotlin { sourceSets { - val commonMain by getting{ + commonMain{ dependencies { api(project(":dataforge-context")) api(project(":dataforge-data")) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053..e708b1c0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 622ab64a..12d38de6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/gradlew b/gradlew index fbd7c515..4f906e0c 100755 --- a/gradlew +++ b/gradlew @@ -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 diff --git a/gradlew.bat b/gradlew.bat index 5093609d..107acd32 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -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 diff --git a/settings.gradle.kts b/settings.gradle.kts index 2433e4dd..7be55542 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -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 {