@@ -2,7 +2,7 @@ package dotty.tools
22package dotc
33package typer
44
5- import ast ._
5+ import ast .{ TreeInfo , tpd , _ }
66import Trees ._
77import core ._
88import Flags ._
@@ -26,7 +26,8 @@ import collection.mutable
2626import reporting .trace
2727import util .Spans .Span
2828import util .SourcePosition
29- import ast .TreeInfo
29+ import dotty .tools .dotc .core .quoted .Spliced
30+ import dotty .tools .dotc .transform .{Splicer , TreeMapWithStages }
3031
3132object Inliner {
3233 import tpd ._
@@ -106,7 +107,7 @@ object Inliner {
106107 else if (enclosingInlineds.length < ctx.settings.XmaxInlines .value) {
107108 val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
108109 if (ctx.reporter.hasErrors) tree
109- else new Inliner (tree, body).inlined(pt)
110+ else new Inliner (tree, body).inlined(pt, tree.sourcePos )
110111 }
111112 else
112113 errorTree(
@@ -359,7 +360,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
359360 }
360361
361362 /** The Inlined node representing the inlined call */
362- def inlined (pt : Type ): Tree = {
363+ def inlined (pt : Type , sourcePos : SourcePosition ): Tree = {
363364
364365 if (callTypeArgs.length == 1 )
365366 if (inlinedMethod == defn.Compiletime_constValue ) {
@@ -467,8 +468,13 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
467468 // The normalized bindings collected in `bindingsBuf`
468469 bindingsBuf.transform(reducer.normalizeBinding(_)(inlineCtx))
469470
471+ // Evaluate the top level ~ if it is a macro
472+ val expansion0 =
473+ if (call.symbol.is(Macro ) && TreeMapWithStages .level == 0 ) expandMacro(expansion, sourcePos)
474+ else expansion
475+
470476 // Run a typing pass over the inlined tree. See InlineTyper for details.
471- val expansion1 = inlineTyper.typed(expansion , pt)(inlineCtx)
477+ val expansion1 = inlineTyper.typed(expansion0 , pt)(inlineCtx)
472478
473479 if (ctx.settings.verbose.value) {
474480 inlining.println(i " to inline = $rhsToInline" )
@@ -487,6 +493,23 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
487493 }
488494 }
489495
496+ private def expandMacro (expansion : Tree , pos : SourcePosition ) = {
497+ // TODO cache macro classloader
498+ val urls = ctx.settings.classpath.value.split(java.io.File .pathSeparatorChar).map(cp => java.nio.file.Paths .get(cp).toUri.toURL)
499+ val macroClassLoader = new java.net.URLClassLoader (urls, getClass.getClassLoader)
500+
501+ new TreeMap () {
502+ override def transform (tree1 : tpd.Tree )(implicit ctx : Context ): tpd.Tree = tree1 match {
503+ case Spliced (splicedBody) =>
504+ val evaluatedSplice = Splicer .splice(splicedBody, pos, macroClassLoader).withSpan(tree1.span)
505+ if (ctx.reporter.hasErrors) EmptyTree
506+ else evaluatedSplice
507+ case _ =>
508+ super .transform(tree1)
509+ }
510+ }.transform(expansion)
511+ }
512+
490513 /** A utility object offering methods for rewriting inlined code */
491514 object reducer {
492515
0 commit comments