Android Custom Lint Detector - replicate suspend function warning for non suspend functions

43 Views Asked by At

I have a requirement to put some lint checks to warn users to call specific functions (which are non-spending and blocking from a library) to be called from within a suspend function or a coroutine.

I can identify different methods using UCallExpression - overriding visitCallExpressions(). But when there are nested methods and lambdas I cannot identify which is the actual parent - lambda or the containing method.

How to identify immediate parents?

// case 1
fun foo(){
   launchl{
     val a = object: XYZ {
       override fun foobar(): Int {
         ABC.testFunc()
       }
     }
    }
}

// case 2
fun foo(){
   launchl{
      ABC.testFunc()
    }
}

// case 3
suspend fun foo() {
  ABC.testFunc()
}

Using combinations of the following, I can identify if the testFunc() is inside a coroutine block like launch, async, future, etc. for Case 2 and Case 3:

node = current.getParentType(KotlinUFunctionCallExpression::class.java)

and below to identify methods and class:

(node.receiver as KotlinUQualifiedReferenceExpression).getExpressionType().canonicalText
or
(node.receiver as PsiClassReferenceType).resolve().qualifiedName
or
node.resolve().containingClass.qualifiedName
or
node.methodIdentifier.name

and below code for identifying the suspend function:

current.getParentofType(KotlinUMethod::class.java).modifierList.text

For Case 1, I can use any of the above codes to extract foobar(), launch{} or foo(), but how can I identify which is the first block containing the call ABC.testFunc()? e.g. for Case 1, it should be foobar() and I should WARN using lint to make foobar a suspend or call ABC.testFunc() from inside another coroutine block.

0

There are 0 best solutions below