From c36d1b15f4ea606af63e0378c9481aea0a085e72 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 27 Aug 2021 20:03:08 +0800 Subject: [PATCH] Remove more verbose default values in ConstructorCallCodegen --- .../kotlin/utils/codegen/ValueDescVisitor.kt | 62 +++++++++++++++---- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/mirai-core/src/commonTest/kotlin/utils/codegen/ValueDescVisitor.kt b/mirai-core/src/commonTest/kotlin/utils/codegen/ValueDescVisitor.kt index 6b6ef5f98..7c9a00832 100644 --- a/mirai-core/src/commonTest/kotlin/utils/codegen/ValueDescVisitor.kt +++ b/mirai-core/src/commonTest/kotlin/utils/codegen/ValueDescVisitor.kt @@ -113,27 +113,65 @@ class RemoveDefaultValuesVisitor( // remove properties who have the same values as their default values, this would significantly reduce code size. mapping.forEach { (name, defaultValue) -> if (desc.properties.entries.removeIf { - it.key.name == name && equals(it.value.origin, defaultValue) - } - ) { + it.key.name == name && isDefaultOrEmpty(it.key, it.value, defaultValue) + }) { return@forEach // by removing one property, there will not by any other matches } } } + private fun isDefaultOrEmpty(key: KParameter, value: ValueDesc, defaultValue: Any?): Boolean { + if (!key.isOptional) return false + if (equals(value.origin, defaultValue)) return true + + if (value is ClassValueDesc<*> + && value.properties.all { it.key.isOptional && isDefaultOrEmpty(it.key, it.value, defaultValue) } + ) { + return true + } + + return false + } + + private fun Any?.isNullOrZeroOrEmpty(): Boolean { + when (this) { + null, + 0.toByte(), 0.toShort(), 0, 0L, 0.toFloat(), 0.toDouble(), 0.toChar(), + "", listOf(), setOf(), mapOf(), + -> return true + } + + check(this != null) + + when { + this is Array<*> && this.isEmpty() -> return true + this is IntArray && this.isEmpty() -> return true + this is ByteArray && this.isEmpty() -> return true + this is ShortArray && this.isEmpty() -> return true + this is LongArray && this.isEmpty() -> return true + this is CharArray && this.isEmpty() -> return true + this is FloatArray && this.isEmpty() -> return true + this is DoubleArray && this.isEmpty() -> return true + this is BooleanArray && this.isEmpty() -> return true + } + + return false + } + fun equals(a: Any?, b: Any?): Boolean { + if (a.isNullOrZeroOrEmpty() && b.isNullOrZeroOrEmpty()) return true return when { a === b -> true a == b -> true - a is Array<*> && b is Array<*> -> a.contentEquals(b) - a is IntArray && b is IntArray -> a.contentEquals(b) - a is ByteArray && b is ByteArray -> a.contentEquals(b) - a is ShortArray && b is ShortArray -> a.contentEquals(b) - a is LongArray && b is LongArray -> a.contentEquals(b) - a is CharArray && b is CharArray -> a.contentEquals(b) - a is FloatArray && b is FloatArray -> a.contentEquals(b) - a is DoubleArray && b is DoubleArray -> a.contentEquals(b) - a is BooleanArray && b is BooleanArray -> a.contentEquals(b) + a is Array<*>? && b is Array<*>? -> a.contentEquals(b) + a is IntArray? && b is IntArray? -> a.contentEquals(b) + a is ByteArray? && b is ByteArray? -> a.contentEquals(b) + a is ShortArray? && b is ShortArray? -> a.contentEquals(b) + a is LongArray? && b is LongArray? -> a.contentEquals(b) + a is CharArray? && b is CharArray? -> a.contentEquals(b) + a is FloatArray? && b is FloatArray? -> a.contentEquals(b) + a is DoubleArray? && b is DoubleArray? -> a.contentEquals(b) + a is BooleanArray? && b is BooleanArray? -> a.contentEquals(b) else -> false } }