Calling instance method in macro implementation for selectDynamic
scala, scala-macros
Solution
You can use `c.prefix.tree` instead of `This`.
// macro implementation
import scala.language.experimental.macros
import scala.reflect.macros.Context
import language.dynamics
object MyMacros {
def selectDynamic(c: Context)(name: c.Expr[String]): c.Expr[String] = {
import c.universe._
// I expected `This` to refer a Sample instance, but actually it refers SampleSpec instance...
c.Expr[String](Apply(Select(c.prefix.tree, newTermName("cap")), List(name.tree)))
}
}
// class which uses selectDynamic and macro
class Sample extends Dynamic {
def cap(name: String): String = name.toUpperCase
def selectDynamic(name: String): String = macro MyMacros.selectDynamic
}
Problem
I'd like to use `Sample#cap(String)` in the following macro implementation for selectDynamic. Is it possible? ``` // macro implementation import scala.language.experimental.macros import scala.reflect.macros._ object MyMacros { def selectDynamic(c: Context)(name: c.Expr[String]): c.Expr[String] = { // I expected `This` to refer a Sample instance, but actually it refers SampleSpec instance... c.Expr[String](Apply(TypeApply(Select(This(tpnme.EMPTY), newTermName("cap")), List(Ident(typeTag[String].tpe.typeSymbol))), List(name.tree))) } } // class which uses selectDynamic and macro import scala.language.dynamics class Sample extends Dynamic { def cap(name: String): String = name.toUpperCase def selectDynamic(name: String): String = macro MyMacros.selectDynamic } class SampleSpec extends FlatSpec with ShouldMatchers { it should "call dynamic" in { val sample = new Sample sample.foo should equal("FOO") // value cap is not a member of SampleSpec } } ```