Scala Quasiquotes Destructuring a Type -


context:

i'm working on library working jmx in scala. 1 of objectives have strong typed interface managed beans. guess akin to spring framework jmx library.

objective: macro deserialise tabulardata case class:

// interface i'd generate implementation using macro trait jmxtabularassembler[t <: product] {   def assemble(data: tabulardata): t }  object jmxannotations {   case class attribute(name: string) extends staticannotation } case class example(   @attribute("name") name: string,   @attribute("age") age: int,   unmarked: string ) 

problem: there plenty of examples of composing tree's using q"" interpolators. can't figure out how use tq"" interpolator extract fields out of case class type context.

private def mkassembler[t <: product : c.weaktypetag](c: context): c.universe.tree = {   import c.universe._   val tt = weaktypeof[t] } 

question: how use quasiquote machinery destructure fields of case class i can loop on them , filter out fields annotation (my attribute annotation not available approach taking"). implementation of following returns fields annotations in declaration order after.

private def harvestfieldswithannotations[t<: product: c.weaktypetag](c: context):      list[(c.universe.name, string, c.universe.type,   list[c.universe.annotation])] = ??? 

bonus: objective attribute fields, generate trees each field extract field tabulardata , use these trees create jmxtabularassembler functor. if show me how example above bootstrap efforts :d.


what have tried: started solving problem using reflection. not seem right way it. snippets:

... val dec = tt.decls.sorted def getfields = dec.withfilter( t=> t.isterm && ! t.ismethod) def getcaseaccessors = dec.withfilter( t => t.ismethod && t.asmethod.iscaseaccessor)  dec.foreach { d=>   println(d.name, d.annotations) }  getfields.foreach { f =>   println(f.annotations) }  val types = getcaseaccessors.map { d =>   println(d.annotations)   (d.name, tt.member(d.name).asmethod.returntype) } ... 

the following method trick, not use quasi quotes. key access backing field of symbol representing field accessor of case class (the accessed call).

private def harvestfieldswithannotations[t <: product : c.weaktypetag](c: context) = {     import c.universe._     val tt = weaktypeof[t]      tt.decls.sorted.filter(t => t.ismethod && t.asmethod.iscaseaccessor).map { ca =>       val asmethod = tt.member(ca.name).asmethod       (ca.name, asmethod.returntype, asmethod.accessed.annotations)     }   } 

field annotations won't retained unless explicitly annotated scala.annotation.meta.field.

so attribute annotation should be:

@field case class attribute(name: string) extends staticannotation 

Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -