@@ -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 ._
@@ -25,6 +25,7 @@ import dotty.tools.dotc.util.{SimpleIdentityMap, SimpleIdentitySet, SourceFile,
2525import collection .mutable
2626import reporting .trace
2727import util .Spans .Span
28+ import dotty .tools .dotc .transform .{Splicer , TreeMapWithStages }
2829
2930object Inliner {
3031 import tpd ._
@@ -104,7 +105,7 @@ object Inliner {
104105 else if (enclosingInlineds.length < ctx.settings.XmaxInlines .value) {
105106 val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
106107 if (ctx.reporter.hasErrors) tree
107- else new Inliner (tree, body).inlined(pt)
108+ else new Inliner (tree, body).inlined(pt, tree.sourcePos )
108109 }
109110 else
110111 errorTree(
@@ -381,7 +382,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
381382 }
382383
383384 /** The Inlined node representing the inlined call */
384- def inlined (pt : Type ): Tree = {
385+ def inlined (pt : Type , sourcePos : SourcePosition ): Tree = {
385386
386387 if (callTypeArgs.length == 1 )
387388 if (inlinedMethod == defn.Compiletime_constValue ) {
@@ -487,7 +488,13 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
487488 trace(i " inlining $call" , inlining, show = true ) {
488489
489490 // The normalized bindings collected in `bindingsBuf`
490- bindingsBuf.transform(reducer.normalizeBinding(_)(inlineCtx))
491+ bindingsBuf.transform { binding =>
492+ val transformedBinding = reducer.normalizeBinding(binding)(inlineCtx)
493+ // Set trees to symbols allow macros to see the definition tree.
494+ // This is used by `underlyingArgument`.
495+ transformedBinding.symbol.defTree = transformedBinding
496+ transformedBinding
497+ }
491498
492499 // Run a typing pass over the inlined tree. See InlineTyper for details.
493500 val expansion1 = inlineTyper.typed(expansion, pt)(inlineCtx)
@@ -949,11 +956,25 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
949956 override def typedSelect (tree : untpd.Select , pt : Type )(implicit ctx : Context ): Tree = {
950957 assert(tree.hasType, tree)
951958 val qual1 = typed(tree.qualifier, selectionProto(tree.name, pt, this ))
952- val res = untpd.cpy.Select (tree)(qual1, tree.name).withType(tree.typeOpt)
959+ val res =
960+ if (tree.symbol == defn.QuotedExpr_splice && StagingContext .level == 0 ) expandMacro(qual1, tree.span)
961+ else untpd.cpy.Select (tree)(qual1, tree.name).withType(tree.typeOpt)
953962 ensureAccessible(res.tpe, tree.qualifier.isInstanceOf [untpd.Super ], tree.sourcePos)
954963 res
955964 }
956965
966+ 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+
972+ val inlinedFrom = enclosingInlineds.last
973+ val evaluatedSplice = Splicer .splice(body, inlinedFrom.sourcePos, macroClassLoader)(ctx.withSource(inlinedFrom.source))
974+ if (ctx.reporter.hasErrors) EmptyTree
975+ else evaluatedSplice.withSpan(span)
976+ }
977+
957978 override def typedIf (tree : untpd.If , pt : Type )(implicit ctx : Context ): Tree =
958979 typed(tree.cond, defn.BooleanType ) match {
959980 case cond1 @ ConstantValue (b : Boolean ) =>
0 commit comments