summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Enclosures.scala1
-rw-r--r--src/reflect/scala/reflect/macros/Enclosures.scala8
-rw-r--r--test/files/run/macro-enclosures.check2
-rw-r--r--test/files/run/macro-enclosures/Impls_Macros_1.scala22
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