Advertisement
Guest User

Untitled

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