From c3756b259a4504a061f2dd1e77e32f71562d2dbb Mon Sep 17 00:00:00 2001 From: DBotThePony <dbotthepony@yandex.ru> Date: Wed, 8 Feb 2023 10:47:56 +0700 Subject: [PATCH] =?UTF-8?q?=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5=20=D0=B1=D1=8B?= =?UTF-8?q?=D1=81=D1=82=D1=80=D1=8B=D0=B9=20isMarkedNullable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../defs/item/DynamicItemDefinition.kt | 2 ++ .../io/json/builder/BuilderAdapter.kt | 26 +++++++++++++------ .../io/json/builder/FactoryAdapter.kt | 4 +-- .../kstarbound/io/json/builder/Properties.kt | 4 +++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/DynamicItemDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/DynamicItemDefinition.kt index 39fe10a3..d23fd401 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/DynamicItemDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/DynamicItemDefinition.kt @@ -8,5 +8,7 @@ class DynamicItemDefinition(def: RegistryObject<IItemDefinition>) : DynamicDefin override fun sanitize(saveInput: JsonObject) { saveInput.remove("itemName") saveInput.remove("pickupQuestTemplates") + saveInput.remove("scripts") + saveInput.remove("scriptDelta") } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt index 5a07adf4..dedce642 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt @@ -60,6 +60,7 @@ class BuilderAdapter<T : Any> private constructor( val stringInterner: Interner<String> = Interner { it }, ) : TypeAdapter<T>() { private val loggedMisses = ObjectOpenHashSet<String>() + private val flatProperties = properties.values.filter { it.isFlat } override fun write(writer: JsonWriter, value: T) { TODO("Not yet implemented") @@ -69,13 +70,16 @@ class BuilderAdapter<T : Any> private constructor( @Suppress("name_shadowing") var reader = reader + // загружаем указатели на стек + val properties = properties + val missing = ObjectOpenHashSet<IResolvedMutableProperty<T, *>>() missing.addAll(properties.values) val instance = factory.invoke() var json: JsonObject by Delegates.notNull() - if (instance is IJsonHolder || properties.values.any { it.isFlat }) { + if (instance is IJsonHolder || flatProperties.isNotEmpty()) { json = TypeAdapters.JSON_ELEMENT.read(reader) as JsonObject reader = JsonTreeReader(json) @@ -86,6 +90,12 @@ class BuilderAdapter<T : Any> private constructor( } } + // загружаем указатели на стек + val logMisses = logMisses + val extraPropertiesAreFatal = extraPropertiesAreFatal + val loggedMisses = loggedMisses + val ignoreKeys = ignoreKeys + reader.beginObject() while (reader.hasNext()) { @@ -102,15 +112,15 @@ class BuilderAdapter<T : Any> private constructor( try { val peek = reader.peek() - if (!property.type.isMarkedNullable && peek == JsonToken.NULL) { + if (!property.isMarkedNullable && peek === JsonToken.NULL) { throw NullPointerException("Property ${property.name} of ${instance::class.qualifiedName} does not accept nulls (JSON contains null)") - } else if (peek == JsonToken.NULL) { + } else if (peek === JsonToken.NULL) { property.set(instance, null) reader.nextNull() } else { val readValue = property.adapter.read(reader) - if (!property.type.isMarkedNullable && readValue == null) + if (!property.isMarkedNullable && readValue == null) throw JsonSyntaxException("Property ${property.name} of ${instance::class.qualifiedName} does not accept nulls (Type provider returned null)") property.set(instance, readValue) @@ -134,14 +144,14 @@ class BuilderAdapter<T : Any> private constructor( reader.endObject() - for (property in properties.values) { - if (!property.isFlat || !missing.remove(property)) + for (property in flatProperties) { + if (!missing.remove(property)) continue try { val read = property.adapter.read(JsonTreeReader(json)) - if (!property.type.isMarkedNullable && read == null) { + if (!property.isMarkedNullable && read == null) { throw NullPointerException("Property ${property.name} of ${instance::class.qualifiedName} does not accept nulls (flat property adapter returned NULL)") } else if (read == null) { property.set(instance, null) @@ -157,7 +167,7 @@ class BuilderAdapter<T : Any> private constructor( if (property.mustBePresent == true) { throw JsonSyntaxException("${instance::class.qualifiedName} demands for ${property.name} to be present, however, it is missing from JSON structure") } else if (property.mustBePresent == null) { - if (property.type.isMarkedNullable) { + if (property.isMarkedNullable) { continue } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt index eb1bcaee..3a54183a 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt @@ -296,7 +296,7 @@ class FactoryAdapter<T : Any> private constructor( val (field) = tuple if (readValues[i] == null) { - if (!tuple.type.isMarkedNullable) { + if (!tuple.isMarkedNullable) { throw JsonSyntaxException("Field ${field.name} of ${bound.qualifiedName} does not accept nulls") } @@ -350,7 +350,7 @@ class FactoryAdapter<T : Any> private constructor( throw JsonSyntaxException("Field ${field.name} of ${bound.qualifiedName} is missing") } - if (tuple.type.isMarkedNullable) { + if (tuple.isMarkedNullable) { continue } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/Properties.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/Properties.kt index 187d6d74..286c3d25 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/Properties.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/Properties.kt @@ -28,6 +28,7 @@ interface IResolvableProperty<T : Any, V> : IReferencedProperty<T, V> { interface IResolvedProperty<T : Any, V> : IReferencedProperty<T, V> { val type: KType val adapter: TypeAdapter<V> + val isMarkedNullable: Boolean operator fun component1() = property operator fun component2() = adapter @@ -39,6 +40,7 @@ class ResolvedProperty<T : Any, V>( override val isFlat: Boolean ) : IResolvableProperty<T, V>, IResolvedProperty<T, V> { override val type: KType = property.returnType + override val isMarkedNullable: Boolean = type.isMarkedNullable override fun resolve(gson: Gson?): IResolvedProperty<T, V> { return this @@ -74,6 +76,7 @@ interface IResolvableMutableProperty<T : Any, V> : IReferencedMutableProperty<T, interface IResolvedMutableProperty<T : Any, V> : IResolvableMutableProperty<T, V> { val type: KType val adapter: TypeAdapter<V> + val isMarkedNullable: Boolean operator fun component1() = property operator fun component2() = adapter @@ -91,6 +94,7 @@ class ResolvedMutableProperty<T : Any, V>( override val mustBePresent: Boolean? ) : IResolvableMutableProperty<T, V>, IResolvedMutableProperty<T, V> { override val type: KType = property.returnType + override val isMarkedNullable: Boolean = type.isMarkedNullable override fun resolve(gson: Gson?): IResolvedMutableProperty<T, V> { return this