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 } // keep
Consistent 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/var
s (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 Abc
Nil + "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 // keep
def 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-scalafix
sbt 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.DottyMigrate
rule (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.NullaryOverride
rule
(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 rules
sbt ~tests/test
# edit rewrites/src/main/scala/...