1

我正在写一个疣去除器插件。我想检测对某些可能返回的方法的调用null,例如System.getProperty. 但是,我尝试匹配它们的所有方法都失败了。这是我最近的尝试:

import org.brianmckenna.wartremover.{WartTraverser, WartUniverse}
import scala.language.{implicitConversions,reflectiveCalls}

object LegacyJavaAPIs extends WartTraverser {

  def apply(u: WartUniverse): u.Traverser = {
    import u.universe._

    @SuppressWarnings(Array("org.brianmckenna.wartremover.warts.AsInstanceOf",
      "com.example.wart.LegacyJavaAPIs"))
    val getProperty = reify(System.getProperty("x")).tree match {
      case Apply(a,b) => a.toString
    }

    new u.Traverser {
      override def traverse(tree: Tree): Unit = {
        if(tree.toString == getProperty)
          u.error(tree.pos,
            """|Do not use System.getProperty - it may return null.
               |Use sys.props instead.""".stripMargin)
        else
          super.traverse(tree)
      }
    }
  }
}

我尝试过的大多数方法都不会导致应该有错误的行出现错误 - 尽管当我尝试.symbol而不是 时.toString,顶级树开始到处匹配。我猜.symbolnull在这些情况下......

我还尝试使用showRaw并复制和粘贴相关的构造函数,但这不起作用,因为它不是有效的 Scala 代码 -java.lang在 的输出中显示为标识符showRaw,而不是包装在它实际包装的任何构造函数中.

4

1 回答 1

0

好吧,我终于设法找到了没有损坏的 scala 反射 API 的一部分:

object LegacyJavaAPIs extends WartTraverser {

  def apply(u: WartUniverse): u.Traverser = {
    import u.universe._

    @SuppressWarnings(Array("org.brianmckenna.wartremover.warts.AsInstanceOf"))
    val systemStatic = rootMirror.typeOf[System].companion

    val getProperty = systemStatic.decl(TermName("getProperty")).alternatives

    new u.Traverser {
      override def traverse(tree: Tree): Unit =
        if(getProperty.contains(tree.symbol))
          u.error(tree.pos,
            """|Do not use System.getProperty - it may return null.
               |Use sys.props.get instead.""".stripMargin)
        else
          super.traverse(tree)
    }
  }

我们需要调用companion(即使java.lang.System没有伴生对象,因为它是 Java),因为 scala-reflect 不识别静态方法的概念,并将它们视为伴生对象上的方法。我们还需要调用alternatives,因为getProperty它重载了。

如果感兴趣的类型是scala.Predef,则有必要稍微调整一下:

val predef = rootMirror.typeOf[scala.Predef.type]
于 2015-07-16T16:17:36.203 回答