Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Kotlin Static Analysis - Kotlin Everywhere 2019
Search
Matheus Cassiano Candido
October 05, 2019
Programming
0
120
Kotlin Static Analysis - Kotlin Everywhere 2019
Slides for my Kotlin Everywhere talk.
Matheus Cassiano Candido
October 05, 2019
Tweet
Share
More Decks by Matheus Cassiano Candido
See All by Matheus Cassiano Candido
JUnit rules and test parameterization
mcassiano
0
130
unraveling custom drawing
mcassiano
0
85
The Basis of Android Threading: Loopers and Handlers
mcassiano
1
130
Hackeando sua próxima entrevista: dicas para conseguir seu próximo estágio ou emprego
mcassiano
1
94
text spans: what, why and how?
mcassiano
0
660
Navigation patterns on Android and something new
mcassiano
3
400
Como conseguir o estágio (ou emprego) dos sonhos
mcassiano
0
49
Databinding e padrão MVVM
mcassiano
1
26
Desenvolvimento móvel: práticas de sucesso
mcassiano
0
29
Other Decks in Programming
See All in Programming
Register is more than clipboard
satorunooshie
1
390
Temporal Knowledge Graphで作る! 時間変化するナレッジを扱うAI Agentの世界
po3rin
5
1.2k
Bakuraku E2E Scenario Test System Architecture #bakuraku_qa_study
teyamagu
PRO
0
250
AIのバカさ加減に怒る前にやっておくこと
blueeventhorizon
0
150
組織もソフトウェアも難しく考えない、もっとシンプルな考え方で設計する #phpconfuk
o0h
PRO
2
330
data-viz-talk-cz-2025
lcolladotor
0
110
AsyncSequenceとAsyncStreamのプロポーザルを全部読む!!
s_shimotori
1
230
フロントエンド開発のためのブラウザ組み込みAI入門
masashi
7
3.7k
퇴근 후 1억이 거래되는 서비스 만들기 | 내가 AI를 사용하는 방법
maryang
2
420
Verilator + Rust + gRPC と Efinix の RISC-V でAIアクセラレータをAIで作ってる話 RTLを語る会(18) 2025/11/08
ryuz88
0
220
スキーマ駆動で、Zod OpenAPI Honoによる、API開発するために、Hono Takibiというライブラリを作っている
nakita628
0
340
Developer Joy - The New Paradigm
hollycummins
1
410
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
Gamification - CAS2011
davidbonilla
81
5.5k
Docker and Python
trallard
46
3.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.2k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
RailsConf 2023
tenderlove
30
1.3k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Automating Front-end Workflow
addyosmani
1371
200k
Transcript
Mantendo código Kotlin seguro: de ponta a ponta Matheus C.
Candido Mobile Software Engineer @ Uber
Agenda 01 Análise estática 02 Ferramentas 03 Arquitetura 04 Customização
05 Automação
Análise estática Static program analysis is the analysis of computer
software that is performed without actually executing programs
Ktlint Simples, drop-in
Ktlint Simples, drop-in Zero configuração
Ktlint Simples, drop-in Zero configuração Code styling*
Ktlint Simples, drop-in Zero configuração Code styling* Formatador
Ktlint Simples, drop-in Zero configuração Code styling* Formatador Baseado no
Kotlin Style Guide, mas suporta Android Style Guide
Detekt Foco no detalhe
Detekt Foco no detalhe Totalmente configurável
Detekt Foco no detalhe Totalmente configurável Code styling
Detekt Foco no detalhe Totalmente configurável Code styling Performance
Detekt Foco no detalhe Totalmente configurável Code styling Performance Tratamento
de exceções
Android Lint Java, Kotlin e Resources
Android Lint Java, Kotlin e Resources Regras especiais para Android
Android Lint Java, Kotlin e Resources Regras especiais para Android
Super extensível
Android Lint Java, Kotlin e Resources Regras especiais para Android
Super extensível Performance
Android Lint Java, Kotlin e Resources Regras especiais para Android
Super extensível Performance Análise de recursos duplicados/não utilizados
Android Lint Java, Kotlin e Resources Regras especiais para Android
Super extensível Performance Análise de recursos duplicados/não utilizados Funciona para projetos não-Android
Warning vs. Errors
Baseline
Ignorando issues conhecidos @SuppressLint("NewApi") @Suppress("NewApi")
Arquitetura
Arquitetura
None
Arquitetura
Criando novas regras
Issue registry @AutoService(IssueRegistry::class) class Registry() :fIssueRegistry() {f override val issues:
List<Issue> = listOf(GetDrawableDetector.ISSUE) override val api: Int = CURRENT_API }f
Issue registry @AutoService(IssueRegistry::class) class Registry() :fIssueRegistry() {f override val issues:
List<Issue> = listOf(GetDrawableDetector.ISSUE) override val api: Int = CURRENT_API }f
Issue registry @AutoService(IssueRegistry::class) class Registry() :fIssueRegistry() {f override val issues:
List<Issue> = listOf(GetDrawableDetector.ISSUE) override val api: Int = CURRENT_API }f
Criando um detector /** *fDetector to check for usages of
`ResourcesCompat.getDrawable` or `ContextCompat.getDrawable`. */ class GetDrawableDetector :fDetector(), SourceCodeScanner {f companion object {f val ISSUE =fIssue.create(f id =fISSUE_ID, briefDescription =fBRIEF_DESCRIPTION, explanation =fLINT_ERROR_MESSAGE, category =fCategory.CORRECTNESS,
Descrição da Issue val ISSUE =fIssue.create(f id =fISSUE_ID, briefDescription =fBRIEF_DESCRIPTION,
explanation =fLINT_ERROR_MESSAGE, category =fCategory.CORRECTNESS, priority =f6, severity =fSeverity.ERROR, implementation =fcreate<GetDrawableDetector>()) }f override fun getApplicableMethodNames() = listOf("getDrawable") override fun visitMethodCall(f context:fJavaContext,
Descrição da Issue val ISSUE =fIssue.create(f id =fISSUE_ID, briefDescription =fBRIEF_DESCRIPTION,
explanation =fLINT_ERROR_MESSAGE, category =fCategory.CORRECTNESS, priority =f6, severity =fSeverity.ERROR, implementation =fcreate<GetDrawableDetector>()) }f override fun getApplicableMethodNames() = listOf("getDrawable") override fun visitMethodCall(f context:fJavaContext,
Descrição da Issue val ISSUE =fIssue.create(f id =fISSUE_ID, briefDescription =fBRIEF_DESCRIPTION,
explanation =fLINT_ERROR_MESSAGE, category =fCategory.CORRECTNESS, priority =f6, severity =fSeverity.ERROR, implementation =fcreate<GetDrawableDetector>()) }f override fun getApplicableMethodNames() = listOf("getDrawable") override fun visitMethodCall(f context:fJavaContext,
Descrição da Issue val ISSUE =fIssue.create(f id =fISSUE_ID, briefDescription =fBRIEF_DESCRIPTION,
explanation =fLINT_ERROR_MESSAGE, category =fCategory.CORRECTNESS, priority =f6, severity =fSeverity.ERROR, implementation =fcreate<GetDrawableDetector>()) }f override fun getApplicableMethodNames() =f listOf("getDrawable") override fun visitMethodCall(f context:fJavaContext,
Filtrando a entrada overrideffunfgetApplicableMethodNames() =f listOf("getDrawable")f override fun visitMethodCall(f context:fJavaContext,
node:fUCallExpression, method:fPsiMethod ){f iff(! getApplicableMethodNames().contains(node.methodName))freturn if (node.methodName == "getDrawable" && isBlacklisted(context.evaluator, node)) {f context.report(ISSUE, context.getLocation(node),
Detectando os problemas override fun visitMethodCall(f context:fJavaContext, node:fUCallExpression, method:fPsiMethod ){f
iff(! getApplicableMethodNames().contains(node.methodName))freturn if (node.methodName == "getDrawable" && isBlacklisted(context.evaluator, node)) {f context.report(ISSUE, context.getLocation(node), LINT_ERROR_MESSAGE) }f
Detectando os problemas iff(! getApplicableMethodNames().contains(node.methodName))freturn if (node.methodName == "getDrawable" &&
isBlacklisted(context.evaluator, node)) {f context.report(ISSUE, context.getLocation(node), LINT_ERROR_MESSAGE) }f }f private fun isBlacklisted():fBoolean {f return evaluator.isMemberInClass(node.resolve(), "androidx.core.content.ContextCompat") ||f
Detectando os problemas iff(! getApplicableMethodNames().contains(node.methodName))freturn if (node.methodName == "getDrawable" &&
isBlacklisted(context.evaluator, node)) {f context.report(ISSUE, context.getLocation(node), LINT_ERROR_MESSAGE) }f }f private fun isBlacklisted():fBoolean {f return evaluator.isMemberInClass(node.resolve(), "androidx.core.content.ContextCompat") ||f
Detectando os problemas context.report(ISSUE, context.getLocation(node), LINT_ERROR_MESSAGE) }f }f private fun
isBlacklisted():fBoolean {f return evaluator.isMemberInClass(node.resolve(),f "androidx.core.content.ContextCompat") ||f evaluator.isMemberInClass(node.resolve(), "androidx.core.content.res.ResourcesCompat")f }f }f
Usando a nova regra // no build.gradle dos outros projetos
dependencies {f lintChecks project(":meu_detector") }f
Usando a nova regra // no build.gradle dos outros projetos
dependencies {f lintChecks project(":meu_detector") }f
Relatórios
Relatórios
Relatórios
Evolução do código
None
Automação
Automação https://bit.cassiano.me/sa-automation
Automação https://bit.cassiano.me/sa-automation
Automação https://bit.cassiano.me/sa-comment-machine
Automação https://bit.cassiano.me/sa-git-hooks
Automação https://bit.cassiano.me/sa-git-hooks
Resumo Combine as ferramentas e aproveite o melhor de cada
uma
Resumo Combine as ferramentas e aproveite o melhor de cada
uma Aplique as regras que façam sentido para seu contexto
Resumo Combine as ferramentas e aproveite o melhor de cada
uma Aplique as regras que façam sentido para seu contexto Automatize a formatação dos arquivos e partes do code review
https://bit.cassiano.me/sa-kotlin-conf-17-talk
https://bit.cassiano.me/sa-kotlin-conf-18-talk
…perguntas?