diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index b6e448e2e1fd..3b498d58da35 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -88,6 +88,16 @@ import dotty.tools.dotc.core.quoted._ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { import ast.tpd._ + /** Classloader used for loading macros */ + private[this] var myMacroClassLoader: java.lang.ClassLoader = _ + private def macroClassLoader(implicit ctx: Context): ClassLoader = { + if (myMacroClassLoader == null) { + val urls = ctx.settings.classpath.value.split(':').map(cp => java.nio.file.Paths.get(cp).toUri.toURL) + myMacroClassLoader = new java.net.URLClassLoader(urls, getClass.getClassLoader) + } + myMacroClassLoader + } + override def phaseName: String = "reifyQuotes" override def run(implicit ctx: Context): Unit = @@ -542,7 +552,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { // Simplification of the call done in PostTyper for non-macros can also be performed now // see PostTyper `case Inlined(...) =>` for description of the simplification val call2 = Ident(call.symbol.topLevelClass.typeRef).withPos(call.pos) - val spliced = Splicer.splice(body, call, bindings, tree.pos).withPos(tree.pos) + val spliced = Splicer.splice(body, call, bindings, tree.pos, macroClassLoader).withPos(tree.pos) transform(cpy.Inlined(tree)(call2, bindings, spliced)) } else super.transform(tree) diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 73876125afd3..1d9acc0324d7 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -30,16 +30,13 @@ object Splicer { * * See: `ReifyQuotes` */ - def splice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position)(implicit ctx: Context): Tree = tree match { + def splice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position, classLoader: ClassLoader)(implicit ctx: Context): Tree = tree match { case Quoted(quotedTree) => quotedTree - case _ => reflectiveSplice(tree, call, bindings, pos) - } - - private def reflectiveSplice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position)(implicit ctx: Context): Tree = { - val liftedArgs = getLiftedArgs(call, bindings) - val interpreter = new Interpreter(pos) - val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol) - interpreted.flatMap(lambda => evaluateLambda(lambda, liftedArgs, pos)).fold(tree)(PickledQuotes.quotedExprToTree) + case _ => + val liftedArgs = getLiftedArgs(call, bindings) + val interpreter = new Interpreter(pos, classLoader) + val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol) + interpreted.flatMap(lambda => evaluateLambda(lambda, liftedArgs, pos)).fold(tree)(PickledQuotes.quotedExprToTree) } /** Given the inline code and bindings, compute the lifted arguments that will be used to execute the macro @@ -98,12 +95,7 @@ object Splicer { * The interpreter assumes that all calls in the trees are to code that was * previously compiled and is present in the classpath of the current context. */ - private class Interpreter(pos: Position)(implicit ctx: Context) { - - private[this] val classLoader = { - val urls = ctx.settings.classpath.value.split(':').map(cp => java.nio.file.Paths.get(cp).toUri.toURL) - new URLClassLoader(urls, getClass.getClassLoader) - } + private class Interpreter(pos: Position, classLoader: ClassLoader)(implicit ctx: Context) { /** Returns the interpreted result of interpreting the code a call to the symbol with default arguments. * Return Some of the result or None if some error happen during the interpretation.