This repo contains the following scalafix rules:
Combine and run all following rules when traveling the scalameta trees represent scala files once
rules = [
ProcedureSyntax # built-in scalafix rule
fix.scala213.ConstructorProcedureSyntax
fix.scala213.ParensAroundLambda
fix.scala213.NullaryOverride
fix.explicittypes.ExplicitImplicitTypes
fix.scala213.MultiArgInfix
fix.scala213.Any2StringAdd
fix.scala213.ExplicitNonNullaryApply
fix.scala213.ExplicitNullaryEtaExpansion
]This rule is successfully used to migrate akka project to scala 2.13.3/ scala 3 (dotty)
Remove constructor procedure syntax: def this(..) {..} => def this(..) = {..}
This rule complement to the built-in ProcedureSyntax rule.
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 } // keepConsistent nullary overriding
trait A {
def i: Int
def u(): Unit
}
trait B extends A {
def i() = 1 // fix by remove `()`: def i = 1
def u = println("hi") // fix by add `()`: def u() = println("hi")
}Explicitly add type to implicit def/val/vars (required by dotty)
trait Foo {
// rewrite implicit members of class/trait
// 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
def f() = {
class C {
// Also rewrite implicit local `def/val/var`s that its parent is a trait/class (required by dotty)
// rewrite to `implicit val i: Int = 1`
implicit val i = 1
}
// local implicits like this don't need to be rewritten
implicit val s = ""
???
}
}Optional. Using symbolReplacements with this config in .scalafix.conf:
ExplicitImplicitTypes.symbolReplacements {
"scala/concurrent/ExecutionContextExecutor#" = "scala/concurrent/ExecutionContext#"
}Then:
import scala.concurrent.ExecutionContextExecutor
trait T {
def someEc(): ExecutionContextExecutor
}
trait A {
def t: T
// rewrite to `implicit def ec: ExecutionContext = t.someEc()`
implicit def ec = t.someEc()
}trait PipeToSupport {
def to(recipient: Int, sender: Int): Unit
}
def p: PipeToSupport = ???
// rewrite to `p.to(1, 2)
p to (1, 2)Remove redundant final modifier for objects:
final object AbcNil + "foo" // => String.valueOf(Nil) + "foo"
type A
def x: A = ???
x + "foo" // => String.valueOf(x) + "foo"
1 + "foo" // => "" + 1 + "foo"// Given:
def meth() = ???
def meth2()(implicit s: String) = ???
object meth3 {
def apply[A]()(implicit a: A) = ???
}
def prop(implicit s: String) = ???
// Then:
meth // rewrite to `meth()`
meth2 // rewrite to `meth2()`
meth3[Int] // rewrite to: meth3[Int]()
prop // keepdef prop = ""
def meth() = ""
def void(x: Any) = ""
def def_prop = prop _ // rewrite to: def def_prop = () => prop
def def_meth = meth _ // leave
def def_idty = void _ // leave
def lzy(f: => Int) = {
val k = f _ // rewrite to: val k = () => f
???
}- fix.scala213.Core
- fix.scala213.NullaryHashHash
- fix.scala213.ScalaSeq
- fix.scala213.Varargs
See also this commit message
- Optional. Add to
.jvmopts
-Xss8m
-Xms1G
-Xmx8G
- Add the
sbt-scalafixsbt plugin, with the SemanticDB compiler plugin enabled (official docs):
// project/plugins.sbt
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.31")// build.sbt
inThisBuild(List(
semanticdbEnabled := true,
semanticdbOptions += "-P:semanticdb:synthetics:on", // make sure to add this
semanticdbVersion := scalafixSemanticdb.revision,
scalafixScalaBinaryVersion := CrossVersion.binaryScalaVersion(scalaVersion.value),
))- Run
fix.scala213.DottyMigraterule (official docs), in sbt: Replace<version>with an actual value, eg0.1.6-sd. See releases
> scalafixAll dependency:fix.scala213.DottyMigrate@com.sandinh:scala-rewrites:<version>You can also add the following to your build.sbt:
ThisBuild / scalafixDependencies += "com.sandinh" %% "scala-rewrites" % "<version>"and then:
> scalafixAll fix.scala213.DottyMigrate- Run
fix.scala213.NullaryOverriderule
(bash)
echo 'rules = [ fix.scala213.NullaryOverride ]' > .NullaryOverride.conf
echo 'NullaryOverride.mode = Rewrite' >> .NullaryOverride.conf(sbt)
> set scalafixConfig := Some(file(".NullaryOverride.conf"))
> scalafixAll- Optional. Run other rules
> scalafixAll fix.scala213.FinalObject
> // similar for other rulessbt ~tests/test
# edit rewrites/src/main/scala/...