https://kotlinlang.org logo
Title
k

Ky

02/25/2020, 7:43 PM
Hallo alle. Maybe you can help me with something. I’m currently writing a custom lint rule for my ViewModel classes which checks to make sure no public functions return any type. It’s almost working working except for the fact that my ViewModel’s are
data class
and lint seems to be considering the parameters of the
data class
as a method.
data class ListViewModel(
    private val handle: SavedStateHandle,
    private val repository: ListRepository,
    private val scheduler: IObservableSchedulerRx2,
    private val errorHandler: Mvvm.ErrorHandler
)
So for each method, I am logging the method name and return type, and this is the output when it hits these params
METHOD NAME: component1
FUN RETURN TYPE: PsiType:SavedStateHandle
component2, component3, etc.. for each subsequent parameter. Any suggestions?
w

wasyl

02/25/2020, 7:55 PM
Ignore methods called
componentX
😉 I think it’s reasonable enough to assume this will block any possible actual mistakes. Or consider not making your view models data classes — I wouldn’t say its what
data classes
are for, generally
k

Ky

02/25/2020, 8:13 PM
@wasyl Thanks for the response and advice. This leads me to another question, Im using
@Parcelize
and the lint is also considering these methods and causing the rule to fail(
toString
,
hashCode
,
equals
,
copy
) Obviously I can just ignore these methods individually but are you aware of a way to just ignore the @Parcelize annotation?
w

wasyl

02/25/2020, 8:19 PM
The methods you pasted actually don’t have anything to do with
@Parcelize
, but with the class being
data class
, so I’d say removing it makes even more sense 😉
But I suppose there might be a way for find methods that were written explicitly and not generated. I just don’t know it from top of my head
From what I see when you have a reference to
node: UMethod
in the detector, you can check
node.sourceElement
to get what part of source resulted in that method in the tree. For me when I log these (
println("${node.name} : ${node.sourceElement}")
), it looks like this:
getClassProperty : class org.jetbrains.kotlin.psi.KtProperty
methodReturningInt : class org.jetbrains.kotlin.psi.KtNamedFunction
methodReturningUnit : class org.jetbrains.kotlin.psi.KtNamedFunction
getConstructorProperty : class org.jetbrains.kotlin.psi.KtParameter
TestClass : class org.jetbrains.kotlin.psi.KtPrimaryConstructor
component1 : class org.jetbrains.kotlin.psi.KtParameter
copy : class org.jetbrains.kotlin.psi.KtClass
toString : class org.jetbrains.kotlin.psi.KtClass
hashCode : class org.jetbrains.kotlin.psi.KtClass
equals : class org.jetbrains.kotlin.psi.KtClass
Only methods written explicitly are have
fun
source element, which is of type
org.jetbrains.kotlin.psi.KtNamedFunction
. So seems
node.sourceElement is KtNamedFunction
pretty good discriminator for the methods you’re looking for.
k

Ky

02/25/2020, 8:32 PM
Yes sorry idk why I was thinking Parcelable, I have a sealed class within my ViewModel which extends Parcelable and is used to represent the ViewModel State. Ahh ok, I think this is exactly what I’m looking for. I wasn’t using the
sourceElement
but clearly this is very helpful and should solve my problem Thanks!!
👍 1