From 318926bbd3525aff1f56d60acca4b1d57e4bd123 Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Mon, 24 Jul 2023 15:16:48 +0200 Subject: [PATCH 1/5] Update Kotlin --- extra/kotlin/build.gradle | 4 ++-- .../configurate/kotlin/extensions/PublisherExtensions.kt | 6 ++---- gradle/libs.versions.toml | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/extra/kotlin/build.gradle b/extra/kotlin/build.gradle index ace4bdb02..8340b7337 100644 --- a/extra/kotlin/build.gradle +++ b/extra/kotlin/build.gradle @@ -23,12 +23,12 @@ dependencies { } kotlin { - coreLibrariesVersion = "1.4.20" + coreLibrariesVersion = "1.8.20" target { compilations.configureEach { kotlinOptions { jvmTarget = "1.8" - languageVersion = "1.4" + languageVersion = "1.8" freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn", "-Xemit-jvm-type-annotations"] } } diff --git a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/PublisherExtensions.kt b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/PublisherExtensions.kt index 9b8cd42aa..bf36121d8 100644 --- a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/PublisherExtensions.kt +++ b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/PublisherExtensions.kt @@ -16,21 +16,19 @@ */ package org.spongepowered.configurate.kotlin.extensions -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.channels.sendBlocking import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.runBlocking import org.spongepowered.configurate.reactive.Publisher import org.spongepowered.configurate.reactive.Subscriber /** Given an [Publisher] instance, return a new [Flow] emitting values from the Flow */ -@OptIn(ExperimentalCoroutinesApi::class) fun Publisher.asFlow(): Flow = callbackFlow { val observer = object : Subscriber { override fun submit(item: V) { - sendBlocking(item) + runBlocking { send(item) } } override fun onError(thrown: Throwable) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2f5020936..2220c5f7b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref stylecheck = "ca.stellardrift:stylecheck:0.2.1" # Kotlin -kotlin-coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" +kotlin-coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2" kotlin-reflect = {module = "org.jetbrains.kotlin:kotlin-reflect"} # version from Kotlin BOM # Core From 271788f6189fb061808d0f9c65d05e124aabc93a Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:34:41 +0200 Subject: [PATCH 2/5] Add ConfigurationNode#getType with java.lang.reflect.Type --- .../configurate/ConfigurationNode.java | 68 +++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/spongepowered/configurate/ConfigurationNode.java b/core/src/main/java/org/spongepowered/configurate/ConfigurationNode.java index 21d84e7ac..9c86a78d5 100644 --- a/core/src/main/java/org/spongepowered/configurate/ConfigurationNode.java +++ b/core/src/main/java/org/spongepowered/configurate/ConfigurationNode.java @@ -30,10 +30,7 @@ import java.lang.reflect.AnnotatedType; import java.lang.reflect.Type; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; +import java.util.*; import java.util.function.Supplier; import java.util.stream.Collector; @@ -737,6 +734,69 @@ default List getList(final TypeToken elementType, final SupplierIf this node has a scalar value, this function treats it as a list + * with one value.

+ * + * @param elementType the expected type + * @return an immutable copy of the values contained + * @throws SerializationException if any value fails to be converted to the + * requested type + * @since TODO: version + */ + default @Nullable List getList(Type elementType) throws SerializationException { + return (List) this.get(TypeFactory.parameterizedClass(List.class, elementType)); + } + + /** + * If this node has list values, this function unwraps them and converts + * them to an appropriate type based on the provided function. + * + *

If this node has a scalar value, this function treats it as a list + * with one value.

+ * + * @param elementType expected type + * @param def default value if no appropriate value is set + * @return an immutable copy of the values contained that could be + * successfully converted, or {@code def} if no values could be + * converted. + * @throws SerializationException if any value fails to be converted to the + * requested type + * @since TODO: version + */ + default List getList(Type elementType, List def) throws SerializationException { + final Type type = TypeFactory.parameterizedClass(List.class, elementType); + final List ret = (List) this.get(type, def); + return ret.isEmpty() ? storeDefault(this, type, def) : ret; + } + + /** + * If this node has list values, this function unwraps them and converts + * them to an appropriate type based on the provided function. + * + *

If this node has a scalar value, this function treats it as a list + * with one value.

+ * + * @param elementType expected type + * @param defSupplier function that will be called to calculate a default + * value only if there is no existing value of the + * correct type + * @return an immutable copy of the values contained that could be + * successfully converted, or {@code def} if no values could be + * converted. + * @throws SerializationException if any value fails to be converted to the + * requested type + * @since TODO: version + */ + default List getList(Type elementType, Supplier> defSupplier) throws SerializationException { + final Type type = TypeFactory.parameterizedClass(List.class, elementType); + final List ret = (List) this.get(type, defSupplier); + return ret.isEmpty() ? storeDefault(this, type, defSupplier.get()) : ret; + } + /** * If this node has list values, this function unwraps them and converts * them to an appropriate type based on the provided function. From e0389c072c32fc02177480423ffb41c9c4b30391 Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:35:08 +0200 Subject: [PATCH 3/5] Add ValueReference#referenceTo with java.lang.reflect.Type --- .../reference/ConfigurationReference.java | 41 +++++++++++++++++++ .../ManualConfigurationReference.java | 10 ++++- .../reference/ValueReferenceImpl.java | 29 ++++++++----- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java b/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java index 1112c2b21..6d52a2e48 100644 --- a/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java +++ b/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java @@ -27,6 +27,7 @@ import org.spongepowered.configurate.reactive.TransactionalSubscriber; import org.spongepowered.configurate.serialize.SerializationException; +import java.lang.reflect.Type; import java.nio.file.Path; import java.util.Map; import java.util.concurrent.ForkJoinPool; @@ -271,6 +272,10 @@ default void set(final NodePath path, final TypeToken type, final @Nullab this.node().node(path).set(type, value); } + default ValueReference referenceTo(final Type type, final Object... path) throws SerializationException { + return this.referenceTo(type, NodePath.of(path)); + } + /** * Create a reference to the node at the provided path. The value will be * deserialized according to the provided TypeToken. @@ -310,6 +315,25 @@ default ValueReference referenceTo(final TypeToken type, final Obje default ValueReference referenceTo(final Class type, final Object... path) throws SerializationException { return this.referenceTo(type, NodePath.of(path)); } + + /** + * Create a reference to the node at the provided path. The value will be + * deserialized according to the provided {@link Type}. + * + *

The returned reference will update with reloads of and changes to the + * value of the provided configuration. Any serialization errors encountered + * will be submitted to the {@link #errors()} stream. + * + * @param type the value's type + * @param path the path from the root node to the node containing the value + * @return a deserializing reference to the node at the given path + * @throws SerializationException if a type serializer could not be found + * for the provided type + * @since TODO: version + */ + default ValueReference referenceTo(final Type type, final NodePath path) throws SerializationException { + return this.referenceTo(type, path, null); + } /** * Create a reference to the node at the provided path. The value will be @@ -351,6 +375,23 @@ default ValueReference referenceTo(final Class type, final NodePath return this.referenceTo(type, path, null); } + /** + * Create a reference to the node at the provided path. The value will be + * deserialized according to the provided {@link Type}. + * + *

The returned reference will update with reloads of and changes to the + * value of the provided configuration. Any serialization errors encountered + * will be submitted to the {@link #errors()} stream. + * + * @param type the value's type + * @param path the path from the root node to the node containing the value + * @return a deserializing reference to the node at the given path + * @throws SerializationException if a type serializer could not be found + * for the provided type + * @since TODO: version + */ + ValueReference referenceTo(Type type, NodePath path, @Nullable Object defaultValue) throws SerializationException; + /** * Create a reference to the node at the provided path. The value will be * deserialized according to the provided {@link TypeToken}. diff --git a/core/src/main/java/org/spongepowered/configurate/reference/ManualConfigurationReference.java b/core/src/main/java/org/spongepowered/configurate/reference/ManualConfigurationReference.java index 8cbb86c93..5ddcf43e3 100644 --- a/core/src/main/java/org/spongepowered/configurate/reference/ManualConfigurationReference.java +++ b/core/src/main/java/org/spongepowered/configurate/reference/ManualConfigurationReference.java @@ -30,6 +30,7 @@ import org.spongepowered.configurate.reactive.Publisher; import org.spongepowered.configurate.serialize.SerializationException; +import java.lang.reflect.Type; import java.util.Map; import java.util.concurrent.Executor; import java.util.function.Function; @@ -125,8 +126,13 @@ public final N get(final Iterable path) { } @Override - public final ValueReference referenceTo(final TypeToken type, - final NodePath path, final @Nullable T def) throws SerializationException { + public final ValueReference referenceTo(final Type type, + final NodePath path, final @Nullable Object def) throws SerializationException { + return new ValueReferenceImpl<>(this, path, type, def); + } + + @Override + public final ValueReference referenceTo(final TypeToken type, final NodePath path, final @Nullable T def) throws SerializationException { return new ValueReferenceImpl<>(this, path, type, def); } diff --git a/core/src/main/java/org/spongepowered/configurate/reference/ValueReferenceImpl.java b/core/src/main/java/org/spongepowered/configurate/reference/ValueReferenceImpl.java index f644b79c7..1eee698b9 100644 --- a/core/src/main/java/org/spongepowered/configurate/reference/ValueReferenceImpl.java +++ b/core/src/main/java/org/spongepowered/configurate/reference/ValueReferenceImpl.java @@ -30,6 +30,7 @@ import org.spongepowered.configurate.serialize.TypeSerializer; import org.spongepowered.configurate.util.UnmodifiableCollections; +import java.lang.reflect.Type; import java.util.concurrent.Executor; import java.util.function.Function; @@ -38,18 +39,19 @@ class ValueReferenceImpl<@Nullable T, N extends ScopedConfigurationNode> impl // Information about the reference private final ManualConfigurationReference root; private final NodePath path; - private final TypeToken type; + private final Type type; private final TypeSerializer serializer; private final Publisher.Cached<@Nullable T> deserialized; - ValueReferenceImpl(final ManualConfigurationReference root, final NodePath path, final TypeToken type, + @SuppressWarnings("unchecked") + ValueReferenceImpl(final ManualConfigurationReference root, final NodePath path, final Type type, final @Nullable T def) throws SerializationException { this.root = root; this.path = path; this.type = type; - final @Nullable TypeSerializer serializer = root.node().options().serializers().get(type); + final @Nullable TypeSerializer serializer = (TypeSerializer) root.node().options().serializers().get(type); if (serializer == null) { - throw new SerializationException(this.path, type.getType(), "Unsupported type" + type); + throw new SerializationException(this.path, type, "Unsupported type" + type); } this.serializer = serializer; @@ -63,19 +65,24 @@ class ValueReferenceImpl<@Nullable T, N extends ScopedConfigurationNode> impl }).cache(deserializedValueFrom(root.node(), def)); } + ValueReferenceImpl(final ManualConfigurationReference root, final NodePath path, final TypeToken type, + final @Nullable T def) throws SerializationException { + this(root, path, type.getType(), def); + } + ValueReferenceImpl(final ManualConfigurationReference root, final NodePath path, final Class type, final @Nullable T def) throws SerializationException { - this(root, path, TypeToken.get(type), def); + this(root, path, (Type) type, def); } private @Nullable T deserializedValueFrom(final N parent, final @Nullable T defaultVal) throws SerializationException { final N node = parent.node(this.path); if (!node.virtual()) { - return this.serializer.deserialize(this.type.getType(), node); + return this.serializer.deserialize(this.type, node); } - final @Nullable T defaultOrEmpty = defaultVal == null ? this.serializer.emptyValue(this.type.getType(), node.options()) : defaultVal; + final @Nullable T defaultOrEmpty = defaultVal == null ? this.serializer.emptyValue(this.type, node.options()) : defaultVal; if (node.options().shouldCopyDefaults()) { - this.serializer.serialize(this.type.getType(), defaultOrEmpty, node); + this.serializer.serialize(this.type, defaultOrEmpty, node); } return defaultOrEmpty; } @@ -88,7 +95,7 @@ class ValueReferenceImpl<@Nullable T, N extends ScopedConfigurationNode> impl @Override public boolean set(final @Nullable T value) { try { - this.serializer.serialize(this.type.getType(), value, node()); + this.serializer.serialize(this.type, value, node()); this.deserialized.submit(value); return true; } catch (final SerializationException e) { @@ -113,7 +120,7 @@ public boolean setAndSave(final @Nullable T value) { @Override public Publisher setAndSaveAsync(final @Nullable T value) { return Publisher.execute(() -> { - this.serializer.serialize(this.type.getType(), value, node()); + this.serializer.serialize(this.type, value, node()); this.deserialized.submit(value); this.root.save(); return true; @@ -135,7 +142,7 @@ public Publisher updateAsync(final Function<@Nullable T, ? extends T> a return Publisher.execute(() -> { final @Nullable T orig = get(); final T updated = action.apply(orig); - this.serializer.serialize(this.type.getType(), updated, node()); + this.serializer.serialize(this.type, updated, node()); this.deserialized.submit(updated); this.root.save(); return true; From 62b61fcbbba763beb661f5d85568727c7dfb5f1f Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:35:52 +0200 Subject: [PATCH 4/5] Add extension functions for KType and use kotlin.reflect.typeOf --- .../configurate/kotlin/ObjectMapping.kt | 7 +- .../extensions/ConfigurationNodeExtensions.kt | 87 +++++++++++++++++-- .../ConfigurationReferenceExtensions.kt | 9 +- .../extensions/ObjectMapperExtensions.kt | 25 +++++- 4 files changed, 113 insertions(+), 15 deletions(-) diff --git a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/ObjectMapping.kt b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/ObjectMapping.kt index ecf2ccc41..f86515b5d 100644 --- a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/ObjectMapping.kt +++ b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/ObjectMapping.kt @@ -38,6 +38,8 @@ import org.spongepowered.configurate.objectmapping.FieldDiscoverer import org.spongepowered.configurate.objectmapping.ObjectMapper import org.spongepowered.configurate.objectmapping.ObjectMapper.Factory import org.spongepowered.configurate.util.Types.combinedAnnotations +import kotlin.reflect.jvm.javaType +import kotlin.reflect.typeOf private val dataClassMapperFactory = ObjectMapper.factoryBuilder().addDiscoverer(DataClassFieldDiscoverer).build() @@ -60,8 +62,9 @@ fun dataClassFieldDiscoverer(): FieldDiscoverer<*> { } /** Get an object mapper for the type [T] using the default object mapper factory */ +@Suppress("UNCHECKED_CAST") inline fun objectMapper(): ObjectMapper { - return objectMapperFactory()[typeTokenOf()] + return objectMapperFactory()[typeOf().javaType] as ObjectMapper } /** Get an object mapper bound to the instance of [T], resolving type parameters */ @@ -69,8 +72,6 @@ inline fun T.toNode(target: ConfigurationNode) { return objectMapperFactory().get().save(this, target) } -@PublishedApi internal inline fun typeTokenOf() = object : TypeToken() {} - /** * A field discoverer that gathers definitions from kotlin `data` classes. * diff --git a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationNodeExtensions.kt b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationNodeExtensions.kt index 8ca9886e6..98d586e9e 100644 --- a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationNodeExtensions.kt +++ b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationNodeExtensions.kt @@ -16,12 +16,14 @@ */ package org.spongepowered.configurate.kotlin.extensions -import kotlin.reflect.KClass import org.spongepowered.configurate.ConfigurationNode import org.spongepowered.configurate.NodePath import org.spongepowered.configurate.ScopedConfigurationNode -import org.spongepowered.configurate.kotlin.typeTokenOf import org.spongepowered.configurate.serialize.SerializationException +import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.jvm.javaType +import kotlin.reflect.typeOf /** * An implementation of `contains` that can traverse multiple levels in [path]. @@ -58,7 +60,7 @@ operator fun ConfigurationNode.contains(path: Any): Boolean { */ @Throws(SerializationException::class) inline fun ConfigurationNode.get(): V? { - return get(typeTokenOf()) + return get(typeOf().javaType) as V? } /** @@ -68,7 +70,7 @@ inline fun ConfigurationNode.get(): V? { */ @Throws(SerializationException::class) inline fun ConfigurationNode.get(default: V): V { - return get(typeTokenOf(), default) + return get(typeOf().javaType, default) as V } /** @@ -98,6 +100,33 @@ fun ConfigurationNode.get(type: KClass, default: () -> T): T { return get(type.java, default) } +/** + * Get a value from the receiver using the type parameter. + * + * @see ConfigurationNode.get + */ +fun ConfigurationNode.get(type: KType): Any? { + return get(type.javaType) +} + +/** + * Get a value from the receiver using the type parameter. + * + * @see ConfigurationNode.get + */ +fun ConfigurationNode.get(type: KType, default: Any): Any { + return get(type.javaType, default) +} + +/** + * Get a value from the receiver using the type parameter. + * + * @see ConfigurationNode.get + */ +fun ConfigurationNode.get(type: KType, default: () -> Any): Any { + return get(type.javaType, default) +} + /** * Get a value from the receiver using the type parameter. * @@ -105,7 +134,7 @@ fun ConfigurationNode.get(type: KClass, default: () -> T): T { */ @Throws(SerializationException::class) inline fun ConfigurationNode.get(noinline default: () -> V): V { - return get(typeTokenOf(), default) + return get(typeOf().javaType, default) as V } /** @@ -115,7 +144,7 @@ inline fun ConfigurationNode.get(noinline default: () -> V): V { */ @Throws(SerializationException::class) inline fun ConfigurationNode.typedSet(value: V?) { - set(typeTokenOf(), value) + set(typeOf().javaType, value) } /** @@ -136,6 +165,34 @@ fun ConfigurationNode.getList(type: KClass, default: List): List return getList(type.java, default) } +/** + * Get a list value from the receiver using a Kotlin type. + * + * @see ConfigurationNode.getList + */ +fun ConfigurationNode.getList(type: KType): List<*>? { + return getList(type.javaType) +} + +/** + * Get a list value from the receiver using a Kotlin type. + * + * @see ConfigurationNode.getList + */ +fun ConfigurationNode.getList(type: KType, default: List<*>): List<*> { + return getList(type.javaType, default) +} + +/** + * Get a list value with element type [T] from the receiver. + * + * @see ConfigurationNode.getList + */ +@Suppress("UNCHECKED_CAST") +inline fun ConfigurationNode.getList(default: List): List { + return getList(typeOf().javaType, default) as List +} + /** * Set a value on the receiver described by a kotlin class. * @@ -145,6 +202,15 @@ fun ConfigurationNode.set(type: KClass, value: T?): ConfigurationNo return set(type.java, value) } +/** + * Set a value on the receiver described by a kotlin class. + * + * @see ConfigurationNode.set + */ +fun ConfigurationNode.set(type: KType, value: Any?): ConfigurationNode { + return set(type.javaType, value) +} + /** * Set a value on the receiver described by a kotlin class. * @@ -153,3 +219,12 @@ fun ConfigurationNode.set(type: KClass, value: T?): ConfigurationNo fun > N.set(type: KClass, value: T?): N { return set(type.java, value) } + +/** + * Set a value on the receiver described by a kotlin class. + * + * @see ConfigurationNode.set + */ +fun > N.set(type: KType, value: T?): N { + return set(type.javaType, value) +} diff --git a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationReferenceExtensions.kt b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationReferenceExtensions.kt index b2261d701..c57be3847 100644 --- a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationReferenceExtensions.kt +++ b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ConfigurationReferenceExtensions.kt @@ -18,20 +18,23 @@ package org.spongepowered.configurate.kotlin.extensions import kotlinx.coroutines.flow.Flow import org.spongepowered.configurate.ScopedConfigurationNode -import org.spongepowered.configurate.kotlin.typeTokenOf import org.spongepowered.configurate.reference.ConfigurationReference import org.spongepowered.configurate.reference.ValueReference +import kotlin.reflect.jvm.javaType +import kotlin.reflect.typeOf /** Create a flow with events for every refresh of a value backing this reference */ +@Suppress("UNCHECKED_CAST") inline fun > ConfigurationReference.flowOf( vararg path: Any ): Flow { - return this.referenceTo(typeTokenOf(), *path).asFlow() + return (this.referenceTo(typeOf().javaType, *path) as ValueReference).asFlow() } /** Get a reference to the value of type [T] at [path]. */ +@Suppress("UNCHECKED_CAST") inline fun > ConfigurationReference.referenceTo( vararg path: Any ): ValueReference { - return this.referenceTo(typeTokenOf(), *path) + return this.referenceTo(typeOf().javaType, *path) as ValueReference } diff --git a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ObjectMapperExtensions.kt b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ObjectMapperExtensions.kt index 34beaed12..78d1bdb1d 100644 --- a/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ObjectMapperExtensions.kt +++ b/extra/kotlin/src/main/kotlin/org/spongepowered/configurate/kotlin/extensions/ObjectMapperExtensions.kt @@ -17,7 +17,6 @@ package org.spongepowered.configurate.kotlin.extensions import kotlin.reflect.KClass -import org.spongepowered.configurate.kotlin.typeTokenOf import org.spongepowered.configurate.objectmapping.ObjectMapper import org.spongepowered.configurate.objectmapping.ObjectMapper.Factory import org.spongepowered.configurate.objectmapping.ObjectMapper.Factory.Builder @@ -25,13 +24,25 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint import org.spongepowered.configurate.objectmapping.meta.Processor import org.spongepowered.configurate.serialize.TypeSerializer import org.spongepowered.configurate.serialize.TypeSerializerCollection +import kotlin.reflect.KType +import kotlin.reflect.jvm.javaType +import kotlin.reflect.typeOf /** * Create an object mapper with the given [Factory] for objects of type [T], accepting parameterized * types. */ +@Suppress("UNCHECKED_CAST") inline fun Factory.get(): ObjectMapper { - return get(typeTokenOf()) + return get(typeOf().javaType) as ObjectMapper +} + +/** + * Create an object mapper with the given [Factory] for objects of type [type], accepting parameterized + * types. + */ +fun Factory.get(type: KType): ObjectMapper<*> { + return get(type.javaType) } /** @@ -46,8 +57,16 @@ fun Factory.get(type: KClass): ObjectMapper { /** * Get the appropriate [TypeSerializer] for the provided type [T], or null if none is applicable. */ +@Suppress("UNCHECKED_CAST") inline fun TypeSerializerCollection.get(): TypeSerializer? { - return get(typeTokenOf()) + return get(typeOf().javaType) as TypeSerializer? +} + +/** + * Get the appropriate [TypeSerializer] for the provided type [type], or null if none is applicable. + */ +fun TypeSerializerCollection.get(type: KType): TypeSerializer<*>? { + return get(type.javaType) } /** From ba4aae25c492c00792254ed0cad1e046f06616d8 Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Mon, 24 Jul 2023 15:32:16 +0200 Subject: [PATCH 5/5] Add missing javadoc --- .../reference/ConfigurationReference.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java b/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java index 6d52a2e48..e65918fe9 100644 --- a/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java +++ b/core/src/main/java/org/spongepowered/configurate/reference/ConfigurationReference.java @@ -272,6 +272,21 @@ default void set(final NodePath path, final TypeToken type, final @Nullab this.node().node(path).set(type, value); } + /** + * Create a reference to the node at the provided path. The value will be + * deserialized according to the provided {@link Type}. + * + *

The returned reference will update with reloads of and changes to the + * value of the provided configuration. Any serialization errors encountered + * will be submitted to the {@link #errors()} stream. + * + * @param type the value's type + * @param path the path from the root node to the node containing the value + * @return a deserializing reference to the node at the given path + * @throws SerializationException if a type serializer could not be found + * for the provided type + * @since TODO: version + */ default ValueReference referenceTo(final Type type, final Object... path) throws SerializationException { return this.referenceTo(type, NodePath.of(path)); }