Пользовательское правило Lint для проверки всех видов в макетах - PullRequest
0 голосов
/ 26 марта 2020

В приложении, над которым я работаю, обязательно, чтобы для всех видов во всех файлах макета было установлено значение id. Поэтому я пытаюсь создать собственное правило lint для обеспечения этого.

Обычно можно использовать метод getApplicableElements() из XmlScanner и включать список строк для каждого тега элемента. Тем не менее, я не могу найти способ взглянуть на все элементы в макете XML, который подкласс View.

Я пытался использовать XmlScannerConstants.ALL, который просматривает все элемент в каждом файле XML. Учитывая, что у нас есть несколько других типов ресурсов XML, это не сработает.

Мой код для класса инспектора приведен ниже. Кто-нибудь знает хороший способ фильтрации getApplicableElements(), чтобы он смотрел на каждый элемент, который подклассов View, и ничего больше?

class IdDetector : ResourceXmlDetector() {

    companion object {

        private const val ISSUE_ID = "MissingId"
        private const val ISSUE_DESCRIPTION = "Missing required attribute 'id'"
        private const val ISSUE_EXPLANATION = "Identifiers are required on all views."

        val ISSUE = Issue.create(
            id = ISSUE_ID,
            briefDescription = ISSUE_DESCRIPTION,
            explanation = ISSUE_EXPLANATION,
            category = Category.A11Y,
            priority = 10,
            severity = Severity.FATAL,
            androidSpecific = true,
            implementation = Implementation(IdDetector::class.java, Scope.RESOURCE_FILE_SCOPE)
        )
    }

    override fun getApplicableElements(): Collection<String>? = XmlScannerConstants.ALL

    override fun visitElement(context: XmlContext, element: Element) {
        if (!element.hasAttributeNS("http://schemas.android.com/apk/res/android", "id")) {
            context.report(ISSUE, element, context.getLocation(element), ISSUE_DESCRIPTION)
        }
    }
}

1 Ответ

0 голосов
/ 21 апреля 2020

Существует метод appliesTo(@NonNull ResourceFolderType folderType), который может помочь вам достичь этого. Я полагаю, что в вашем случае вас заинтересует только ориентация папки макета. Ваш новый детектор будет выглядеть примерно так:

class IdDetector : ResourceXmlDetector() {

    companion object {

        private const val ISSUE_ID = "MissingId"
        private const val ISSUE_DESCRIPTION = "Missing required attribute 'id'"
        private const val ISSUE_EXPLANATION = "Identifiers are required on all views."

        val ISSUE = Issue.create(
            id = ISSUE_ID,
            briefDescription = ISSUE_DESCRIPTION,
            explanation = ISSUE_EXPLANATION,
            category = Category.A11Y,
            priority = 10,
            severity = Severity.FATAL,
            androidSpecific = true,
            implementation = Implementation(IdDetector::class.java, Scope.RESOURCE_FILE_SCOPE)
        )
    }

    override fun appliesTo(folderType: ResourceFolderType): Boolean = ResourceFolderType.LAYOUT == folderType

    override fun getApplicableElements(): Collection<String>? = XmlScannerConstants.ALL

    override fun visitElement(context: XmlContext, element: Element) {
        if (!element.hasAttributeNS("http://schemas.android.com/apk/res/android", "id")) {
            context.report(ISSUE, element, context.getLocation(element), ISSUE_DESCRIPTION)
        }
    }
}
...