mike
mike

Reputation: 859

Scala Macros: get vals from object

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

Answers (1)

ghik
ghik

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 Symbols 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 Exprs and Trees). 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

Related Questions