0

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
mike
  • 749
  • 10
  • 21
  • I'm completely guessing here, and my scala is not that good, but try checking the size of `objects` or the type of `objects(0)`. Maybe you're getting something other than a B – Millie Smith Nov 09 '13 at 15:54
  • This may give you the answers you need: http://stackoverflow.com/questions/12128783/how-can-i-get-the-actual-object-referred-to-by-scala-2-10-reflection – Millie Smith Nov 09 '13 at 16:03

1 Answers1

1

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.

ghik
  • 10,706
  • 1
  • 37
  • 50