Scalafix rules

Build Statud

All rules are migrated to that project!

Old README

This project contains scalafix rules I create when migrating akka to dotty.

ConstructorProcedureSyntax

Remove constructor procedure syntax: def this(..) {..} => def this(..) = {..}

This rule complement to the built-in ProcedureSyntax rule.

Any2StringAdd

ParensAroundLambda

Fix: parentheses are required around the parameter of a lambda

Seq(1).map { i: Int => // rewrite to: Seq(1).map { (i: Int) =>
 i + 1
}
Seq(1).map { i => i + 1 } // keep

FinalObject

Remove redundant final modifier for objects:

final object Abc

NullaryOverride

Consistent nullary overriding

trait A {
  def i: Int
  def u(): Unit
}
trait B {
  def i() = 1 // fix by remove `()`: def i = 1
  def u = println("hi") // fix by add `()`: def u() = println("hi")
}

ExplicitNonNullaryApply

Compare to fix.scala213.ExplicitNonNullaryApply from scala-rewrites project:

  • Pros
    • When I try scala-rewrites' ExplicitNonNullaryApply for akka sources, it crashed!

    • This rule run faster than scala-rewrites' one.

    • Don't need to publishLocal to use. scala/scala-rewrites#32

      Just add "github:ohze/scalafix-rules/ExplicitNonNullaryApply" to .scalafix.conf

  • Cons
    • This rule also add () to methods that are defined in java and be overridden in scala, eg the calls in ExplicitNonNullaryApplyJavaPending test. Those ()s are not required by dotty.
  • Technical note: This rule don't need scala.meta.internal.pc.ScalafixGlobal to hook into scala-compiler.

ExplicitImplicitTypes

Before scalacenter/scalafix#1180 is fixed, to explicitly add type to implicit def/val/vars (required by dotty) you need:

rules = [
  ExplicitResultTypes
]
ExplicitResultTypes {
  memberVisibility = [] # only rewrite implicit members
}

=> Add type to implicit members of classes, traits

trait T {
  // rewrite to `implicit val s: Seq[String] = Nil`
  implicit val s = Seq.empty[String]
  // rewrite to `implicit def i: Int = 1`
  implicit def i = 1
}
  • And use this rule
rules = [
  "github:ohze/scalafix-rules/ExplicitImplicitTypes"
]
# Optinal
ExplicitImplicitTypes.symbolReplacements {
  "scala/concurrent/ExecutionContextExecutor#" = "scala/concurrent/ExecutionContext#"
}

=> Add type to implicit local def/val/vars that its parent is a trait/class

import scala.concurrent.ExecutionContextExecutor

trait T
trait A {
  def f() = {
    class C {
      // rewrite to `implicit val i: Int = 1`
      implicit val i = 1
    }
    ???
  }
  def someEc(): ExecutionContextExecutor
  def g() = new T {
    // rewrite to `implicit def ec: ExecutionContext = someEc()`
    implicit def ec = someEc()
  }
}

Usage

  • Eg, for ExplicitNonNullaryApply rule:
scalafix --rules=github:ohze/scalafix-rules/ExplicitNonNullaryApply

Dev guide

cd scalafix
sbt ~test
# edit scalafix/rules/src/main/scala/fix/*.scala

Licence

This software is licensed under the Apache 2 license: http://www.apache.org/licenses/LICENSE-2.0

Copyright 2020 Sân Đình (https://sandinh.com)