user3248346
user3248346

Reputation:

Get a List of Type of All Fields and Their Methods in A Case Class

I have a simple case class defined as follows:

case class Foo(f1 : String, f2:String)

I would like to use reflection to query a the Foo type for all it's declared fields, get the type of those fields, and then get the methods associated to those types. So in this example, it would get the fields f1 and f2 and then for those fields it will determine their type, in this case String and then get all the methods associated to the String type.

I tried the following:

scala> import reflect.runtime.{universe => ru}
import reflect.runtime.{universe=>ru}

scala> case class Foo(f1 : String, f2:String)
defined class Foo

scala> ru.typeOf[Foo].declarations
warning: there was one deprecation warning; re-run with -deprecation for details
res30: reflect.runtime.universe.MemberScope = SynchronizedOps(value f1, value f1, value f2, value f2, constructor Foo, method copy, method copy$default$1, method copy$default$2, method productPrefix, method productArity, method productElement, method productIterator, method canEqual, method hashCode, method toString, method equals)

First question is why f1 and f2 appear twice in this list?

I couldn't get at the types of f1 and f2 here so I tried

scala> ru.typeOf[Foo].getClass.getFields
res31: Array[java.lang.reflect.Field] = Array(public final scala.reflect.api.Universe scala.reflect.api.Types$TypeApi.$outer)

But this doesn't look like it's retrieved the fields f1 and f2.

How can I achieve what I need with scala reflect?

Upvotes: 0

Views: 97

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170805

First question is why f1 and f2 appear twice in this list?

Both field and its getter method.

ru.typeOf[Foo].getClass.getFields

typeOf[Foo] returns a Type. So typeOf[Foo].getClass will return a class which implements Type, not Foo. Just write classOf[Foo].getDeclaredFields. Or if you want to use scala-reflect types:

ru.typeOf[Foo].declarations.collect { 
  case t: TermSymbol if t.isCaseAccessor => t 
}

Upvotes: 1

Related Questions