I define following macro to transform case fields to map
import scala.language.experimental.macros
import scala.reflect.macros.Context
def asMap_impl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]) = {
import c.universe._
val mapApply = Select(reify(Map).tree, newTermName("apply"))
val pairs = weakTypeOf[T].declarations.collect {
case m: MethodSymbol if m.isCaseAccessor =>
val name = c.literal(m.name.decoded)
val value = c.Expr(Select(t.tree, m.name))
reify(name.splice -> value.splice).tree
}
c.Expr[Map[String, Any]](Apply(mapApply, pairs.toList))
}
And the method implementation
def asMap[T](t: T) = macro asMap_impl[T]
Then I define a case class to test it
case class User(name : String)
It works fine(with scala repl):
scala> asMap(User("foo")) res0:
scala.collection.immutable.Map[String,String] = Map(name -> foo)
But When I wrap this method with another generic method
def printlnMap[T](t: T) = println(asMap(t))
This method always print empty map:
scala> printlnMap(User("foo"))
Map()
The type information seems lost, how to get the printlnMap to print all fields ?