From d170f5d60c62128ee482a3669ecccf750feb3755 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 9 Sep 2020 10:22:15 +0300 Subject: [PATCH] Explicit API mode --- .../kotlin/hep/dataforge/context/Factory.kt | 4 +- .../kotlin/hep/dataforge/context/Named.kt | 13 +++--- .../kotlin/hep/dataforge/context/Plugin.kt | 24 ++++------- .../hep/dataforge/context/PluginManager.kt | 36 ++++++++-------- .../kotlin/hep/dataforge/provider/Path.kt | 26 ++++++------ .../kotlin/hep/dataforge/provider/Provider.kt | 18 ++++---- .../kotlin/hep/dataforge/provider/Type.kt | 2 +- .../kotlin/hep/dataforge/data/Action.kt | 8 ++-- .../hep/dataforge/data/CoroutineMonitor.kt | 42 ++++++++++++------- .../kotlin/hep/dataforge/data/Data.kt | 2 +- .../meta/transformations/MetaConverter.kt | 40 +++++++++--------- .../transformations/MetaTransformation.kt | 38 ++++++++--------- .../hep/dataforge/values/valueExtensions.kt | 2 +- .../dataforge/workspace/WorkspacePlugin.kt | 2 +- 14 files changed, 126 insertions(+), 131 deletions(-) diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt index b01334e6..b8858a13 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt @@ -2,6 +2,6 @@ package hep.dataforge.context import hep.dataforge.meta.Meta -interface Factory { - operator fun invoke(meta: Meta = Meta.EMPTY, context: Context = Global): T +public interface Factory { + public operator fun invoke(meta: Meta = Meta.EMPTY, context: Context = Global): T } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt index 9e9db17f..e32946e0 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt @@ -24,16 +24,14 @@ import hep.dataforge.names.isEmpty * * @author Alexander Nozik */ -interface Named { +public interface Named { /** * The name of this object instance - * - * @return */ - val name: Name + public val name: Name - companion object { + public companion object { /** * Get the name of given object. If object is Named its name is used, @@ -42,7 +40,7 @@ interface Named { * @param obj * @return */ - fun nameOf(obj: Any): Name { + public fun nameOf(obj: Any): Name { return if (obj is Named) { obj.name } else { @@ -56,5 +54,4 @@ interface Named { * Check if this object has an empty name and therefore is anonymous. * @return */ -val Named.isAnonymous: Boolean - get() = this.name.isEmpty() +public val Named.isAnonymous: Boolean get() = this.name.isEmpty() diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt index bcc331c0..b8bc6601 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt @@ -22,21 +22,17 @@ import hep.dataforge.provider.Provider * * @author Alexander Nozik */ -interface Plugin : Named, ContextAware, Provider, MetaRepr { +public interface Plugin : Named, ContextAware, Provider, MetaRepr { /** * Get tag for this plugin - * - * @return */ - val tag: PluginTag + public val tag: PluginTag - val meta: Meta + public val meta: Meta /** * The name of this plugin ignoring version and group - * - * @return */ override val name: Name get() = tag.name.toName() @@ -44,25 +40,21 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr { * Plugin dependencies which are required to attach this plugin. Plugin * dependencies must be initialized and enabled in the Context before this * plugin is enabled. - * - * @return */ - fun dependsOn(): Collection> + public fun dependsOn(): Collection> /** * Start this plugin and attach registration info to the context. This method * should be called only via PluginManager to avoid dependency issues. - * - * @param context */ - fun attach(context: Context) + public fun attach(context: Context) /** * Stop this plugin and remove registration info from context and other * plugins. This method should be called only via PluginManager to avoid * dependency issues. */ - fun detach() + public fun detach() override fun toMeta(): Meta = Meta { "context" put context.name.toString() @@ -71,9 +63,9 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr { "meta" put meta } - companion object { + public companion object { - const val PLUGIN_TARGET = "plugin" + public const val PLUGIN_TARGET = "plugin" } } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt index 4f4a062a..dadb333e 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt @@ -5,12 +5,12 @@ import hep.dataforge.meta.MetaBuilder import kotlin.reflect.KClass -interface PluginFactory : Factory { - val tag: PluginTag - val type: KClass +public interface PluginFactory : Factory { + public val tag: PluginTag + public val type: KClass - companion object{ - const val TYPE = "pluginFactory" + public companion object{ + public const val TYPE: String = "pluginFactory" } } @@ -21,7 +21,7 @@ interface PluginFactory : Factory { * @property context A context for this plugin manager * @author Alexander Nozik */ -class PluginManager(override val context: Context) : ContextAware, Iterable { +public class PluginManager(override val context: Context) : ContextAware, Iterable { /** * A set of loaded plugins @@ -34,7 +34,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable { + public fun sequence(recursive: Boolean): Sequence { return if (recursive && parent != null) { plugins.asSequence() + parent.sequence(true) } else { @@ -47,7 +47,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable Boolean): Plugin? = sequence(recursive).find(predicate) + public fun find(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate) /** @@ -56,7 +56,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable get(type: KClass, tag: PluginTag? = null, recursive: Boolean = true): T? = + public operator fun get(type: KClass, tag: PluginTag? = null, recursive: Boolean = true): T? = find(recursive) { type.isInstance(it) && (tag == null || tag.matches(it.tag)) } as T? - inline operator fun get(tag: PluginTag? = null, recursive: Boolean = true): T? = + public inline operator fun get(tag: PluginTag? = null, recursive: Boolean = true): T? = get(T::class, tag, recursive) - inline operator fun get(factory: PluginFactory, recursive: Boolean = true): T? = + public inline operator fun get(factory: PluginFactory, recursive: Boolean = true): T? = get(factory.type, factory.tag, recursive) /** @@ -87,7 +87,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable load(plugin: T): T { + public fun load(plugin: T): T { if (context.isActive) error("Can't load plugin into active context") if (get(plugin::class, plugin.tag, recursive = false) != null) { @@ -107,16 +107,16 @@ class PluginManager(override val context: Context) : ContextAware, Iterable load(factory: PluginFactory, meta: Meta = Meta.EMPTY): T = + public fun load(factory: PluginFactory, meta: Meta = Meta.EMPTY): T = load(factory(meta, context)) - fun load(factory: PluginFactory, metaBuilder: MetaBuilder.() -> Unit): T = + public fun load(factory: PluginFactory, metaBuilder: MetaBuilder.() -> Unit): T = load(factory, Meta(metaBuilder)) /** * Remove a plugin from [PluginManager] */ - fun remove(plugin: Plugin) { + public fun remove(plugin: Plugin) { if (context.isActive) error("Can't remove plugin from active context") if (plugins.contains(plugin)) { @@ -130,7 +130,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable fetch(factory: PluginFactory, recursive: Boolean = true, meta: Meta = Meta.EMPTY): T { + public fun fetch(factory: PluginFactory, recursive: Boolean = true, meta: Meta = Meta.EMPTY): T { val loaded = get(factory.type, factory.tag, recursive) return when { loaded == null -> load(factory(meta, context)) @@ -139,7 +139,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable fetch( + public fun fetch( factory: PluginFactory, recursive: Boolean = true, metaBuilder: MetaBuilder.() -> Unit diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt index 06c36ab0..c69e939c 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt @@ -26,25 +26,25 @@ import hep.dataforge.names.toName * @author Alexander Nozik * @version $Id: $Id */ -inline class Path(val tokens: List) : Iterable { +public inline class Path(public val tokens: List) : Iterable { - val head: PathToken? get() = tokens.firstOrNull() + public val head: PathToken? get() = tokens.firstOrNull() - val length: Int get() = tokens.size + public val length: Int get() = tokens.size /** * Returns non-empty optional containing the chain without first segment in case of chain path. * * @return */ - val tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1)) + public val tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1)) override fun iterator(): Iterator = tokens.iterator() - companion object { - const val PATH_SEGMENT_SEPARATOR = "/" + public companion object { + public const val PATH_SEGMENT_SEPARATOR = "/" - fun parse(path: String): Path { + public fun parse(path: String): Path { val head = path.substringBefore(PATH_SEGMENT_SEPARATOR) val tail = path.substringAfter(PATH_SEGMENT_SEPARATOR) return PathToken.parse(head).toPath() + parse(tail) @@ -52,18 +52,18 @@ inline class Path(val tokens: List) : Iterable { } } -operator fun Path.plus(path: Path) = Path(this.tokens + path.tokens) +public operator fun Path.plus(path: Path): Path = Path(this.tokens + path.tokens) -data class PathToken(val name: Name, val target: String? = null) { +public data class PathToken(val name: Name, val target: String? = null) { override fun toString(): String = if (target == null) { name.toString() } else { "$target$TARGET_SEPARATOR$name" } - companion object { - const val TARGET_SEPARATOR = "::" - fun parse(token: String): PathToken { + public companion object { + public const val TARGET_SEPARATOR: String = "::" + public fun parse(token: String): PathToken { val target = token.substringBefore(TARGET_SEPARATOR, "") val name = token.substringAfter(TARGET_SEPARATOR).toName() if (target.contains("[")) TODO("target separators in queries are not supported") @@ -72,4 +72,4 @@ data class PathToken(val name: Name, val target: String? = null) { } } -fun PathToken.toPath() = Path(listOf(this)) +public fun PathToken.toPath(): Path = Path(listOf(this)) diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt index bea7b12c..665912b8 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt @@ -22,29 +22,25 @@ import hep.dataforge.names.Name * * @author Alexander Nozik */ -interface Provider { +public interface Provider { /** * Default target for this provider - * - * @return */ - val defaultTarget: String get() = "" + public val defaultTarget: String get() = "" /** * Default target for next chain segment - * - * @return */ - val defaultChainTarget: String get() = "" + public val defaultChainTarget: String get() = "" /** * A map of direct children for specific target */ - fun provideTop(target: String): Map = emptyMap() + public fun provideTop(target: String): Map = emptyMap() } -fun Provider.provide(path: Path, targetOverride: String? = null): Any? { +public fun Provider.provide(path: Path, targetOverride: String? = null): Any? { if (path.length == 0) throw IllegalArgumentException("Can't provide by empty path") val first = path.first() val target = targetOverride ?: first.target ?: defaultTarget @@ -63,7 +59,7 @@ fun Provider.provide(path: Path, targetOverride: String? = null): Any? { /** * Type checked provide */ -inline fun Provider.provide(path: String, targetOverride: String? = null): T? { +public inline fun Provider.provide(path: String, targetOverride: String? = null): T? { return provide(Path.parse(path), targetOverride) as? T } // @@ -77,7 +73,7 @@ inline fun Provider.provide(path: String, targetOverride: Stri /** * Typed top level content */ -inline fun Provider.top(target: String): Map { +public inline fun Provider.top(target: String): Map { return provideTop(target).mapValues { it.value as? T ?: error("The type of element $it is ${it::class} but ${T::class} is expected") } diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt index a31f1fdb..e07cfd10 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt @@ -7,4 +7,4 @@ package hep.dataforge.provider */ @MustBeDocumented @Target(AnnotationTarget.CLASS) -annotation class Type(val id: String) +public annotation class Type(val id: String) diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt index cf030c75..d747587e 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt @@ -5,23 +5,23 @@ import hep.dataforge.meta.Meta /** * A simple data transformation on a data node */ -interface Action { +public interface Action { /** * Transform the data in the node, producing a new node. By default it is assumed that all calculations are lazy * so not actual computation is started at this moment */ - operator fun invoke(node: DataNode, meta: Meta): DataNode + public operator fun invoke(node: DataNode, meta: Meta): DataNode /** * Terminal action is the one that could not be invoked lazily and requires some kind of blocking computation to invoke */ - val isTerminal: Boolean get() = false + public val isTerminal: Boolean get() = false } /** * Action composition. The result is terminal if one of its parts is terminal */ -infix fun Action.then(action: Action): Action { +public infix fun Action.then(action: Action): Action { // TODO introduce composite action and add optimize by adding action to the list return object : Action { override fun invoke(node: DataNode, meta: Meta): DataNode { diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt index 8cbd6192..d1c0d55e 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt @@ -1,48 +1,58 @@ package hep.dataforge.data +import hep.dataforge.meta.DFExperimental import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlin.coroutines.CoroutineContext + + /** * A monitor of goal state that could be accessed only form inside the goal */ -class CoroutineMonitor : CoroutineContext.Element { +@DFExperimental +public class CoroutineMonitor : CoroutineContext.Element { override val key: CoroutineContext.Key<*> get() = CoroutineMonitor - var totalWork: Double = 1.0 - var workDone: Double = 0.0 - var status: String = "" + public var totalWork: Double = 1.0 + public var workDone: Double = 0.0 + public var status: String = "" /** * Mark the goal as started */ - fun start() { + public fun start() { } /** * Mark the goal as completed */ - fun finish() { + public fun finish() { workDone = totalWork } - companion object : CoroutineContext.Key + public companion object : CoroutineContext.Key } -class Dependencies(val values: Collection) : CoroutineContext.Element { +public class Dependencies(public val values: Collection) : CoroutineContext.Element { override val key: CoroutineContext.Key<*> get() = Dependencies - companion object : CoroutineContext.Key + public companion object : CoroutineContext.Key } -val CoroutineContext.monitor: CoroutineMonitor? get() = this[CoroutineMonitor] -val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.monitor +@DFExperimental +public val CoroutineContext.monitor: CoroutineMonitor? get() = this[CoroutineMonitor] +@DFExperimental +public val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.monitor -val Job.dependencies: Collection get() = this[Dependencies]?.values ?: emptyList() +public val Job.dependencies: Collection get() = this[Dependencies]?.values ?: emptyList() -val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0) -val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0) -val Job.status: String get() = monitor?.status ?: "" -val Job.progress: Double get() = workDone / totalWork \ No newline at end of file +@DFExperimental +public val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0) +@DFExperimental +public val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0) +@DFExperimental +public val Job.status: String get() = monitor?.status ?: "" +@DFExperimental +public val Job.progress: Double get() = workDone / totalWork \ No newline at end of file diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt index 233ea164..c7acf91c 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt @@ -11,7 +11,7 @@ import kotlin.reflect.KClass /** * A data element characterized by its meta */ -interface Data : Goal, MetaRepr{ +public interface Data : Goal, MetaRepr{ /** * Type marker for the data. The type is known before the calculation takes place so it could be checked. */ diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt index 931e7cf3..0e4d6261 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt @@ -6,18 +6,18 @@ import hep.dataforge.values.* /** * A converter of generic object to and from [MetaItem] */ -interface MetaConverter { - fun itemToObject(item: MetaItem<*>): T - fun objectToMetaItem(obj: T): MetaItem<*> +public interface MetaConverter { + public fun itemToObject(item: MetaItem<*>): T + public fun objectToMetaItem(obj: T): MetaItem<*> - companion object { + public companion object { - val item = object : MetaConverter> { + public val item: MetaConverter> = object : MetaConverter> { override fun itemToObject(item: MetaItem<*>): MetaItem<*> = item override fun objectToMetaItem(obj: MetaItem<*>): MetaItem<*> = obj } - val meta = object : MetaConverter { + public val meta: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Meta = when (item) { is MetaItem.NodeItem -> item.node is MetaItem.ValueItem -> item.value.toMeta() @@ -26,7 +26,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: Meta): MetaItem<*> = MetaItem.NodeItem(obj) } - val value = object : MetaConverter { + public val value: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Value = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -35,7 +35,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: Value): MetaItem<*> = MetaItem.ValueItem(obj) } - val string = object : MetaConverter { + public val string: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): String = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -44,7 +44,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: String): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val boolean = object : MetaConverter { + public val boolean: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Boolean = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -53,7 +53,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: Boolean): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val number = object : MetaConverter { + public val number: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Number = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -62,7 +62,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: Number): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val double = object : MetaConverter { + public val double: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Double = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -71,7 +71,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: Double): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val float = object : MetaConverter { + public val float: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Float = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -80,7 +80,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: Float): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val int = object : MetaConverter { + public val int: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Int = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -89,7 +89,7 @@ interface MetaConverter { override fun objectToMetaItem(obj: Int): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val long = object : MetaConverter { + public val long: MetaConverter = object : MetaConverter { override fun itemToObject(item: MetaItem<*>): Long = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -98,14 +98,14 @@ interface MetaConverter { override fun objectToMetaItem(obj: Long): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - inline fun > enum(): MetaConverter = object : MetaConverter { + public inline fun > enum(): MetaConverter = object : MetaConverter { @Suppress("USELESS_CAST") override fun itemToObject(item: MetaItem<*>): E = item.enum() as? E ?: error("The Item is not a Enum") override fun objectToMetaItem(obj: E): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - fun valueList(writer: (T) -> Value = {Value.of(it)}, reader: (Value) -> T): MetaConverter> = + public fun valueList(writer: (T) -> Value = {Value.of(it)}, reader: (Value) -> T): MetaConverter> = object : MetaConverter> { override fun itemToObject(item: MetaItem<*>): List = item.value?.list?.map(reader) ?: error("The item is not a value list") @@ -117,8 +117,8 @@ interface MetaConverter { } } -fun MetaConverter.nullableItemToObject(item: MetaItem<*>?): T? = item?.let { itemToObject(it) } -fun MetaConverter.nullableObjectToMetaItem(obj: T?): MetaItem<*>? = obj?.let { objectToMetaItem(it) } +public fun MetaConverter.nullableItemToObject(item: MetaItem<*>?): T? = item?.let { itemToObject(it) } +public fun MetaConverter.nullableObjectToMetaItem(obj: T?): MetaItem<*>? = obj?.let { objectToMetaItem(it) } -fun MetaConverter.metaToObject(meta: Meta): T = itemToObject(MetaItem.NodeItem(meta)) -fun MetaConverter.valueToObject(value: Value): T = itemToObject(MetaItem.ValueItem(value)) +public fun MetaConverter.metaToObject(meta: Meta): T = itemToObject(MetaItem.NodeItem(meta)) +public fun MetaConverter.valueToObject(value: Value): T = itemToObject(MetaItem.ValueItem(value)) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt index 38984520..2c09faa5 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt @@ -6,31 +6,31 @@ import hep.dataforge.names.Name /** * A transformation for meta item or a group of items */ -interface TransformationRule { +public interface TransformationRule { /** * Check if this transformation should be applied to a node with given name and value */ - fun matches(name: Name, item: MetaItem<*>?): Boolean + public fun matches(name: Name, item: MetaItem<*>?): Boolean /** * Select all items to be transformed. Item could be a value as well as node * * @return a sequence of item paths to be transformed */ - fun selectItems(meta: Meta): Sequence = + public fun selectItems(meta: Meta): Sequence = meta.sequence().filter { matches(it.first, it.second) }.map { it.first } /** * Apply transformation for a single item (Node or Value) to the target */ - fun > transformItem(name: Name, item: MetaItem<*>?, target: M): Unit + public fun > transformItem(name: Name, item: MetaItem<*>?, target: M): Unit } /** * A transformation which keeps all elements, matching [selector] unchanged. */ -data class KeepTransformationRule(val selector: (Name) -> Boolean) : +public data class KeepTransformationRule(val selector: (Name) -> Boolean) : TransformationRule { override fun matches(name: Name, item: MetaItem<*>?): Boolean { return selector(name) @@ -47,7 +47,7 @@ data class KeepTransformationRule(val selector: (Name) -> Boolean) : /** * A transformation which transforms element with specific name */ -data class SingleItemTransformationRule( +public data class SingleItemTransformationRule( val from: Name, val transform: MutableMeta<*>.(Name, MetaItem<*>?) -> Unit ) : TransformationRule { @@ -64,7 +64,7 @@ data class SingleItemTransformationRule( } } -data class RegexItemTransformationRule( +public data class RegexItemTransformationRule( val from: Regex, val transform: MutableMeta<*>.(name: Name, MatchResult, MetaItem<*>?) -> Unit ) : TransformationRule { @@ -84,12 +84,12 @@ data class RegexItemTransformationRule( /** * A set of [TransformationRule] to either transform static meta or create dynamically updated [MutableMeta] */ -inline class MetaTransformation(val transformations: Collection) { +public inline class MetaTransformation(public val transformations: Collection) { /** * Produce new meta using only those items that match transformation rules */ - fun generate(source: Meta): Meta = + public fun generate(source: Meta): Meta = Meta { transformations.forEach { rule -> rule.selectItems(source).forEach { name -> @@ -102,7 +102,7 @@ inline class MetaTransformation(val transformations: Collection rule.selectItems(source).forEach { name -> rule.transformItem(name, source[name], this) @@ -115,7 +115,7 @@ inline class MetaTransformation(val transformations: Collection rule.selectItems(source).forEach { name -> @@ -128,7 +128,7 @@ inline class MetaTransformation(val transformations: Collection> bind(source: Config, target: M) { + public fun > bind(source: Config, target: M) { source.onChange(target) { name, _, newItem -> transformations.forEach { t -> if (t.matches(name, newItem)) { @@ -147,27 +147,27 @@ inline class MetaTransformation(val transformations: Collection() +public class MetaTransformationBuilder { + private val transformations = HashSet() /** * Keep all items with name satisfying the criteria */ - fun keep(selector: (Name) -> Boolean) { + public fun keep(selector: (Name) -> Boolean) { transformations.add(KeepTransformationRule(selector)) } /** * Keep specific item (including its descendants) */ - fun keep(name: Name) { + public fun keep(name: Name) { keep { it == name } } /** * Keep nodes by regex */ - fun keep(regex: String) { + public fun keep(regex: String) { transformations.add( RegexItemTransformationRule(regex.toRegex()) { name, _, metaItem -> setItem(name, metaItem) @@ -177,7 +177,7 @@ class MetaTransformationBuilder { /** * Move an item from [from] to [to], optionally applying [operation] it defined */ - fun move(from: Name, to: Name, operation: (MetaItem<*>?) -> Any? = { it }) { + public fun move(from: Name, to: Name, operation: (MetaItem<*>?) -> Any? = { it }) { transformations.add( SingleItemTransformationRule(from) { _, item -> set(to, operation(item)) @@ -185,5 +185,5 @@ class MetaTransformationBuilder { ) } - fun build() = MetaTransformation(transformations) + public fun build(): MetaTransformation = MetaTransformation(transformations) } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt index 07e66ea8..2171c4ea 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt @@ -13,7 +13,7 @@ public fun Value.isNull(): Boolean = this == Null */ public fun Value.isList(): Boolean = this.list.size > 1 -public val Value.boolean +public val Value.boolean: Boolean get() = this == True || this.list.firstOrNull() == True || (type == ValueType.STRING && string.toBoolean()) diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt index f608b59d..02452ce6 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt @@ -35,7 +35,7 @@ public abstract class WorkspacePlugin : AbstractPlugin() { public inline fun task( name: String, noinline builder: TaskBuilder.() -> Unit - ) = task(name, T::class, builder) + ): GenericTask = task(name, T::class, builder) // ////TODO add delegates to build gradle-like tasks