Reputation: 859
I use scala macros for extract all object from package, and then i would like get some values from object:
package example
trait A {}
object B extends A { val test = "test" }
//macro
object Macro
def getVals(packageName: String) = macro getValsImpl
def getValsImpl(c: Context)(packageName: c.Expr[String]): c.Expr[Unit] = {
import c.universe._
val pkg = from.tree match {
case Literal(Constant(name: String)) => c.mirror.staticPackage(name)
}
val objects = pkg.typeSignature.members.collect {
//get all objects which a subtype of `A`
case x if (x.isModule && x.typeSignature <:< typeOf[A]) => x
}.toList
val o = objects(0)
println(o.test)
reify {}
}
}
But i got error
value test is not a member of c.universe.ModuleSymbol
Upvotes: 0
Views: 572
Reputation: 10764
You are mistaking compile time artifacts for actual runtime values.
Macro implementation is invoked at compile time. The actual objects you are trying to access don't yet exist (only the language Symbol
s that represent them). That is why you are getting a ModuleSymbol
when you expect the B
object.
In other words, you simply can't access B
in macro implementation.
Macros are meant to analyze, transform and generate code (represented as Expr
s and Tree
s). So, what you can do is - having a ModuleSymbol
that represents an object - generate code that, when compiled and finally executed in runtime, will evaluate to that object. But I don't know if this is what you want here.
Upvotes: 1