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

I am trying to match Array.apply, List.apply, Seq.apply, Set.apply and other Traverable apply method.

How should I implement isTraverable(coll)

jilen
  • 5,633
  • 3
  • 35
  • 84

1 Answers1

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"()"
  }
}

test

isTraverable.apply(
  List(
    List(
      List(1, 2, 3)
    )
  ))
余杰水
  • 1,404
  • 1
  • 11
  • 14