Skip to content

Commit b17deea

Browse files
committed
Cache macro classloader
1 parent f8b9f3f commit b17deea

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

compiler/src/dotty/tools/dotc/Driver.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import dotty.tools.FatalError
66
import config.CompilerCommand
77
import core.Comments.{ContextDoc, ContextDocstrings}
88
import core.Contexts.{Context, ContextBase}
9-
import core.{Mode, TypeError}
9+
import core.{MacroClassLoader, Mode, TypeError}
1010
import reporting._
1111

1212
import scala.util.control.NonFatal
@@ -54,6 +54,7 @@ class Driver {
5454
val ctx = rootCtx.fresh
5555
val summary = CompilerCommand.distill(args)(ctx)
5656
ctx.setSettings(summary.sstate)
57+
MacroClassLoader.init(ctx)
5758

5859
if (!ctx.settings.YdropComments.value(ctx) || ctx.mode.is(Mode.ReadComments)) {
5960
ctx.setProperty(ContextDoc, new ContextDocstrings)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dotty.tools.dotc.core
2+
3+
import dotty.tools.dotc.core.Contexts._
4+
import dotty.tools.dotc.util.Property
5+
import dotty.tools.dotc.reporting.trace
6+
7+
import scala.collection.mutable
8+
9+
object MacroClassLoader {
10+
11+
/** A key to be used in a context property that caches the class loader used for macro expansion */
12+
private val MacroClassLoaderKey = new Property.Key[ClassLoader]
13+
14+
/** Get the macro class loader */
15+
def fromContext(implicit ctx: Context): ClassLoader =
16+
ctx.property(MacroClassLoaderKey).getOrElse(makeMacroClassLoader)
17+
18+
/** Context with a cached macro class loader that can be accessed with `macroClassLoader` */
19+
def init(ctx: FreshContext): ctx.type =
20+
ctx.setProperty(MacroClassLoaderKey, makeMacroClassLoader(ctx))
21+
22+
private def makeMacroClassLoader(implicit ctx: Context): ClassLoader = trace("new macro class loader") {
23+
val urls = ctx.settings.classpath.value.split(java.io.File.pathSeparatorChar).map(cp => java.nio.file.Paths.get(cp).toUri.toURL)
24+
new java.net.URLClassLoader(urls, getClass.getClassLoader)
25+
}
26+
}

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Symbols._
1010
import Types._
1111
import Decorators._
1212
import Constants._
13+
import StagingContext._
1314
import StdNames._
1415
import transform.SymUtils._
1516
import Contexts.Context
@@ -957,20 +958,16 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
957958
assert(tree.hasType, tree)
958959
val qual1 = typed(tree.qualifier, selectionProto(tree.name, pt, this))
959960
val res =
960-
if (tree.symbol == defn.QuotedExpr_splice && StagingContext.level == 0) expandMacro(qual1, tree.span)
961+
if (tree.symbol == defn.QuotedExpr_splice && level == 0) expandMacro(qual1, tree.span)
961962
else untpd.cpy.Select(tree)(qual1, tree.name).withType(tree.typeOpt)
962963
ensureAccessible(res.tpe, tree.qualifier.isInstanceOf[untpd.Super], tree.sourcePos)
963964
res
964965
}
965966

966967
private def expandMacro(body: Tree, span: Span)(implicit ctx: Context) = {
967-
assert(StagingContext.level == 0)
968-
// TODO cache macro classloader
969-
val urls = ctx.settings.classpath.value.split(java.io.File.pathSeparatorChar).map(cp => java.nio.file.Paths.get(cp).toUri.toURL)
970-
val macroClassLoader = new java.net.URLClassLoader(urls, getClass.getClassLoader)
971-
968+
assert(level == 0)
972969
val inlinedFrom = enclosingInlineds.last
973-
val evaluatedSplice = Splicer.splice(body, inlinedFrom.sourcePos, macroClassLoader)(ctx.withSource(inlinedFrom.source))
970+
val evaluatedSplice = Splicer.splice(body, inlinedFrom.sourcePos, MacroClassLoader.fromContext)(ctx.withSource(inlinedFrom.source))
974971
if (ctx.reporter.hasErrors) EmptyTree
975972
else evaluatedSplice.withSpan(span)
976973
}

0 commit comments

Comments
 (0)