Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import scala.reflect.runtime.universe.{NoSymbol, TermName}
- import scala.reflect.{classTag, ClassTag}
- object ReflectionUtils {
- def defaultValues[T: ClassTag]: Map[String, Any] = {
- import scala.reflect.runtime.currentMirror
- val classSymbol = currentMirror.classSymbol(classTag[T].runtimeClass)
- val moduleMirror = currentMirror.reflectModule(classSymbol.companion.asModule)
- val instanceMirror = currentMirror.reflect(moduleMirror.instance)
- val instanceTypeSignature = instanceMirror.symbol.typeSignature
- val applyMirror = instanceTypeSignature.member(TermName("apply")).asMethod
- applyMirror.paramLists.flatten.zipWithIndex
- .map {
- case (arg, index) =>
- arg.name.toString -> instanceTypeSignature.member(TermName(s"apply$$default$$${index + 1}"))
- }
- .filterNot(_._2 == NoSymbol)
- .map { case (name, value) => name -> instanceMirror.reflectMethod(value.asMethod)() }
- .toMap
- }
- def instantiate[T: ClassTag](values: Map[String, Any]): T = {
- import scala.reflect.runtime.currentMirror
- val classSymbol = currentMirror.classSymbol(classTag[T].runtimeClass)
- val moduleMirror = currentMirror.reflectModule(classSymbol.companion.asModule)
- val instanceMirror = currentMirror.reflect(moduleMirror.instance)
- val instanceTypeSignature = instanceMirror.symbol.typeSignature
- val applyMirror = instanceTypeSignature.member(TermName("apply")).asMethod
- val args = applyMirror.paramLists.flatten.zipWithIndex.map {
- case (arg, index) =>
- val name = arg.name.toString
- if (values.contains(name))
- values(name)
- else
- instanceTypeSignature.member(TermName(s"apply$$default$$${index + 1}")) match {
- case NoSymbol =>
- throw new Exception(s"Missing value for argument $name")
- case value: Any =>
- instanceMirror.reflectMethod(value.asMethod)()
- }
- }
- instanceMirror.reflectMethod(applyMirror)(args: _*).asInstanceOf[T]
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement