diff options
4 files changed, 24 insertions, 9 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Enclosures.scala b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala index 5e931817b5..0b4aad85a3 100644 --- a/src/compiler/scala/reflect/macros/contexts/Enclosures.scala +++ b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala @@ -18,6 +18,7 @@ trait Enclosures { // vals are eager to simplify debugging // after all we wouldn't save that much time by making them lazy val macroApplication: Tree = expandee + val enclosingOwner = site.owner def enclosingPackage: PackageDef = strictEnclosure[PackageDef] val enclosingClass: Tree = lenientEnclosure[ImplDef] def enclosingImpl: ImplDef = strictEnclosure[ImplDef] diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala index 1ced2e54c6..7c186139cf 100644 --- a/src/reflect/scala/reflect/macros/Enclosures.scala +++ b/src/reflect/scala/reflect/macros/Enclosures.scala @@ -20,7 +20,8 @@ import scala.language.existentials // SI-6541 * This is somewhat aligned with the overall evolution of macros during the 2.11 development cycle, where we played with * `c.introduceTopLevel` and `c.introduceMember`, but at the end of the day decided to reject them. * - * If you're relying on the now deprecated APIs, consider reformulating your macros in terms of completely local expansion + * If you're relying on the now deprecated APIs, consider using the new [[c.enclosingOwner]] method that can be used to obtain + * the names of enclosing definitions. Alternatively try reformulating your macros in terms of completely local expansion * and/or joining a discussion of a somewhat related potential language feature at [[https://groups.google.com/forum/#!topic/scala-debate/f4CLmYShX6Q]]. * We also welcome questions and suggestions on our mailing lists, where we would be happy to further discuss this matter. */ @@ -51,6 +52,11 @@ trait Enclosures { */ def enclosingPosition: Position + /** Symbol associated with the innermost enclosing lexical context. + * Walking the owner chain of this symbol will reveal information about more and more enclosing contexts. + */ + def enclosingOwner: Symbol + /** Tree that corresponds to the enclosing method, or EmptyTree if not applicable. * @see [[scala.reflect.macros.Enclosures]] */ diff --git a/test/files/run/macro-enclosures.check b/test/files/run/macro-enclosures.check index 36bb67e194..b6fe7a4a91 100644 --- a/test/files/run/macro-enclosures.check +++ b/test/files/run/macro-enclosures.check @@ -30,3 +30,5 @@ enclosingTemplate = scala.AnyRef { } enclosingMethod = def test = Macros.foo enclosingDef = def test = Macros.foo +enclosingOwner = method test +enclosingOwnerChain = List(method test, object Test, package test, package <root>) diff --git a/test/files/run/macro-enclosures/Impls_Macros_1.scala b/test/files/run/macro-enclosures/Impls_Macros_1.scala index 5b04cf29e9..a0f66a6b98 100644 --- a/test/files/run/macro-enclosures/Impls_Macros_1.scala +++ b/test/files/run/macro-enclosures/Impls_Macros_1.scala @@ -3,15 +3,21 @@ import scala.reflect.macros.blackbox.Context object Macros { def impl(c: Context) = { import c.universe._ - reify { - println("enclosingPackage = " + c.Expr[String](Literal(Constant(c.enclosingPackage.toString))).splice) - println("enclosingClass = " + c.Expr[String](Literal(Constant(c.enclosingClass.toString))).splice) - println("enclosingImpl = " + c.Expr[String](Literal(Constant(c.enclosingImpl.toString))).splice) - println("enclosingTemplate = " + c.Expr[String](Literal(Constant(c.enclosingTemplate.toString))).splice) - println("enclosingMethod = " + c.Expr[String](Literal(Constant(c.enclosingMethod.toString))).splice) - println("enclosingDef = " + c.Expr[String](Literal(Constant(c.enclosingDef.toString))).splice) + def chain(sym: Symbol): List[Symbol] = sym.owner match { + case NoSymbol => sym :: Nil + case owner => sym :: chain(owner) } + q""" + println("enclosingPackage = " + ${c.enclosingPackage.toString}) + println("enclosingClass = " + ${c.enclosingClass.toString}) + println("enclosingImpl = " + ${c.enclosingImpl.toString}) + println("enclosingTemplate = " + ${c.enclosingTemplate.toString}) + println("enclosingMethod = " + ${c.enclosingMethod.toString}) + println("enclosingDef = " + ${c.enclosingDef.toString}) + println("enclosingOwner = " + ${c.enclosingOwner.toString}) + println("enclosingOwnerChain = " + ${chain(c.enclosingOwner).toString}) + """ } - def foo = macro impl + def foo: Any = macro impl }
\ No newline at end of file |