Skip to content

Instantly share code, notes, and snippets.

@xeno-by
Created December 26, 2014 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xeno-by/7fbd422c6789299140a7 to your computer and use it in GitHub Desktop.
Save xeno-by/7fbd422c6789299140a7 to your computer and use it in GitHub Desktop.
import scala.reflect.macros.whitebox._
import scala.language.experimental.macros
object Macros {
def impl(c: Context)(fn: c.Tree) = {
import c.universe._
val Typed(Block(List(ClassDef(_, _, _, Template(_, _, stats))), _), _) = fn
val List(_, DefDef(_, TermName("applyOrElse"), _, _, _, Match(_, clauses :+ _)), _) = stats
val pfs = clauses.map(clause => {
object betterUntypecheck extends Transformer {
override def transform(tree: Tree): Tree = tree match {
case UnApply(Apply(Select(qual, TermName("unapply")), List(Ident(TermName("<unapply-selector>")))), args) =>
Apply(transform(qual), transformTrees(args))
case _ => super.transform(tree)
}
def apply(tree: Tree): Tree = c.untypecheck(transform(tree))
}
val clause1 = betterUntypecheck(clause)
q"_root_.scala.PartialFunction[${clause.pat.tpe}, ${clause.body.tpe}]({ case $clause1 })"
})
q"List(..$pfs)"
}
def split(fn: PartialFunction[Int, Int]): Any = macro impl
}
object Test extends App {
object Foo { def unapply(x: Int) = Some(x) }
Macros.split{ case Foo(Foo(x)) => x; case x => x }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment