Search code examples
scalatypesreflectionscala-reflect

Scala case classes and recursive reflection


Given 2 Scala case classes

case class Bar(x: Int)
case class Foo(b: Bar, z: Double)

I have a piece of code that prints the types of Foo fields using reflection:

import scala.reflect.runtime.universe._
def f[T: TypeTag] = typeOf[T].members.filter(!_.isMethod)

and I call it like f[Foo] and f[Bar]. Calling the former returns a List[Type] as [Bar, Double].

How can I call f on the first element of the list? Equivalently, how can I print types recursively when Foo has a custom class Bar? Equivalently how can I get from Bar as Type a Bar.type?

Many thanks


Solution

  • You don't actually need the type variable T in f. You can define it like this (as Dima suggested in the comments):

    def f(t: Type) =
      t.members.filter(!_.isMethod).map(_.typeSignature)
    

    To use this to recursively print a type:

    def printTypesRecursive(t: Type, prefix: String = ""): Unit = {
      println(prefix + t)
      f(t).foreach(printTypesRecursive(_, prefix + " "))
    }
    
    printTypesRecursive(typeOf[Foo])
    

    Output:

    Foo
     Double
     Bar
      Int