safe r kotlin code
play

Safe(r) Kotlin Code Static Analysis Tools for Kotlin Marvin Ramin - PowerPoint PPT Presentation

Safe(r) Kotlin Code Static Analysis Tools for Kotlin Marvin Ramin Static Analysis public class kotlinconf { var YEAR = 2018 fun Welcome(year: Int?) { println("Welcome to KotlinConf ${year!!}!") } } public class kotlinconf {


  1. import android.util.Log 0: UFile 1: UImportStatement import com.something.Else 2: UImportStatement 4: UClass class Something {

  2. class ImportVisitor(private val context: JavaContext) : UElementHandler() { override fun visitImportStatement(import: UImportStatement) { val resolved = import.resolve() if (resolved !is PsiClass) { return } if (resolved.qualifiedName == "android.util.Log") { context.report(ISSUE, import, context.getLocation(import), "...") } } }

  3. class ImportVisitor(private val context: JavaContext) : UElementHandler() { override fun visitImportStatement(import: UImportStatement) { val resolved = import.resolve() if (resolved !is PsiClass) { return } if (resolved.qualifiedName == "android.util.Log") { context.report(ISSUE, import, context.getLocation(import), "...") } } }

  4. class ImportVisitor(private val context: JavaContext) : UElementHandler() { override fun visitImportStatement(import: UImportStatement) { val resolved = import.resolve() if (resolved !is PsiClass) { return } if (resolved.qualifiedName == "android.util.Log") { context.report(ISSUE, import, context.getLocation(import), "...") } } }

  5. class ImportVisitor(private val context: JavaContext) : UElementHandler() { override fun visitImportStatement(import: UImportStatement) { val resolved = import.resolve() if (resolved !is PsiClass) { return } if (resolved.qualifiedName == "android.util.Log") { context.report(ISSUE, import, context.getLocation(import), "...") } } }

  6. class ImportVisitor(private val context: JavaContext) : UElementHandler() { override fun visitImportStatement(import: UImportStatement) { val resolved = import.resolve() if (resolved !is PsiClass) { return } if (resolved.qualifiedName == "android.util.Log") { context.report(ISSUE, import, context.getLocation(import), "...") } } }

  7. android.util.Log

  8. android.util.Log "android.util.Log"

  9. class AndroidLogDetector : Detector(), Detector.UastScanner { override fun getApplicableUastTypes(): List<Class<out UElement>>? { return listOf(UImportStatement::class.java) } }

  10. class AndroidLogDetector : Detector(), Detector.UastScanner { override fun getApplicableUastTypes(): List<Class<out UElement>>? { return listOf(UImportStatement::class.java) } }

  11. class AndroidLogDetector : Detector(), Detector.UastScanner { override fun getApplicableUastTypes(): List<Class<out UElement>>? { return listOf(UImportStatement::class.java) } }

  12. Findings Reports

  13. HTML Reports XML

  14. Extensibility

  15. AST Detector

  16. AST Detector

  17. package com.example class CustomIssueRegistry : IssueRegistry() { override fun getIssues() = listOf(ISSUE_ANDROID_LOG) }

  18. jar { manifest { attributes("Lint-Registry-v2": "com.example.CustomIssueRegistry") } }

  19. Write your custom Issue & Detector

Recommend


More recommend