Fix MetaItem inference from Any

This commit is contained in:
Alexander Nozik 2020-12-25 16:19:19 +03:00
parent 76968f07e5
commit 460dc77d51
7 changed files with 84 additions and 77 deletions

View File

@ -2,7 +2,7 @@ plugins {
id("ru.mipt.npm.project") id("ru.mipt.npm.project")
} }
val dataforgeVersion by extra("0.3.0-dev-SNAPSHOT") val dataforgeVersion by extra("0.3.0-dev")
val bintrayRepo by extra("dataforge") val bintrayRepo by extra("dataforge")
val githubProject by extra("dataforge-core") val githubProject by extra("dataforge-core")

View File

@ -131,6 +131,7 @@ public final class hep/dataforge/meta/ItemProviderKt {
public static final fun getChild (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/ItemProvider; public static final fun getChild (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/ItemProvider;
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;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/ItemProvider;Ljava/lang/String;)Ljava/util/Map;
public static final fun getRootItem (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun getRootNode (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Meta; 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; public static final fun withDefault (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/ItemProvider;
} }
@ -252,6 +253,22 @@ public final class hep/dataforge/meta/MetaBuilderKt {
public static final fun builder (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MetaBuilder; public static final fun builder (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MetaBuilder;
} }
public final class hep/dataforge/meta/MetaItemKt {
public static final fun asMetaItem (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/NodeItem;
public static final fun asMetaItem (Lhep/dataforge/values/Value;)Lhep/dataforge/meta/ValueItem;
public static final fun getBoolean (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Boolean;
public static final fun getDouble (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Double;
public static final fun getFloat (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Float;
public static final fun getInt (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Integer;
public static final fun getLong (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Long;
public static final fun getNode (Lhep/dataforge/meta/TypedMetaItem;)Lhep/dataforge/meta/Meta;
public static final fun getNumber (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Number;
public static final fun getShort (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Short;
public static final fun getString (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/String;
public static final fun getStringList (Lhep/dataforge/meta/TypedMetaItem;)Ljava/util/List;
public static final fun getValue (Lhep/dataforge/meta/TypedMetaItem;)Lhep/dataforge/values/Value;
}
public final class hep/dataforge/meta/MetaItemSerializer : kotlinx/serialization/KSerializer { public final class hep/dataforge/meta/MetaItemSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lhep/dataforge/meta/MetaItemSerializer; public static final field INSTANCE Lhep/dataforge/meta/MetaItemSerializer;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/TypedMetaItem; public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/TypedMetaItem;
@ -263,9 +280,6 @@ public final class hep/dataforge/meta/MetaItemSerializer : kotlinx/serialization
public final class hep/dataforge/meta/MetaKt { public final class hep/dataforge/meta/MetaKt {
public static final fun get (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/TypedMetaItem; public static final fun get (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun get (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun get (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun get (Lhep/dataforge/meta/TypedMeta;Ljava/lang/String;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun isEmpty (Lhep/dataforge/meta/Meta;)Z public static final fun isEmpty (Lhep/dataforge/meta/Meta;)Z
public static final fun itemSequence (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; public static final fun itemSequence (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
public static final fun iterator (Lhep/dataforge/meta/Meta;)Ljava/util/Iterator; public static final fun iterator (Lhep/dataforge/meta/Meta;)Ljava/util/Iterator;
@ -508,20 +522,10 @@ public final class hep/dataforge/meta/TypedMetaItem$Companion {
public final fun serializer (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer; public final fun serializer (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
} }
public final class hep/dataforge/meta/TypedMetaItemKt { public final class hep/dataforge/meta/TypedMetaKt {
public static final fun asMetaItem (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/NodeItem; public static final fun get (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun asMetaItem (Lhep/dataforge/values/Value;)Lhep/dataforge/meta/ValueItem; public static final fun get (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun getBoolean (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Boolean; public static final fun get (Lhep/dataforge/meta/TypedMeta;Ljava/lang/String;)Lhep/dataforge/meta/TypedMetaItem;
public static final fun getDouble (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Double;
public static final fun getFloat (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Float;
public static final fun getInt (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Integer;
public static final fun getLong (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Long;
public static final fun getNode (Lhep/dataforge/meta/TypedMetaItem;)Lhep/dataforge/meta/Meta;
public static final fun getNumber (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Number;
public static final fun getShort (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/Short;
public static final fun getString (Lhep/dataforge/meta/TypedMetaItem;)Ljava/lang/String;
public static final fun getStringList (Lhep/dataforge/meta/TypedMetaItem;)Ljava/util/List;
public static final fun getValue (Lhep/dataforge/meta/TypedMetaItem;)Lhep/dataforge/values/Value;
} }
public final class hep/dataforge/meta/ValueItem : hep/dataforge/meta/TypedMetaItem { public final class hep/dataforge/meta/ValueItem : hep/dataforge/meta/TypedMetaItem {

View File

@ -21,10 +21,15 @@ public fun interface ItemProvider {
*/ */
public operator fun ItemProvider?.get(name: Name): MetaItem? = this?.getItem(name) public operator fun ItemProvider?.get(name: Name): MetaItem? = this?.getItem(name)
/**
* Root item of this provider
*/
public val ItemProvider.rootItem: MetaItem? get() = get(Name.EMPTY)
/** /**
* The root node of this item provider if it is present * The root node of this item provider if it is present
*/ */
public val ItemProvider.rootNode: Meta? get() = get(Name.EMPTY).node public val ItemProvider.rootNode: Meta? get() = rootItem.node
/** /**
* Parse [Name] from [key] using full name notation and pass it to [Meta.get] * Parse [Name] from [key] using full name notation and pass it to [Meta.get]

View File

@ -3,7 +3,6 @@ package hep.dataforge.meta
import hep.dataforge.names.* import hep.dataforge.names.*
import hep.dataforge.values.Value import hep.dataforge.values.Value
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
/** /**
@ -91,48 +90,4 @@ public fun Meta.itemSequence(): Sequence<Pair<Name, MetaItem>> = sequence {
public operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem>> = itemSequence().iterator() public operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem>> = itemSequence().iterator()
/**
* A meta node that ensures that all of its descendants has at least the same type
*/
public interface TypedMeta<out M : TypedMeta<M>> : Meta {
override val items: Map<NameToken, TypedMetaItem<M>>
@Suppress("UNCHECKED_CAST")
override fun getItem(name: Name): TypedMetaItem<M>? = super.getItem(name)?.let { it as TypedMetaItem<M> }
//Typed meta guarantees that all children have M type
}
/**
* The same as [Meta.get], but with specific node type
*/
public operator fun <M : TypedMeta<M>> M?.get(name: Name): TypedMetaItem<M>? = this?.getItem(name)
public operator fun <M : TypedMeta<M>> M?.get(key: String): TypedMetaItem<M>? = this[key.toName()]
public operator fun <M : TypedMeta<M>> M?.get(key: NameToken): TypedMetaItem<M>? = this[key.asName()]
/**
* Equals, hashcode and to string for any meta
*/
public abstract class MetaBase : Meta {
override fun equals(other: Any?): Boolean = if (other is Meta) {
this.items == other.items
} else {
false
}
override fun hashCode(): Int = items.hashCode()
override fun toString(): String = Json {
prettyPrint = true
useArrayPolymorphism = true
}.encodeToString(MetaSerializer, this)
}
/**
* Equals and hash code implementation for meta node
*/
public abstract class AbstractTypedMeta<M : TypedMeta<M>> : TypedMeta<M>, MetaBase()
public fun Meta.isEmpty(): Boolean = this === Meta.EMPTY || this.items.isEmpty() public fun Meta.isEmpty(): Boolean = this === Meta.EMPTY || this.items.isEmpty()

View File

@ -18,10 +18,11 @@ public sealed class TypedMetaItem<out M : Meta>() {
public companion object { public companion object {
public fun of(arg: Any?): MetaItem { public fun of(arg: Any?): MetaItem {
return when (arg) { return when (arg) {
null -> ValueItem(Null) null -> Null.asMetaItem()
is MetaItem -> arg is MetaItem -> arg
is Meta -> NodeItem(arg) is Meta -> arg.asMetaItem()
else -> ValueItem(Value.of(arg)) is ItemProvider -> arg.rootItem ?: Null.asMetaItem()
else -> Value.of(arg).asMetaItem()
} }
} }
} }

View File

@ -2,7 +2,6 @@ package hep.dataforge.meta
import hep.dataforge.names.* import hep.dataforge.names.*
import hep.dataforge.values.Value import hep.dataforge.values.Value
import hep.dataforge.values.asValue
public interface MutableItemProvider : ItemProvider { public interface MutableItemProvider : ItemProvider {
public fun setItem(name: Name, item: MetaItem?) public fun setItem(name: Name, item: MetaItem?)
@ -30,15 +29,7 @@ public inline fun MutableItemProvider.remove(name: String): Unit = remove(name.t
public operator fun MutableItemProvider.set(name: Name, value: Any?) { public operator fun MutableItemProvider.set(name: Name, value: Any?) {
when (value) { when (value) {
null -> remove(name) null -> remove(name)
is Value -> set(name, value) else -> set(name, MetaItem.of(value))
is Number -> set(name, value.asValue())
is String -> set(name, value.asValue())
is Boolean -> set(name, value.asValue())
is MetaItem -> set(name, value)
is Meta -> set(name, value)
is MetaRepr -> set(name, value.toMeta())
is Configurable -> set(name, value.config)
else -> set(name, Value.of(value))
} }
} }

View File

@ -0,0 +1,51 @@
package hep.dataforge.meta
import hep.dataforge.names.Name
import hep.dataforge.names.NameToken
import hep.dataforge.names.toName
import kotlinx.serialization.json.Json
/**
* A meta node that ensures that all of its descendants has at least the same type
*/
public interface TypedMeta<out M : TypedMeta<M>> : Meta {
override val items: Map<NameToken, TypedMetaItem<M>>
@Suppress("UNCHECKED_CAST")
override fun getItem(name: Name): TypedMetaItem<M>? = super.getItem(name)?.let { it as TypedMetaItem<M> }
//Typed meta guarantees that all children have M type
}
/**
* The same as [Meta.get], but with specific node type
*/
public operator fun <M : TypedMeta<M>> M.get(name: Name): TypedMetaItem<M>? = getItem(name)
public operator fun <M : TypedMeta<M>> M.get(key: String): TypedMetaItem<M>? = this[key.toName()]
public operator fun <M : TypedMeta<M>> M.get(key: NameToken): TypedMetaItem<M>? = items[key]
/**
* Equals, hashcode and to string for any meta
*/
public abstract class MetaBase : Meta {
override fun equals(other: Any?): Boolean = if (other is Meta) {
this.items == other.items
} else {
false
}
override fun hashCode(): Int = items.hashCode()
override fun toString(): String = Json {
prettyPrint = true
useArrayPolymorphism = true
}.encodeToString(MetaSerializer, this)
}
/**
* Equals and hash code implementation for meta node
*/
public abstract class AbstractTypedMeta<M : TypedMeta<M>> : TypedMeta<M>, MetaBase()