Skip to content

Commit 5cf42a5

Browse files
committed
Cashe classloader directly in ReifyQuotes
1 parent 04c18a5 commit 5cf42a5

File tree

2 files changed

+19
-20
lines changed

2 files changed

+19
-20
lines changed

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ import dotty.tools.dotc.core.quoted._
8888
class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
8989
import ast.tpd._
9090

91-
private lazy val splicer: Splicer = new Splicer
91+
/** Classloader used for loading macros */
92+
private var macroClassLoader: java.lang.ClassLoader = _
9293

9394
override def phaseName: String = "reifyQuotes"
9495

@@ -544,7 +545,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
544545
// Simplification of the call done in PostTyper for non-macros can also be performed now
545546
// see PostTyper `case Inlined(...) =>` for description of the simplification
546547
val call2 = Ident(call.symbol.topLevelClass.typeRef).withPos(call.pos)
547-
val spliced = splicer.splice(body, call, bindings, tree.pos).withPos(tree.pos)
548+
val spliced = Splicer.splice(body, call, bindings, tree.pos, getMacroClassLoader).withPos(tree.pos)
548549
transform(cpy.Inlined(tree)(call2, bindings, spliced))
549550
}
550551
else super.transform(tree)
@@ -622,6 +623,14 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
622623
transform(tp)
623624
}
624625

626+
private def getMacroClassLoader(implicit ctx: Context): ClassLoader = {
627+
if (macroClassLoader == null) {
628+
val urls = ctx.settings.classpath.value.split(':').map(cp => java.nio.file.Paths.get(cp).toUri.toURL)
629+
macroClassLoader = new java.net.URLClassLoader(urls, getClass.getClassLoader)
630+
}
631+
macroClassLoader
632+
}
633+
625634
override protected def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.is(Macro)
626635

627636
/** Returns the type of the compiled macro as a lambda: Seq[Any] => Object */

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,22 @@ import dotty.tools.dotc.util.Positions.Position
2121
import scala.reflect.ClassTag
2222

2323
/** Utility class to splice quoted expressions */
24-
class Splicer {
24+
object Splicer {
2525
import tpd._
2626

27-
private var classLoader: URLClassLoader = _
28-
2927
/** Splice the Tree for a Quoted expression. `~'(xyz)` becomes `xyz`
3028
* and for `~xyz` the tree of `xyz` is interpreted for which the
3129
* resulting expression is returned as a `Tree`
3230
*
3331
* See: `ReifyQuotes`
3432
*/
35-
def splice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position)(implicit ctx: Context): Tree = tree match {
33+
def splice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position, classLoader: ClassLoader)(implicit ctx: Context): Tree = tree match {
3634
case Quoted(quotedTree) => quotedTree
37-
case _ => reflectiveSplice(tree, call, bindings, pos)
38-
}
39-
40-
private def reflectiveSplice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position)(implicit ctx: Context): Tree = {
41-
val liftedArgs = getLiftedArgs(call, bindings)
42-
val interpreter = new Interpreter(pos)
43-
val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol)
44-
interpreted.flatMap(lambda => evaluateLambda(lambda, liftedArgs, pos)).fold(tree)(PickledQuotes.quotedExprToTree)
35+
case _ =>
36+
val liftedArgs = getLiftedArgs(call, bindings)
37+
val interpreter = new Interpreter(pos, classLoader)
38+
val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol)
39+
interpreted.flatMap(lambda => evaluateLambda(lambda, liftedArgs, pos)).fold(tree)(PickledQuotes.quotedExprToTree)
4540
}
4641

4742
/** Given the inline code and bindings, compute the lifted arguments that will be used to execute the macro
@@ -100,12 +95,7 @@ class Splicer {
10095
* The interpreter assumes that all calls in the trees are to code that was
10196
* previously compiled and is present in the classpath of the current context.
10297
*/
103-
private class Interpreter(pos: Position)(implicit ctx: Context) {
104-
105-
if (classLoader == null) {
106-
val urls = ctx.settings.classpath.value.split(':').map(cp => java.nio.file.Paths.get(cp).toUri.toURL)
107-
classLoader = new URLClassLoader(urls, getClass.getClassLoader)
108-
}
98+
private class Interpreter(pos: Position, classLoader: ClassLoader)(implicit ctx: Context) {
10999

110100
/** Returns the interpreted result of interpreting the code a call to the symbol with default arguments.
111101
* Return Some of the result or None if some error happen during the interpretation.

0 commit comments

Comments
 (0)