Skip to content

Instantly share code, notes, and snippets.

@xeno-by
Created June 28, 2012 16:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xeno-by/3012199 to your computer and use it in GitHub Desktop.
Save xeno-by/3012199 to your computer and use it in GitHub Desktop.
import scala.reflect.makro.Context
object Macros {
def trace[A](expr: A) = macro traceImpl[A]
def traceImpl[A: c.TypeTag](c: Context)(expr: c.Expr[A]): c.Expr[A] = {
import c.universe._
// stand-in for the real type of the traced sub expression.
// This lets us conveniently splice this type into the
// reify call. The correct type is passed in implicitly
// as the TypeTag[T]
def impl[T] = {
object tracingTransformer extends Transformer {
override def transform(tree: Tree): Tree = {
tree match {
case a @ Apply(qual, args) =>
val sub = Apply(transform(qual), args.map(a => transform(a)))
implicit val TTag = c.TypeTag[T](sub.tpe)
val subExpr = c.Expr[T](sub)
val subExprCode = c.Expr[String](Literal(Constant(show(a))))
c.reify {
val temp: T = subExpr.splice
println("" + subExprCode.splice + " = " + temp)
temp
}.tree
case a @ Select(qual, name) if name.isTermName =>
val sub = Select(transform(qual), name)
implicit val TTag = c.TypeTag[T](sub.tpe)
a.tpe match {
case MethodType(_, _) | PolyType(_, _) =>
// qual.meth(...)
// \-------/
// don't trace this part.
sub
case _ =>
val subExpr = c.Expr[T](sub)
val subExprCode = c.Expr[Any](Literal(Constant(show(a))))
c.reify {
val temp: T = subExpr.splice
println("" + subExprCode.splice + " = " + temp)
temp
}.tree
}
case _ => super.transform(tree)
}
}
}
val t = tracingTransformer.transform(expr.tree)
c.Expr[A](c.resetAllAttrs(t))
}
impl
}
}
@dcsobral
Copy link

String Interpolation on lines 24, 41?

@xeno-by
Copy link
Author

xeno-by commented Jun 28, 2012

I agree, that'd look better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment