From e931994b751fc610598094e001642d0a30d54c36 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 23 Dec 2020 21:22:47 +0300 Subject: [PATCH] Cleanup --- dataforge-meta/api/dataforge-meta.api | 21 +++++---- .../kotlin/hep/dataforge/meta/ItemProvider.kt | 44 +++++++++++++++++-- .../kotlin/hep/dataforge/meta/JsonMeta.kt | 3 +- .../kotlin/hep/dataforge/meta/Meta.kt | 15 +++---- .../kotlin/hep/dataforge/meta/MetaItem.kt | 3 +- .../kotlin/hep/dataforge/meta/MutableMeta.kt | 3 +- .../kotlin/hep/dataforge/meta/Scheme.kt | 10 ++--- .../hep/dataforge/meta/Specification.kt | 2 +- .../kotlin/hep/dataforge/meta/getIndexed.kt | 36 --------------- .../hep/dataforge/meta/SpecificationTest.kt | 6 +-- 10 files changed, 69 insertions(+), 74 deletions(-) delete mode 100644 dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index ca03c72a..a72681ba 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -56,13 +56,6 @@ public abstract interface annotation class hep/dataforge/meta/DFBuilder : java/l public abstract interface annotation class hep/dataforge/meta/DFExperimental : java/lang/annotation/Annotation { } -public final class hep/dataforge/meta/GetIndexedKt { - public static final fun getIndexed (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)Ljava/util/Map; - public static final fun getIndexed (Lhep/dataforge/meta/Meta;Ljava/lang/String;)Ljava/util/Map; - public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Ljava/util/Map; - public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Ljava/lang/String;)Ljava/util/Map; -} - public final class hep/dataforge/meta/ItemDelegateKt { public static final fun boolean (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; public static final fun boolean (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadOnlyProperty; @@ -135,6 +128,11 @@ public final class hep/dataforge/meta/ItemProvider$Companion { public final class hep/dataforge/meta/ItemProviderKt { public static final fun get (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; public static final fun get (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem; + public static final fun getIndexed (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Ljava/util/Map; + public static final fun getIndexed (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Ljava/util/Map; + public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Ljava/util/Map; + public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Ljava/lang/String;)Ljava/util/Map; + public static final fun getRootNode (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Meta; public static final fun withDefault (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/ItemProvider; } @@ -492,8 +490,8 @@ public class hep/dataforge/meta/SchemeSpec : hep/dataforge/meta/Specification, h public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Scheme; public synthetic fun read (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; public fun read (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; - public synthetic fun write (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; - public fun write (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; + public synthetic fun write (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + public fun write (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; } public final class hep/dataforge/meta/SealedMeta : hep/dataforge/meta/AbstractTypedMeta { @@ -509,13 +507,13 @@ public abstract interface class hep/dataforge/meta/Specification { public abstract fun empty ()Lhep/dataforge/meta/MutableItemProvider; public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; public abstract fun read (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; - public abstract fun write (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + public abstract fun write (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; } public final class hep/dataforge/meta/Specification$DefaultImpls { public static fun empty (Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; public static fun invoke (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; - public static synthetic fun write$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider; + public static synthetic fun write$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider; } public final class hep/dataforge/meta/SpecificationKt { @@ -529,6 +527,7 @@ public final class hep/dataforge/meta/SpecificationKt { } public abstract interface class hep/dataforge/meta/TypedMeta : hep/dataforge/meta/Meta { + public abstract fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; public abstract fun getItems ()Ljava/util/Map; } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt index dd3194b6..736753c2 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt @@ -1,9 +1,7 @@ package hep.dataforge.meta import hep.dataforge.meta.MetaItem.NodeItem -import hep.dataforge.names.Name -import hep.dataforge.names.NameToken -import hep.dataforge.names.toName +import hep.dataforge.names.* public fun interface ItemProvider { //getItem used instead of get in order to provide extension freedom @@ -24,10 +22,15 @@ public fun interface ItemProvider { */ public operator fun ItemProvider?.get(name: Name): MetaItem<*>? = this?.getItem(name) +/** + * The root node of this item provider if it is present + */ +public val ItemProvider.rootNode: Meta? get() = get(Name.EMPTY).node + /** * Parse [Name] from [key] using full name notation and pass it to [Meta.get] */ -public operator fun ItemProvider?.get(key: String): MetaItem<*>? = get(key.toName()) +public operator fun ItemProvider?.get(key: String): MetaItem<*>? = this?.get(key.toName()) /** * Create a provider that uses given provider for default values if those are not found in this provider @@ -35,3 +38,36 @@ public operator fun ItemProvider?.get(key: String): MetaItem<*>? = get(key.toNam public fun ItemProvider.withDefault(default: ItemProvider): ItemProvider = ItemProvider { this[it] ?: default[it] } + +/** + * Get all items matching given name. The index of the last element, if present is used as a [Regex], + * against which indexes of elements are matched. + */ +public fun ItemProvider.getIndexed(name: Name): Map> { + val root: Meta = when (name.length) { + 0 -> error("Can't use empty name for 'getIndexed'") + 1 -> this.rootNode ?: return emptyMap() + else -> this[name.cutLast()].node ?: return emptyMap() + } + + val (body, index) = name.lastOrNull()!! + return if (index == null) { + root.items.filter { it.key.body == body }.mapKeys { it.key.index } + } else { + val regex = index.toRegex() + root.items.filter { it.key.body == body && (regex.matches(it.key.index ?: "")) } + .mapKeys { it.key.index } + } +} + +public fun ItemProvider.getIndexed(name: String): Map> = this@getIndexed.getIndexed(name.toName()) + +/** + * Get all items matching given name. + */ +@Suppress("UNCHECKED_CAST") +public fun > M.getIndexed(name: Name): Map> = + (this as Meta).getIndexed(name) as Map> + +public fun > M.getIndexed(name: String): Map> = + getIndexed(name.toName()) 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 6dcfe76a..1b028477 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt @@ -2,7 +2,6 @@ package hep.dataforge.meta -import hep.dataforge.meta.JsonMeta.Companion.JSON_ARRAY_KEY import hep.dataforge.meta.descriptors.ItemDescriptor import hep.dataforge.meta.descriptors.ItemDescriptor.Companion.DEFAULT_INDEX_KEY import hep.dataforge.meta.descriptors.NodeDescriptor @@ -26,7 +25,7 @@ public fun Value.toJson(descriptor: ValueDescriptor? = null): JsonElement = when //Use these methods to customize JSON key mapping @Suppress("NULLABLE_EXTENSION_OPERATOR_WITH_SAFE_CALL_RECEIVER") -private fun String.toJsonKey(descriptor: ItemDescriptor?) = descriptor?.attributes["jsonName"].string ?: toString() +private fun String.toJsonKey(descriptor: ItemDescriptor?) = descriptor?.attributes?.get("jsonName").string ?: toString() //private fun NodeDescriptor?.getDescriptor(key: String) = this?.items?.get(key) 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 20cac1dd..cad22948 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt @@ -4,7 +4,6 @@ import hep.dataforge.meta.MetaItem.NodeItem import hep.dataforge.meta.MetaItem.ValueItem import hep.dataforge.names.* import hep.dataforge.values.Value -import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json @@ -63,7 +62,7 @@ public interface Meta : MetaRepr, ItemProvider { } } -public operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token) +public operator fun Meta.get(token: NameToken): MetaItem<*>? = items.get(token) /** * Get a sequence of [Name]-[Value] pairs @@ -98,17 +97,17 @@ public operator fun Meta.iterator(): Iterator>> = itemSeq */ public interface TypedMeta> : Meta { override val items: Map> + + @Suppress("UNCHECKED_CAST") + override fun getItem(name: Name): MetaItem? = super.getItem(name)?.let { it as MetaItem } + //Typed meta guarantees that all children have M type } /** * The same as [Meta.get], but with specific node type */ -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 -} +public operator fun > M?.get(name: Name): MetaItem? = this?.getItem(name) + public operator fun > M?.get(key: String): MetaItem? = this[key.toName()] public operator fun > M?.get(key: NameToken): MetaItem? = this[key.asName()] diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt index e4934ed9..c85d8ba2 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt @@ -3,7 +3,6 @@ package hep.dataforge.meta import hep.dataforge.meta.MetaItem.NodeItem import hep.dataforge.meta.MetaItem.ValueItem import hep.dataforge.values.* -import kotlinx.serialization.Serializable /** * A member of the meta tree. Could be represented as one of following: @@ -72,7 +71,7 @@ public val MetaItem<*>?.int: Int? get() = number?.toInt() public val MetaItem<*>?.long: Long? get() = number?.toLong() public val MetaItem<*>?.short: Short? get() = number?.toShort() -public inline fun > MetaItem<*>?.enum(): E? = if (this is MetaItem.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) } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt index c0520792..e4ec6c4b 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt @@ -28,7 +28,6 @@ public abstract class AbstractMutableMeta> : AbstractTypedMet //itemChanged(key.asName(), oldItem, newItem) } - @Suppress("UNCHECKED_CAST") protected fun wrapItem(item: MetaItem<*>?): MetaItem? = when (item) { null -> null is MetaItem.ValueItem -> item @@ -50,7 +49,7 @@ public abstract class AbstractMutableMeta> : AbstractTypedMet 0 -> error("Can't setValue meta item for empty name") 1 -> { val token = name.firstOrNull()!! - @Suppress("UNCHECKED_CAST") val oldItem: MetaItem? = getItem(name) as? MetaItem + val oldItem: MetaItem? = getItem(name) replaceItem(token, oldItem, wrapItem(item)) } else -> { diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt index f2cb2bb7..e307010d 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt @@ -86,12 +86,12 @@ public inline operator fun T.invoke(block: T.() -> Unit): T = apply * A specification for simplified generation of wrappers */ public open class SchemeSpec( - private val builder: (config: Config, defaultProvider: ItemProvider, descriptor: NodeDescriptor?) -> T, + private val builder: (target: MutableItemProvider, defaultProvider: ItemProvider, descriptor: NodeDescriptor?) -> T, ) : Specification, Described { - public constructor(emptyBuilder: () -> T) : this({ config: Config, defaultProvider: ItemProvider, descriptor: NodeDescriptor? -> + public constructor(emptyBuilder: () -> T) : this({ target: MutableItemProvider, defaultProvider: ItemProvider, descriptor: NodeDescriptor? -> emptyBuilder().apply { - this.items = config + this.items = target this.default = defaultProvider this.descriptor = descriptor } @@ -100,8 +100,8 @@ public open class SchemeSpec( override fun read(items: ItemProvider): T = builder(Config(), items, descriptor) - override fun write(config: Config, defaultProvider: ItemProvider): T = - builder(config, defaultProvider, descriptor) + override fun write(target: MutableItemProvider, defaultProvider: ItemProvider): T = + builder(target, defaultProvider, descriptor) //TODO Generate descriptor from Scheme class override val descriptor: NodeDescriptor? get() = null diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt index 3cf0c0b5..a4e18069 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt @@ -19,7 +19,7 @@ public interface Specification { /** * Wrap [MutableItemProvider], using it as inner storage (changes to [Specification] are reflected on [MutableItemProvider] */ - public fun write(config: Config, defaultProvider: ItemProvider = ItemProvider.EMPTY): T + public fun write(target: MutableItemProvider, defaultProvider: ItemProvider = ItemProvider.EMPTY): T /** * Generate an empty object diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt deleted file mode 100644 index 6b01723a..00000000 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt +++ /dev/null @@ -1,36 +0,0 @@ -package hep.dataforge.meta - -import hep.dataforge.names.* - -/** - * Get all items matching given name. The index of the last element, if present is used as a [Regex], - * against which indexes of elements are matched. - */ -public fun Meta.getIndexed(name: Name): Map> { - val root = when (name.length) { - 0 -> error("Can't use empty name for 'getIndexed'") - 1 -> this - else -> this[name.cutLast()].node ?: return emptyMap() - } - - val (body, index) = name.lastOrNull()!! - return if (index == null) { - root.items.filter { it.key.body == body }.mapKeys { it.key.index } - } else { - val regex = index.toRegex() - root.items.filter { it.key.body == body && (regex.matches(it.key.index ?: "")) } - .mapKeys { it.key.index } - } -} - -public fun Meta.getIndexed(name: String): Map> = this@getIndexed.getIndexed(name.toName()) - -/** - * Get all items matching given name. - */ -@Suppress("UNCHECKED_CAST") -public fun > M.getIndexed(name: Name): Map> = - (this as Meta).getIndexed(name) as Map> - -public fun > M.getIndexed(name: String): Map> = - getIndexed(name.toName()) \ No newline at end of file diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt index 5bb93649..93934154 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt @@ -4,14 +4,14 @@ import kotlin.test.Test import kotlin.test.assertEquals class SpecificationTest { - class TestStyled(config: Config, default: ItemProvider?) : Scheme(config, default) { + class TestStyled(target: MutableItemProvider, default: ItemProvider?) : Scheme(target, default) { var list by numberList(1, 2, 3) companion object : Specification { override fun read(items: ItemProvider): TestStyled = TestStyled(Config(), items) - override fun write(config: Config, defaultProvider: ItemProvider): TestStyled = - TestStyled(config, defaultProvider) + override fun write(target: MutableItemProvider, defaultProvider: ItemProvider): TestStyled = + TestStyled(target, defaultProvider) } }