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. AGENDA 1. Intro and context 2. ASTs and related workflows

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

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

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

    = ??? someMethod(1, "something") // after def someMethod(t: (Int, String)) = ??? someMethod((1, "something"))
  5. 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(_ + _)
  6. The JS tooling landscape is living in the future —

    Ólafur Páll Geirsson, author of Scalafix
  7. TOKENS val answer = 42 // | | | |

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

    | | | | // | | \__Term.Name__/ | \_Lit.Int_/ | // | | | | // | \_____Pat.Var.Term__/ | // | | // \_____________________Defn.Val____________________/
  9. 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 )
  10. 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) }
  11. SCALAMETA VADEMECUM ▸ Trees ▸ Tokens ▸ Parser ▸ Tree

    manipulation primitives ▸ Semantic API ▸ (pretty-printer)
  12. 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
  13. 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
  14. 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)
  15. 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;)
  16. 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.
  17. LintMessage / LintCategory A LintMessage is a warning/error that gets

    displayed to the user. Each LintMessage belongs to LintCategory (e.g. "MissingExplicitType" )
  18. SemanticdbIndex A index for looking up data in a scalameta's

    Semantic Database. It contains all the available semantic information.
  19. SHORT-TERM ▸ more linter rules ▸ rule "bundles" ▸ more

    robust expansion of inferred types / implicits