Best way to reflect case class fields in scala 2.11?

I want to (static) reflect the class sample as follows:

case class Foo[T,U](stuff:T, more:U, age:Int) { val ignore:Boolean = false } 

I started like this:

 val symbol = currentMirror.classSymbol(clazz) // symbol is universe.ClassSymbol // I want to know about type placeholders T and U val typeParamArgs = symbol.typeParams.map( tp => tp.name.toString) if( symbol.isCaseClass ) { val tsig = symbol.typeSignature println(tsig) } 

Ok, at this point, if I type tsig, I see:

 [T, U]scala.AnyRef with scala.Product with scala.Serializable { val stuff: T private[this] val stuff: T val more: U private[this] val more: U val age: scala.Int private[this] val age: scala.Int def <init>(stuff: T,more: U,age: scala.Int): co.blocke.Foo[T,U] val ignore: scala.Boolean private[this] val ignore: scala.Boolean def copy[T, U](stuff: T,more: U,age: scala.Int): co.blocke.Foo[T,U] def copy$default$1[T, U]: T @scala.annotation.unchecked.uncheckedVariance def copy$default$2[T, U]: U @scala.annotation.unchecked.uncheckedVariance def copy$default$3[T, U]: scala.Int @scala.annotation.unchecked.uncheckedVariance override def productPrefix: java.lang.String def productArity: scala.Int def productElement(x$1: scala.Int): scala.Any override def productIterator: Iterator[scala.Any] def canEqual(x$1: scala.Any): scala.Boolean override def hashCode(): scala.Int override def toString(): java.lang.String override def equals(x$1: scala.Any): scala.Boolean } 

Look at this line in the middle with <init>? This is an expression that I want to understand. He got what I need.

How can I highlight tsig (universe.Type) to get information about <init>? (I don't need information about "ignore.")

+5
source share
1 answer

Instead of checking the .typeSignature class .typeSignature verify the signature of the constructor type with .primaryConstructor.typeSignature :

 val csig = symbol.primaryConstructor.typeSignature val params = csig.paramLists.head // paramLists returns a List of Lists 

This gives you a list of options for the main constructor, so you can ask for names, types, etc.:

 scala> params(1).name res47: reflect.runtime.universe.Symbol#NameType = more scala> params(2).typeSignature res48: reflect.runtime.universe.Type = scala.Int 
+3
source

Source: https://habr.com/ru/post/1213091/


All Articles