Skip to content

Instantly share code, notes, and snippets.

@BlackPrincess
Last active May 20, 2016 10:13
Show Gist options
  • Save BlackPrincess/a255eb4d472b0b494c6e603669bf18f3 to your computer and use it in GitHub Desktop.
Save BlackPrincess/a255eb4d472b0b494c6e603669bf18f3 to your computer and use it in GitHub Desktop.
memo
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
import skinny.micro.{SkinnyMicroParams, MultiParams}
object bindParams {
def applyParam_impl[A: c.WeakTypeTag](c: Context)(params: c.Expr[SkinnyMicroParams]) = {
import c.universe._
val A = weakTypeTag[A].tpe
val constructor = A.decls.collectFirst { case m: MethodSymbol if m.isPrimaryConstructor => m}.getOrElse {
c.abort(c.enclosingPosition, s"Could not find the primary constructor for $A. type $A must be a class or case class, not trait or type parameter")
}
val constParams = constructor.paramLists.head.map { field =>
val typOpt = field.typeSignature
val typ = typOpt.typeArgs.headOption.getOrElse {
c.abort(c.enclosingPosition, s"Field type must be Option[$typOpt], but $typOpt found.")
}
val name = field.name.decodedName.toString
q"${field.name.toTermName} = $params.getAs[$typ]($name)"
}
c.Expr[A](q"new ${weakTypeTag[A].tpe}(..$constParams)")
}
def apply[A](params: SkinnyMicroParams): A = macro applyParam_impl[A]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment