Using scala reflection to access parameters in the cosntructor of a class and print their type

Hello everyone. I wrote the following method to obtain the parameters in the constructor of a class:

/** Get the parameters in the constructor of a given scala class.
    * Returns a list of tuples with the name as first and the type of the parameter as second.
  def getConstructorParams(target: Any): Seq[(String, String)] = {
    import scala.reflect.runtime.universe._
    import scala.reflect.api.{Mirror, TypeCreator, Universe}
    val c = target.getClass
    val mirror = runtimeMirror(c.getClassLoader) // obtain runtime mirror
    val sym = mirror.staticClass(c.getName) // obtain class symbol for `c`
    val tpe = sym.selfType // obtain type object for `c`
    // create a type tag which contains above type object
    val tt = TypeTag(
      new TypeCreator {
        def apply[U <: Universe with Singleton](m: Mirror[U]) =
          if (m eq mirror) tpe.asInstanceOf[U#Type]
            throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
    // Collect all the parameters in the primary constructor
    // 1. Get all the members of this type
    // 2. Filter the method symbol that is the primary constructor
    // 3. Get the list of params in this method
    val l = tt.tpe.members.collect {
      case m: MethodSymbol if m.isPrimaryConstructor => { a => (, }
    // Remove the first element (the constructor itself)

However, it “fails” on pretty print of the type when a parameter is of a class type:

it("should parameter of complex types of a class") {
      class A(private val a: Int) { val c = 10 }
      val a = new A(1)
      getConstructorParams(a) should be(Seq(("a", "Int")))

      class B(protected val aClass: A) { val c = 10 }
      val b = new B(a)
      getConstructorParams(b) should be(Seq(("aClass", "A")))

When applied to b it returns List(("aClass", "ParametersAnnotationSpec.this.$A$7")) instead of List(("aClass", "A")).

How can I solve this?

I managed to fix it with a workaround:

 val l = tt.tpe.members.collect {
      case m: MethodSymbol if m.isPrimaryConstructor => { a =>
          val t ="\\$")
          val typeName = if (t.length > 1) t(1) else t(0) // Remove the package name
          val instName =
          (instName, typeName)

I’m not sure if it is 100% correct though