如何告诉对象是宏中的Traversable(List,Seq ..)的伴随对象

时间:2016-03-16 10:55:24

标签: scala scala-macros

case q"$pack.$coll.apply[..$t](..$v)" if isTraverable(coll) => xxx

我正在尝试匹配Array.applyList.applySeq.applySet.apply和其他Traverable申请方法。

我应该如何实施isTraverable(coll)

1 个答案:

答案 0 :(得分:0)

object isTraverable {
  def apply[V](v: V): Any = macro impl[V]

  def impl[V: c.WeakTypeTag](c: whitebox.Context)(v: c.Expr[V]) = {
    import c.universe._

    def isTraverable(coll: Tree) = {
      coll.tpe.typeConstructor <:< typeOf[TraversableOnce[_]].typeConstructor
    }

    def pattern(tree: Tree): Unit = tree match {

      // NODE : coll.tye is not typeOf[List[_]] but rather typeOf[List.type]

      case q"$coll.apply[..$t](..$agrs)" if isTraverable(tree) =>
        println(s"${coll} <:< TraversableOnce")
        pattern(agrs.last)
      case other =>
        println(s"$other is not TraversableOnce")
    }

    //immutable.this.List <:< TraversableOnce
    //immutable.this.List <:< TraversableOnce
    //immutable.this.List <:< TraversableOnce
    //3 is not TraversableOnce
    pattern(v.tree)

    q"()"
  }
}

测试

isTraverable.apply(
  List(
    List(
      List(1, 2, 3)
    )
  ))