Bob
Bob

Reputation: 529

Custom lint rule kotlin object

I'm trying to create a custom lint rule in order to avoid using a kotlin object class.

object AColors {
    val white: Color = Color(0xFFFFFFFF)
}

fun main() {

  val myColor = AColors.white //Lint error : Do not use AColors 
}

How can I manage to get a lint issue when AColors is used?

In my case, AColors can't be private because I need it for a specific case.

I tried to create a custom lint rule to check the import but this is not a bullet-proof solution as you can use AColors without importing anything

    class InvalidImportHandler(private val context: JavaContext) : UElementHandler() {

        override fun visitImportStatement(node: UImportStatement) {
          //check the import
        }
    }

Upvotes: 1

Views: 213

Answers (1)

Xid
Xid

Reputation: 4951

For this specific case, you may check for USimpleNameReferenceExpressions and then check if the reference is to the AColors class. Like so:

class AColorsReferenceDetector : Detector(), Detector.UastScanner {

    override fun getApplicableUastTypes(): List<Class<out UElement>> {
        return listOf(USimpleNameReferenceExpression::class.java)
    }

    override fun createUastHandler(context: JavaContext): UElementHandler {
        return object : UElementHandler() {
            override fun visitSimpleNameReferenceExpression(
                node: USimpleNameReferenceExpression
            ) {
                val element = node.resolve()?.unwrapped
                if (element is KtObjectDeclaration && element.name == "AColors") {
                    context.report(
                        ISSUE, 
                        node, 
                        context.getLocation(node.uastParent)
                    )
                }
            }
        }
    }

    companion object {
        val ISSUE = Issue.create(
            AColorsReferenceDetector::class.simpleName.orEmpty(),
            "Do not use AColors",
            "Do not use AColors",
            Category.CORRECTNESS,
            10,
            Severity.ERROR,
            Implementation(
                AColorsReferenceDetector::class.java,
                EnumSet.of(Scope.JAVA_FILE)
            )
        )
    }
}

Example IssueRegistry:

class IssueRegistry : IssueRegistry() {
    override val api = CURRENT_API

    override val minApi: Int
        get() = 8

    override val vendor: Vendor = Vendor()

    override val issues
         get() = listOf(AColorsReferenceDetector.ISSUE)
}

Example result: Example output

Upvotes: 2

Related Questions