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

Move fast and fix things

Move fast and fix things

An introduction to Scalafix, presented at Scala World 2017

Gabriele Petronella

September 19, 2017
Tweet

More Decks by Gabriele Petronella

Other Decks in Programming

Transcript

  1. Move fast and BREAK FIX things

  2. ME, HI!

  3. STUFF I DO (BY DAY)

  4. STUFF I DO (BY NIGHT) https://astexplorer.net/ https://github.com/gabro/vscode-scalafmt https://github.com/scalacenter/scalafix

  5. AGENDA 1. Intro and context 2. ASTs and related workflows

    3. Scalameta 4. Scalafix 5. Live examples
  6. WHAT IS SCALAFIX Scalafix is a rewrite and linting tool

    for Scala — scalacenter.github.io/scalafix
  7. EXAMPLE 1 - NOPROCEDURESYNTAX // before def main(args: Seq[String]) {

    println("Hello world!") } // after def main(args: Seq[String]): Unit = { println("Hello world!") }
  8. EXAMPLE 2 - NOAUTOTUPLING // before def someMethod(t: (Int, String))

    = ??? someMethod(1, "something") // after def someMethod(t: (Int, String)) = ??? someMethod((1, "something"))
  9. EXAMPLE 3 - REMOVECARTESIANBUILDER // before import cats.syntax.cartesian._ val o1:

    Option[Int] = Some(42) val o2: Option[String] = Some("hello") o1 |@| o2 map (_ + _) // after import cats.syntax.apply._ val o1: Option[Int] = Some(42) val o2: Option[String] = Some("hello") (o1, o2).mapN(_ + _)
  10. EXAMPLE 4 - NOINFER val myList = List(Some(42), Right("foo")) //

    ^ // |__ ⚠ Product with Serializable
  11. LET'S TALK ABOUT MAINTAINERS

  12. PURE EVIL BREAK CODE WITHOUT DOCUMENTING WHAT BROKE

  13. MILD EVIL BREAK CODE DOCUMENTING WHAT BROKE (OR LINKING TO

    A SUPER-LONG ISSUE)
  14. GOOD EFFORT BREAK CODE AND DOCUMENT HOW TO FIX IT

  15. YOU ROCK! BREAK CODE AFTER A DEPRECATION CYCLE AND EXPLAIN

    HOW TO FIX IT
  16. SUPERHERO BREAK CODE AFTER A DEPRECATION CYCLE AND PROVIDE AN

    AUTOMATIC REWRITE
  17. SCI-FI?

  18. MEANWHILE IN SWIFT

  19. MEANWHILE IN JAVASCRIPT

  20. MEANWHILE IN JAVASCRIPT 3 paragraphs later

  21. The JS tooling landscape is living in the future —

    Ólafur Páll Geirsson, author of Scalafix
  22. IT'S TIME WE JUMP INTO THE FUTURE

  23. HOW? LET'S TAKE A STEP BACK

  24. A QUICK PRIMER TO THE AST

  25. LET'S START FROM THE ANSWER val answer = 42

  26. TOKENS val answer = 42 // | | | |

    | | | | // \_'val'_/ \_Name_/ \_'='_/ \_Literal_/
  27. GRAMMAR val answer = 42 // | | | |

    | | | | // | | \__Term.Name__/ | \_Lit.Int_/ | // | | | | // | \_____Pat.Var.Term__/ | // | | // \_____________________Defn.Val____________________/
  28. SO... AST?

  29. ABSTRACT SYNTAX TREE

  30. WHY ABSTRACT?

  31. val answer = 42; val answer = 42 val answer

    = 42 val answer = 42
  32. None
  33. ASTS... WHY SHOULD I CARE?

  34. AST WORKFLOW 1: SCALAC

  35. AST WORKFLOW 2: MACROS

  36. AST WORKFLOW 3: SCALAFMT

  37. AST WORKFLOW 4: SCALAFIX

  38. AST WORKFLOW 4: SCALAFIX Woops, copy-paste?

  39. WHAT SCALAFIX COULD DO: // before def someMethod(string: String) {

    // I like trees println(string.trim.split("/").lastOption) } // after def someMethod(string: String): Unit = println( string .trim .split("/") .lastOption )
  40. None
  41. WHAT SCALAFIX DOES INSTEAD: // before def someMethod(string: String) {

    // I like trees println(string.trim.split("/").lastOption) } // after def someMethod(string: String): Unit = { // I like trees println(string.trim.split("/").lastOption) }
  42. "AST" WORKFLOW 4: SCALAFIX

  43. OK, LET'S DO THIS!

  44. None
  45. Introducing SCALAMETA

  46. Scalameta is a modern metaprogramming library for Scala — scalameta.org

  47. METAPROGRAMMING?

  48. METAPROGRAMMING DEVTOOLS! ▸ code formatting ▸ code fixing ▸ code

    browsing ▸ and many more applications!
  49. SCALAMETA VADEMECUM ▸ Trees ▸ Tokens ▸ Parser ▸ Tree

    manipulation primitives ▸ Semantic API ▸ (pretty-printer)
  50. TOKENS The "atoms"

  51. TREES The fundamental data structure

  52. PARSER ! ➡ # several dialects

  53. TREE MANIPULATION PRIMITIVES ▸ transform ▸ traverse ▸ collect

  54. SEMANTIC API: DATABASE ▸ Names ▸ Symbols ▸ Messages ▸

    Synthetics
  55. SEMANTIC API: NAMES package scalaworld.semantic Names: [8..18): scalaworld => _root_.scalaworld.

    [19..27): semantic => _root_.scalaworld.semantic.
  56. SEMANTIC API: SYMBOLS List(1, 2, 3).head Symbols: _root_.scala.collection.immutable.List. => final

    object List _root_.scala.collection.IterableLike#head()Ljava/lang/Object;. => def head: A
  57. SEMANTIC API: MESSAGES object A { 1 + 1 }

    Messages: [140..145): [warning] a pure expression does nothing in statement position; you may be omitting necessary parentheses
  58. SEMANTIC API: SYNTHETICS (SUGARS) List(1, 2, 3) Synthetics: [2..7): apply

    => _root_.scala.collection.immutable.List.apply (Lscala/collection/Seq;) [8..11): Int => _root_.scala.Int# List.apply[Int](1, 2, 3)
  59. RECAP List(1, 2, 3) // Symbol _root_.scala.collection.immutable.List. // Denotation final

    object List // Synthetic [2..7): apply => _root_.scala.collection.immutable.List.apply (Lscala/collection/Seq;)
  60. None
  61. SCALAFIX FINALLY!

  62. Rule Rewrite

  63. Rule A rule can be: ▸ checked ▸ fixed

  64. Patch

  65. Patch A Scalafix Patch is a patch in the diff

    sense of patch. It boils down to a list of -/+ to apply to the source code.
  66. LintMessage LintCategory

  67. LintMessage / LintCategory A LintMessage is a warning/error that gets

    displayed to the user. Each LintMessage belongs to LintCategory (e.g. "MissingExplicitType" )
  68. RuleCtx

  69. RuleCtx The toolbox for writing rules. It provides the API

    for producing patches.
  70. SemanticdbIndex

  71. SemanticdbIndex A index for looking up data in a scalameta's

    Semantic Database. It contains all the available semantic information.
  72. None
  73. LIVE

  74. WHAT'S NEXT?

  75. SHORT-TERM ▸ more linter rules ▸ rule "bundles" ▸ more

    robust expansion of inferred types / implicits
  76. MEDIUM TERM ▸ editor integrations ▸ stable API ▸ docs

  77. None
  78. Questions? @gabro27 @buildoHQ @ScalaItaly