Advertisement
Guest User

Untitled

a guest
Aug 5th, 2014
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.81 KB | None | 0 0
  1. package macros
  2.  
  3. import scala.language.experimental.macros
  4. import scala.reflect.macros.whitebox.Context
  5.  
  6. trait TestMacro[T] {
  7.   def check(row: List[Any]): Unit
  8.   //def map(row: List[Any]): T
  9.   //def unapply(obj: T): List[Any]
  10. }
  11.  
  12. object TestMacro {
  13.  
  14.   implicit def method[T]: TestMacro[T] = macro methodImpl[T]
  15.  
  16.   def methodImpl[T: c.WeakTypeTag](c: Context): c.Expr[TestMacro[T]] = {
  17.     import c.universe._
  18.  
  19.     val tpe = weakTypeOf[T]
  20.     val decls = tpe.decls
  21.     val ctor = decls.collectFirst { case m: MethodSymbol if m.isPrimaryConstructor => m}.get
  22.     val params = ctor.paramLists.head
  23.     val companion = tpe.typeSymbol.companion
  24.  
  25.  
  26.     val typs = params.map(p => p.typeSignature)
  27.     val vals = (1 to typs.length).map(x => TermName(s"v$x"))
  28.     val patt = vals.zip(typs).map { case (v, t) => pq"$v: $t"}
  29.  
  30.  
  31.     val copy = decls.collectFirst {case m: MethodSymbol if m.fullName.contains("copy") => m}.get
  32.  
  33.     val unapplyVals = params.map {
  34.       case p =>
  35.         val valName = p.name.toTermName
  36.         q"obj.$valName"
  37.     }
  38.  
  39.     val check = typs.zipWithIndex.map {
  40.       case (t, i) =>
  41.         val typ = q"row($i).getClass.toString"
  42.         q"""
  43.            if(!row($i).isInstanceOf[$t])
  44.              throw new Exception("Error mapping " + row + ", type: " + $typ +
  45.              ${s", row($i) should be " + t.toString}
  46.              )"""
  47.     }
  48.  
  49.     c.Expr[TestMacro[T]] {
  50.       q"""
  51.        new TestMacro[$tpe] {
  52.  
  53.          def check(row: List[Any]): Unit = {
  54.            ..$check
  55.          }
  56.  
  57.          def map(row: List[Any]) = {
  58.            row match {
  59.              case List(..$patt) => $copy(..$vals)
  60.              case _ => throw new Exception("Can not map " + row)
  61.            }
  62.          }
  63.  
  64.          def unapply(obj: $tpe) = $unapplyVals
  65.        }
  66.      """
  67.     }
  68.   }
  69. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement