My application has a compile dependency to a library A. There is a specific function in this library which I know that causes performance problems. But it is not deprecated and if you don't have this prior information you would think that it is safe to use it. I'm looking for a way to somehow deprecate this function or prevent it from being called directly.
Would it be possible to achieve this via static analysis tools or builtin compiler flags?
I have checked scalafix but it was too complicated to setup for just this kind of linting. I ended up using wartremover and adding a custom wart.
Custom warts sit in a subproject as shown in this example.
lazy val myWarts = project.in(file("my-warts")).settings(
commonSettings,
libraryDependencies ++= Seq(
"org.wartremover" % "wartremover" % wartremover.Wart.PluginVersion cross CrossVersion.full
)
)
lazy val main = project.in(file("main")).settings(
commonSettings,
wartremoverWarnings += Wart.custom("mywarts.ExtractOrElse"),
wartremoverClasspaths ++= {
(fullClasspath in (myWarts, Compile)).value.map(_.data.toURI.toString)
}
)
I have created a custom wart by simply modifying builtin EitherProjectionPartial wart.
object ExtractOrElse extends WartTraverser {
def apply(u: WartUniverse): u.Traverser = {
import u.universe._
val extractableJsonAstNode = rootMirror.staticClass("org.json4s.ExtractableJsonAstNode")
new u.Traverser {
override def traverse(tree: Tree): Unit = {
tree match {
// Ignore trees marked by SuppressWarnings
case t if hasWartAnnotation(u)(t) =>
case Select(left, TermName("extractOrElse")) if left.tpe.baseType(extractableJsonAstNode) != NoType =>
error(u)(tree.pos, "extractOrElse is deprecated - use toOption.map or extract[Option[A]] instead")
super.traverse(tree)
case _ => super.traverse(tree)
}
}
}
}
}