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
88
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
120
unraveling custom drawing
mcassiano
0
83
The Basis of Android Threading: Loopers and Handlers
mcassiano
1
120
Hackeando sua próxima entrevista: dicas para conseguir seu próximo estágio ou emprego
mcassiano
1
92
text spans: what, why and how?
mcassiano
0
600
Navigation patterns on Android and something new
mcassiano
3
390
Como conseguir o estágio (ou emprego) dos sonhos
mcassiano
0
45
Databinding e padrão MVVM
mcassiano
1
23
Desenvolvimento móvel: práticas de sucesso
mcassiano
0
26
Other Decks in Programming
See All in Programming
Запуск 1С:УХ в крупном энтерпрайзе: мечта и реальность ПМа
lamodatech
0
960
Jaspr Dart Web Framework 박제창 @Devfest 2024
itsmedreamwalker
0
150
月刊 競技プログラミングをお仕事に役立てるには
terryu16
1
1.2k
Rubyでつくるパケットキャプチャツール
ydah
0
180
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
430
return文におけるstd::moveについて
onihusube
1
1.4k
2025.01.17_Sansan × DMM.swift
riofujimon
2
580
Azure AI Foundryのご紹介
qt_luigi
1
210
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
6
710
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
1.4k
情報漏洩させないための設計
kubotak
5
1.3k
DevinとCursorから学ぶAIエージェントメモリーの設計とMoatの考え方
itarutomy
0
160
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
244
12k
Side Projects
sachag
452
42k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
3
360
Raft: Consensus for Rubyists
vanstee
137
6.7k
RailsConf 2023
tenderlove
29
980
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
240
GitHub's CSS Performance
jonrohan
1030
460k
The Invisible Side of Design
smashingmag
299
50k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.7k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
52k
Gamification - CAS2011
davidbonilla
80
5.1k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
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?