Writing Your Own Warts
A wart rule has to be an object that extends WartTraverser
. The
object only needs an apply
method which takes a WartUniverse
and
returns a WartUniverse#universe#Traverser
.
The WartUniverse
has error
and warning
methods, which both take
(WartUniverse#universe#Position, String)
. They are side-effecting
methods for adding errors and warnings.
Most traversers will want a super.traverse
call to be able to
recursively continue.
package mywarts
import org.wartremover.{ WartTraverser, WartUniverse }
object Unimplemented extends WartTraverser {
def apply(u: WartUniverse): u.Traverser = {
import u.universe._
import scala.reflect.NameTransformer
val notImplementedName: TermName = TermName(NameTransformer.encode("???"))
val notImplemented: Symbol = typeOf[Predef.type].member(notImplementedName)
require(notImplemented != NoSymbol)
new Traverser {
override def traverse(tree: Tree): Unit = {
tree match {
case rt: RefTree if rt.symbol == notImplemented =>
error(u)(tree.pos, "There was something left unimplemented")
case _ =>
}
super.traverse(tree)
}
}
}
}
Once you have your wart written you can add it to your config using Wart.custom
:
wartremoverWarnings += Wart.custom("mywarts.Unimplemented")
You’ll also need to add the package containing your wart to wartremover’s classpath. The usual way to do this relies on adding your package as a library dependency:
libraryDependencies += "myOrg" %% "myWartPackage" % "1.0.0"
wartremoverClasspaths ++= {
(Compile / dependencyClasspath).value.files
.find(_.name.contains("myWartPackage"))
.map(_.toURI.toString)
.toList
}
See also example repository