Remove more verbose default values in ConstructorCallCodegen

This commit is contained in:
Him188 2021-08-27 20:03:08 +08:00
parent ec9ad7f0f1
commit c36d1b15f4

View File

@ -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<Any>(), setOf<Any>(), mapOf<Any, Any>(),
-> 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
}
}