Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building a Better Codebase with Lint - Droidcon Americas

Building a Better Codebase with Lint - Droidcon Americas

Subhrajyoti Sen

November 17, 2020
Tweet

More Decks by Subhrajyoti Sen

Other Decks in Programming

Transcript

  1. What is Lint? • Static analysis tool • Open Source

    • Works on .java, .kt, .gradle and a lot more
  2. What is Lint? • Static analysis tool • Open Source

    • Works on .java, .kt, .gradle and a lot more • Can be used outside Android as well
  3. What is Lint? • Static analysis tool • Open Source

    • Works on .java, .kt, .gradle and a lot more • Can be used outside Android as well • Can be extended to write custom rules
  4. What is Lint? • Static analysis tool • Open Source

    • Works on .java, .kt, .gradle and a lot more • Can be used outside Android as well • Can be extended to write custom rules • Can be run from both Android Studio and CLI
  5. Issue Registry class Registry : IssueRegistry() { override val api:

    Int = CURRENT_API @get:NotNull override val issues: List<Issue> get() = listOf() }
  6. The Basic Elements Scope The kind of files the lint

    rule applies to • JAVA_FILE_SCOPE • GRADLE_SCOPE • MANIFEST_SCOPE • PROGUARD_SCOPE • RESOURCE_FILE_SCOPE
  7. The Basic Elements Severity How severe is the issue •

    INFORMATIONAL • WARNING • ERROR • FATAL
  8. The Basic Elements Category The category the issue falls in,

    from a pre-defined list of categories • SECURITY • PERFORMANCE • L18N • A11Y
  9. Custom Rule Structure val ISSUE: Issue = Issue.create( "MissingStyleAttribute", "style

    attribute is missing", "We should use style to style a TextView " + "in order to provide consistent design", Category.CORRECTNESS, 5, Severity.ERROR, Implementation( MissingStyleAttributeDetector::class.java, Scope.RESOURCE_FILE_SCOPE ) )
  10. Custom Rule Structure class MissingStyleAttributeDetector : ResourceXmlDetector() { @Nullable override

    fun getApplicableElements(): Collection<String>? { return listOf("TextView") } }
  11. Custom Rule Structure class MissingStyleAttributeDetector : ResourceXmlDetector() { @Nullable override

    fun getApplicableElements(): Collection<String>? { return listOf(SdkConstants.TEXT_VIEW) } }
  12. Custom Rule Structure class MissingStyleAttributeDetector : ResourceXmlDetector() { //.. override

    fun appliesTo(folderType: ResourceFolderType): Boolean { return folderType == ResourceFolderType.LAYOUT } }
  13. Custom Rule Structure class MissingStyleAttributeDetector : ResourceXmlDetector() { //.. override

    fun visitElement(context: XmlContext, element: Element) { if (!element.hasAttribute(SdkConstants.ATTR_STYLE)) { context.report( ISSUE, element, context.getLocation(element), "Add style to TextView in order to provide consistent design" ) } } }
  14. Remember this? class MissingStyleAttributeDetector : ResourceXmlDetector() { @Nullable override fun

    getApplicableElements(): Collection<String>? { return listOf(SdkConstants.TEXT_VIEW) } }
  15. lint-baseline.xml <issues format="5" by="lint 3.6.3" client="gradle" variant="debug" version="3.6.3"> <issue id="MissingStyleAttribute"

    message="Add style to TextView in order to provide consistent design" errorLine1=" &lt;TextView" errorLine2=" ^"> <location file="src/main/res/layout/activity_main.xml" line="10" column="5"/> </issue> </issues>
  16. Performance • Single pass • Missing attribute • Fast •

    Enable in IDE • Multiple pass • Unused resources • Slow • Disable in IDE
  17. Kotlin Considerations? • No explicit return statements • No explicit

    type declarations • Write one test case for Kotlin usage