Question

I am attempting to define a Scala object by providing a string to ToolBox, but I cannot find a way to get a handle to the resulting ModuleMirror. I imagine it would be something like the following but I don't seem able to get the RuntimeClass from the result of the ToolBox eval:

import scala.reflect.runtime._
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox

val src = """ object MyObject { def hello() = "world" } """

val mirror = universe.runtimeMirror(getClass.getClassLoader)

val toolBox = mirror.mkToolBox()
val tree = toolBox.parse(src)
val value = toolBox.eval(tree)

// convert from result of eval to RuntimeClass...?
val runtimeClass: RuntimeClass = ???

val moduleSymbol = mirror.moduleSymbol(runtimeClass)

val moduleMirror = mirror.reflectModule(moduleSymbol.asModule)

Any suggestions?

Was it helpful?

Solution

The best way to get a class of the object would probably be returning MyObject.getClass from the block of code being compiled.

However, calling moduleSymbol on the resulting class would result in NoSymbol, because local objects aren't currently supported by Scala reflection. Why local objects? Because eval wraps the code fed to it in a method to enable its evaluation, which means that MyObject would end up being local to the wrapper method. Why aren't currently supported? Well, it's because Scala reflection relies on @ScalaSignature annotations that carry Scala-specific metadata, and these annotations are currently not saved for local definitions.

I think it would be possible to change ToolBox.compile (a non-evaluating counterpart of eval) to special-case processing of top-level definitions, so that they not end up being compiled as local. Could you submit an issue to our issue tracker, so that we don't forget to fix it?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top