Here is one possible answer. Basically, there is a reset() method that calls the following things (mostly private, so either you buy the whole package or not):
clearExecutionWrapper() resetClassLoader() resetAllCreators() prevRequests.clear() referencedNameMap.clear() definedNameMap.clear() virtualDirectory.clear()
In my case, I use a custom runtime wrapper, so it needs to be tuned again, and the import is processed through a regular interpretation loop, so either add them again, or it is best to add them using the execution wrapper.
I would like to keep the bindings, they also disappeared:
import tools.nsc._ import interpreter.IMain object Test { private final class Intp(cset: nsc.Settings) extends IMain(cset, new NewLinePrintWriter(new ConsoleWriter, autoFlush = true)) { override protected def parentClassLoader = Test.getClass.getClassLoader } object Foo { def bar() { println("BAR" )} } def run() { val cset = new nsc.Settings() cset.classpath.value += java.io.File.pathSeparator + sys.props("java.class.path") val i = new Intp(cset) i.initializeSynchronous() i.bind[Foo.type]("foo", Foo) val res0 = i.interpret("foo.bar(); val x = 33") println(s"res0: $res0") i.reset() val res1 = i.interpret("println(x)") println(s"res1: $res1") i.reset() val res2 = i.interpret("foo.bar()") println(s"res2: $res2") } }
This will find Foo in the first iteration, correctly forget x in the second iteration, but then in the third iteration you can see that the Foo binding is also lost:
foo: Test.Foo.type = Test$Foo$@8bf223 BAR x: Int = 33 res0: Success <console>:8: error: not found: value x println(x) ^ res1: Error <console>:8: error: not found: value foo foo.bar() ^ res2: Error
Everything seems to be in order:
for(j <- 0 until 3) { val user = "foo.bar()" val synth = """import Test.{Foo => foo} """.stripMargin + user val res = i.interpret(synth) println(s"res$j: $res") i.reset() }
source share