Skip to content

Instantly share code, notes, and snippets.

@netvl
Created February 4, 2015 17:09
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 netvl/d04632c3101b6632f0c9 to your computer and use it in GitHub Desktop.
Save netvl/d04632c3101b6632f0c9 to your computer and use it in GitHub Desktop.
package evaluator
import scala.language.experimental.macros
import scala.reflect.macros.Context
object Evaluator {
def preprocess[T]: T = ???
def evaluate[A] = macro evaluateImpl[A]
def evaluateImpl[A: c.WeakTypeTag](c: Context): c.Expr[A] = {
import c.universe._
val tpe = weakTypeOf[A]
val sym = tpe.typeSymbol.asClass
require(sym.isCaseClass)
val companionSym = sym.companionSymbol
val companionTpe = companionSym.typeSignature
val applyMethod = companionTpe.member(newTermName("apply")).asMethod
val argTypes = applyMethod.paramss.flatten.map(_.typeSignature)
val tpeTypeArgs = tpe match {
case TypeRef(_, _, args) => args
}
val arguments = argTypes.map { argTpe =>
q"evaluator.Evaluator.preprocess[$argTpe]"
}
c.Expr(q"$companionSym.apply[..$tpeTypeArgs](..$arguments)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment