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

22 - Detekt 1.22.0

22 - Detekt 1.22.0

Do you know Detekt? We are a static analyzer for Kotlin.
Our mission: spot bugs, antipatterns, and potential errors in your Kotlin code.

Detekt is helping millions of Kotlin developers around the globe to spot bugs before they reach production. What took us here is a vibrant community of users & contributors that are helping us build this ecosystem of tools.

In this talk, I will walk you through 22 goodies, tips and rules we released in 2022 for maintaining an elegant and beautiful Kotlin codebase.

Nicola Corti

January 01, 2023
Tweet

More Decks by Nicola Corti

Other Decks in Technology

Transcript

  1. 2 2

  2. Nicola Corti Kotlin GDE Detekt Maintainer twitter.com/cortinico [email protected] 
 


    github.com/cortinico 
 
 ncorti.com The Developers’ Bakery Podcast 
 thebakery.dev
  3. 22

  4. UnnecessaryNotNullCheck 1 fun main() { val santa = "🎅" println(requireNotNull(santa))

    } Remove unnecessary not - null checks on non - null types.
  5. CanBeNonNullable 2 var song: String? = "All I want for

    Christmas” fun sing() { song = "is you!" } Variable can be changed to non - nullable, as it is never set to null.
  6. CanBeNonNullable 2 var song: String = "All I want for

    Christmas” fun sing() { song = "is you!" }
  7. NullCheckOnMutableProperty 3 var snow: String? = null if (snow !=

    null) { println("Let it $snow") } Checking nullability on a mutable property is not useful because the property may be set to null afterwards.
  8. AlsoCouldBeApply 4 Rudolph().also { it.nose = "Red" it.glows() } When

    an `also` block contains only `it` - started expressions, simplify it
  9. ElseCaseInsteadOfExhaustiveWhen 5 enum class Cake { PANDORO, PANETTONE, STOLLEN }

    when(cake) { Cake.PANDORO -> {} Cake.PANETTONE -> {} else -> {} } A `when` expression that has an exhaustive set of cases should not contain an `else` case.
  10. ElseCaseInsteadOfExhaustiveWhen 5 enum class Cake { PANDORO, PANETTONE, STOLLEN }

    when(cake) { Cake.PANDORO -> {} Cake.PANETTONE -> {} Cake.STOLLEN -> {} }
  11. NullableBooleanCheck 6 var snows: Boolean? = checkWeather() if (snows ?:

    true) { // it snows } Nullable boolean check should use ` = = ` rather than ` ? : `
  12. CouldBeSequence 7 listOf(1, 2, 3, 4) .map { it *

    2 } .filter { it < 4 } .map { it * it } Several chained collection operations that should be a sequence.
  13. CouldBeSequence 7 listOf(1, 2, 3, 4) .asSequence() .map { it*2

    } .filter { it < 4 } .map { it*it } .toList()
  14. NestedScopeFunctions 8 class Santa(var name: String = "") class Deer(var

    color: String = "") Santa().apply { Deer().apply { name = "🎅" color = "🔴" } } Over - using scope functions makes code confusing, hard to read and bug prone
  15. ForbiddenSuppress 9 @Suppress("UNCHECKED_CAST") class Santa(var name: String = "") Cannot

    @Suppress UNCHECKED_CAST due to the current conf i guration
  16. 11 val answer = 42 This expression contains a magic

    number. Consider def i ning it to a well named
  17. 12 @Composable fun XmasView(text: String, onClick: () -> Unit) {

    // Render Xmas time! } Function names should follow the naming convention set in the conf i guration.
  18. libraries 17 libraries: active: true ForbiddenPublicDataClass: active: true ignorePackages: -

    '*.internal' - '*.internal.*' LibraryCodeMustSpecifyReturnType: active: true LibraryEntitiesShouldNotBePublic: active: true
  19. libraries 17 libraries: active: true ForbiddenPublicDataClass: active: true ignorePackages: -

    '*.internal' - '*.internal.*' LibraryCodeMustSpecifyReturnType: active: true LibraryEntitiesShouldNotBePublic: active: true