Unapply/patter matching with scala macros and quasiquotes for knownDirectSubclasses -


i'm trying create match statement using macros, matches subclasses of given type. have trouble extracting field values of case classes. example:

sealed abstract class foobar case class foo(x:int,f:foobar) extends foobar case class bar(s:string, f:foobar) extends foobar 

now want create code looks this, when foobar given:

 e1 match {    case foo(args) => args.tostring    case bar(args) => args.tostring  } 

thats got far:

  def eqimpl[a: c.weaktypetag](c: context)(e1: c.expr[a], e2: c.expr[a]): c.expr[boolean] = {     import c.universe._      val tpe = c.weaktypeof[a].typesymbol.asclass     tpe.typesignature // si-7046     val subclasses = tpe.knowndirectsubclasses      val cases =        subclasses.map{ clazz =>       cq"x: $clazz => x "      }     println(cases)     reify(true)   } 

this code match foo , bar, can not extract fields, need on right hand side.

so got working, here example:

def eqimpl[a: c.weaktypetag](c: context)(e1: c.expr[a], e2: c.expr[a]): c.expr[boolean] = {     import c.universe._     val tpe = c.weaktypeof[a].typesymbol.asclass     tpe.typesignature // si-7046 workaround       val subclasses = tpe.knowndirectsubclasses      val cases =        subclasses.map{ case clazz : classsymbol =>         require (clazz.iscaseclass)         val name = clazz.companionsymbol.name         val fields = clazz.typesignature.declarations.collect {         case m: methodsymbol if m.iscaseaccessor => m.name}         //pattern fields of left , right side side         val lfields = fields.map{ m => pq"""${m+"l":termname}"""}          val rfields = fields.map{ m => pq"""${m+"r":termname}"""} side         //right hand side of case statment          val eqfields =            fields.map{ m => q"""${m+"r":termname} == ${m+"l":termname}"""}.reduce[tree]{              case (acc,n) => q"$acc && $n"}          cq"($name(..$lfields),$name(..$rfields)) => $eqfields  "      }     val matchstmt = q"""tuple2[$tpe,$tpe]($e1,$e2) match {           case ..$cases           case _ => false }"""     c.expr[boolean](matchstmt)   } } 

this code creates match statement, matches tuple. if both sides of tuple instances of same case class, fields compared. true returned, if fields equal. know not particularly realistic example, hope helps. example question generate:

tuple2[foobar,foobar](e1,e2) match {      case (foo(xl,fl),foo(xr,fr) => xl == xr && fl == fr      case (bar(sl,fl),bar(sr,fr) => sl == sr && fl == fr      case _                      => false  } 

Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -

php - Accessing static methods using newly created $obj or using class Name -