Generic case class
case class GroupResult[T](
group: String,
reduction: Seq[T]
)
Macro method
def foo[T] = macro fooImpl[T]
def fooImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val tpe = weakTypeOf[T]
tpe.declarations.collect {
case m: MethodSymbol if m.isCaseAccessor => println(m.returnType)
}
c.literalUnit
}
When I invoke foo[GroupResult[Int]]
The output is
String
Seq[T]
T is not applied ? How can I get the applied Seq[Int]
?
You can use typeSignatureIn
to get the type signature of a method given GroupResult[Int]
:
import scala.language.experimental.macros
import scala.reflect.macros.Context
case class GroupResult[T](group: String, reduction: Seq[T])
def foo[T] = macro fooImpl[T]
def fooImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val tpe = weakTypeOf[T]
tpe.declarations.collect {
case m: MethodSymbol if m.isCaseAccessor => println(m.typeSignatureIn(tpe))
}
c.literalUnit
}
And then:
scala> foo[GroupResult[Int]]
=> String
=> Seq[Int]
So we're closer, but now we're getting the "types" of the accessors, not their return types. If we want the return types we can use the NullaryMethodType
extractor:
def foo[T] = macro fooImpl[T]
def fooImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val tpe = weakTypeOf[T]
tpe.declarations.collect {
case m: MethodSymbol if m.isCaseAccessor => m.typeSignatureIn(tpe) match {
case NullaryMethodType(returnType) => println(returnType)
}
}
c.literalUnit
}
And then:
scala> foo[GroupResult[Int]]
String
Seq[Int]
And we're done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With