skylerl
skylerl

Reputation: 4170

Convert Scala Reflection MethodMirror to Scala Function

I am trying to create a Seq of methods that will operate on a Spark DataFrame. Currently I am explicitly creating this Seq at runtime:

val allFuncs: Seq[DataFrame => DataFrame] = Seq(func1, func2, func3)
def func1(df: DataFrame): DataFrame = {}
def func2(df: DataFrame): DataFrame = {}
def func3(df: DataFrame): DataFrame = {}

I added functionality that allows developers to add an annotation and I'm creating a Seq of MethodMirrors from it like so, but I'd like getMyFuncs to return a Seq[(DataFrame => DataFrame)]:

  def getMyFuncs(): Seq[(DataFrame => DataFrame)] = {
    // Gets anything with the @MyFunc annotation
    val listOfAnnotations = typeOf[T].members.flatMap(f => f.annotations.find(_.tree.tpe =:= typeOf[MyFunc]).map((f, _))).toList
    val rm = runtimeMirror(this.getClass.getClassLoader)
    val instanceMirror = rm.reflect(this)
    listOfAnnotations.map(annotation =>   instanceMirror.reflectMethod(annotation._1.asMethod)).toSeq
}

@MyFunc
def func1(df: DataFrame): DataFrame = {}
@MyFunc
def func2(df: DataFrame): DataFrame = {}
@MyFunc
def func3(df: DataFrame): DataFrame = {}

However, the Seq returned by getMyFuncs is a Seq[reflect.runtime.universe.MethodMirror], not Seq[(DataFrame => DataFrame)]. Which is expected, but not the output I need. Is there any way to convert the MethodMirrors into a Scala function?

Upvotes: 0

Views: 132

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51648

Try mapping:

val getMyFuncs: Seq[reflect.runtime.universe.MethodMirror] = ???
val getMyFuncs1: Seq[DataFrame => DataFrame] = 
  getMyFuncs.map(mirror => (dataFrame: DataFrame) => mirror(dataFrame).asInstanceOf[DataFrame])

i.e. creating lambdas manually using reflect.runtime.universe.MethodMirror#apply(..).

Upvotes: 2

Related Questions