import scalafix.v1.{Patch, SemanticDocument, SemanticRule} import scala.meta._ import scalafix.v1._ class ReplaceScalazState extends SemanticRule("ReplaceScalazState") { override def fix(implicit doc: SemanticDocument): Patch = { doc.tree.collect { case t: Term.Apply if t.fun.symbol.displayName == "apply" && t.symbol.owner.value == "scalaz/IndexedStateT#" && t.args.size == 1 => val Term.Select(_, method) = t.fun Patch.replaceTree(method, "eval") case t: Defn.Val if t.pats.size == 1 && t.rhs.symbol.owner.value == "scalaz/IndexedStateT#" => t.pats match { case List(x @ Pat.Tuple(List(Pat.Wildcard(), p))) => Patch.replaceTree(x, p.toString) case _ => Patch.empty } }.asPatch } }
import scala.meta._ import scalafix.v1._ class ScalazEitherInfix extends SemanticRule("ScalazEitherInfix") { override def fix(implicit doc: SemanticDocument): Patch = { doc.tree.collect { case x: Type.Apply if """scalaz/`\/`#""" == x.tpe.symbol.value && x.args.size == 2 => Patch.replaceTree(x, s"""${x.args(0)} \\/ ${x.args(1)}""") }.asPatch } }
import scalafix.v1._ import scala.meta.Pat.{ Extract, Wildcard } import scala.meta.Term.Select import scala.meta._ class NonFatalLog extends SemanticRule("NonFatalLog") { override def fix(implicit doc: SemanticDocument): Patch = { doc.tree.collect { case c @ Case(Extract(x, List(Wildcard())), None, _) => // ↑ try catchのcase部分かつWildcardで潰してるやつ取り出し val patch1 = x match { case Select(_, Term.Name("NonFatal")) => // 歴史的都合で `case scala.util.control.NonFatal(_)` となってる部分あったからついでに書き換え Option(Patch.addGlobalImport(importer"scala.util.control.NonFatal")) case Term.Name("NonFatal") => Option(Patch.empty) case _ => None } patch1.map { p => List( p, Patch.addGlobalImport(importer"独自のLoggerのimport追加"), Patch.replaceTree( c.pat, s"NonFatal(e)" // 変数bindするように変更 ), Patch.replaceTree( c.body, s"""変数 `e` と、独自のLogger使ってログ出す処理。 ${c.body} はそのまま後ろに残す """ ) ).asPatch }.asPatch }.asPatch } }