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
86
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
96
text spans: what, why and how?
mcassiano
0
690
Navigation patterns on Android and something new
mcassiano
3
400
Como conseguir o estágio (ou emprego) dos sonhos
mcassiano
0
51
Databinding e padrão MVVM
mcassiano
1
27
Desenvolvimento móvel: práticas de sucesso
mcassiano
0
31
Other Decks in Programming
See All in Programming
Windows on Ryzen and I
seosoft
0
280
Go Conference mini in Sendai 2026 : Goに新機能を提案し実装されるまでのフロー徹底解説
yamatoya
0
570
20260228_JAWS_Beginner_Kansai
takuyay0ne
5
510
最初からAWS CDKで技術検証してもいいんじゃない?
akihisaikeda
4
140
どんと来い、データベース信頼性エンジニアリング / Introduction to DBRE
nnaka2992
1
280
エンジニアの「手元の自動化」を加速するn8n 2026.02.27
symy2co
0
150
How to stabilize UI tests using XCTest
akkeylab
0
120
encoding/json/v2のUnmarshalはこう変わった:内部実装で見る設計改善
kurakura0916
0
410
SourceGeneratorのマーカー属性問題について
htkym
0
190
AWS Infrastructure as Code の新機能 2025 総まとめ 〜SA 4人による怒涛のデモ祭り〜
konokenj
10
3.3k
Kubernetesでセルフホストが簡単なNewSQLを求めて / Seeking a NewSQL Database That's Simple to Self-Host on Kubernetes
nnaka2992
0
110
maplibre-gl-layers - 地図に移動体たくさん表示したい
kekyo
PRO
0
260
Featured
See All Featured
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
130
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
64
53k
The Cost Of JavaScript in 2023
addyosmani
55
9.8k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
410
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
350
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
390
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
Code Reviewing Like a Champion
maltzj
528
40k
How to Ace a Technical Interview
jacobian
281
24k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
240
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
170
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
480
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?