mercredi 15 janvier 2020

Recursively filter and map a list of properties

I'm using Kotlin reflection to check if attributes that have a certain annotation are null.

Given the following example:

data class DataClass(
    @SomeRandomAnnotation
    val otherAnnotated: String?,
    val inner: InnerClass
)

data class AnotherDataClass(
    @SomeRandomAnnotation
    val annotatedProperty: String?,
    val dataClass: DataClass
) {

    fun checkCreditAnalysisConstrain() {
        print(checkConstrain(this))
    }
}

And the function that checks it:

fun checkConstrain(parentClass: Any): List<String> {
    val filter = parentClass::class.memberProperties.filter {
        if (memberIsDataClass(it)) checkConstrain(getMemberPropertyInstance(parentClass, it))

        hasAnnotation(it) && propertyIsNull(it, parentClass)
    }
    return filter.map { formatResult(parentClass, it) }
}

The idea is that the function is going to iterate through the attributes of my classes checking if they have the annotation and checking if the value is null. If the property is a data class, the code evaluates the properties of the childs, recursively.

After that, I map the results, transforming the KProperty's into a simple String that is human readable, containing the class name and the attribute name.

The problem is that the above code does not work as expected. The properties returned are only the properties from the first-level class.

If, instead of doing a filter, I just run a forEach and print the result, I get the expected attributes. So I'm pretty sure it's related to the recurring inside a filter.

Do you see any way of doing this in a more functional way? I'm just concerned I won't need a "temp" list and add values to the list and reset it afterwards.





Aucun commentaire:

Enregistrer un commentaire