General refactoring rules available in scalafix
日本語版の README.md は こちら
ThisBuild / scalafixDependencies += "net.pixiv" %% "scalafix-pixiv-rule" % "<VERSIONS>"
Remove unnecessary end-of-line semicolons. If a line is connected after the semicolon, it will be not deleted.
/* rule = UnnecessarySemicolon */
val x = 3; // rewrite to: `val x = 3`
val a = 1; val b = 2
Replace deprecated arrow (→, ⇒) characters with ->, =>.
/* rule = UnifiedArrow */
List(1 → "a", 2 → "b", 3 → "c").map { // rewrite to: List(1 -> "a", 2 -> "b", 3 -> "c").map {
case (_, s) ⇒ s // rewrite to: case (_, s) => s
}
Replaces access to the first element by index in Seq
with a call to head
.
/* rule = ZeroIndexToHead */
Seq(1, 2, 3)(0) // rewrite to: `Seq(1, 2, 3).head`
Replace emptiness checks for Option
and Seq
with isEmpty
, nonEmpty
, and isDefined
.
/* rule = CheckIsEmpty */
Some(1) == None // rewrite to: Some(1).isEmpty
Some(1).nonEmpty // if `CheckIsEmpty.alignIsDefined = true` then rewrite to Some(1).isDefined
Raise a warning for case class
definitions that inherit from Exception
.
This is because implementing case class
would compromise the benefits of exception hierarchy and uniqueness.
/* rule = NonCaseException */
case class NonCaseException(msg: String) extends RuntimeException(msg)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
case class として Exception を継承することは推奨されません: NonCaseException
Replace List()
and List.empty
without type variables specification with Nil
.
This is because Nil
is defined as List[Nothing]
.
Also, List[Any]()
with a type variable specification is replaced with List.empty[Any]
.
/* rule = EmptyListToNil */
val empty = List.empty // rewrite to: val empty = Nil
val list = List[String]() // rewrite to: val list = List.empty[String]
Split a pattern match that has only one case
.
It also replaces patterns where only Some.unapply
is used with foreach
calls.
⚠︎This rule may destroy indentation. Always use with a formatter!
/* rule = SingleConditionMatch */
Some(1) match {
case result => println(result)
}
/* rewrite to:
* println(Some(1))
*/
Due to technical issues, only the most deeply nested patterns will be replaced.
/* rule = SingleConditionMatch */
Some(1) match {
case result =>
result match {
case result => println(result)
}
}
/* rewrite to:
* Some(1) match {
* case result =>
* println(result)
* }
*/
Unify the notation for using Mockito in Scala.
While when/then syntax can be used to check the return type, it has some disadvantages, such as not being able to return void (Unit). This rule replaces test code written in when/then syntax with do/when syntax.
/* rule = MockitoThenToDo */
Mockito.when(a.hoge()).thenReturn("mock1").thenReturn("mock2")
when(a.fuga).thenReturn("mock")
/* rewrite to:
* Mockito.doReturn("mock1").doReturn("mock2").when(a).hoge()
* Mockito.doReturn("mock").when(a).fuga
*/
Unify the assertion of Exceptions for using Scalatest.
In the case of Exception assertion in article using_assertions, there are assertThrows
and intercept
that difference between assertThrows
and intercept
is intercept
returns Exceptions but assertThrows
does not.
Applying this rule changes assertThrows
to intercept
.
/* rule = ScalatestAssertThrowsToIntercept */
assertThrows[RuntimeException]{
a.hoge()
}
/* rewrite to:
* intercept[RuntimeException]{
* a.hoge()
* }
*/
Raise a warning if a message is not given of a class
that extends RuntimeException
.
This is to allow identification when errors are notified.
/* rule = NeedMessageExtendsRuntimeException */
class RedException extends RuntimeException {}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeException を継承したクラスを作る際にはメッセージを付与してください: RedException
*/
Generates a warning when a class that follows a certain naming convention is found in an inappropriate package.
For example, when using the Play Framework, a class named Controller is required to not be in the filters directory.
/*
rule = NamingConventionPackage
NamingConventionPackage.convention = [
{ package = "^filters$", class = "^.+Controller$" }
]
*/
package filters
// class HomeController は filters パッケージに実装すべきではありません
class HomeController {}
Rewriting rules for namespaces changed since Jakarta EE 9.
The javax.*
namespace is changed to jakarta.*
.
The complete list of packages to be changed is here.
/* rule = PackageJavaxToJakarta */
package fix.pixiv
import javax.inject.Inject // rewrite to: import jakarta.inject.Inject
class PackageJavaxToJakarta @Inject()() {
}