I am writing a macro to get the enclosing val/var
definition. I can get the enclosing val/var
symbol, but I can not get the defining tree. One solution here suggested using enclosingClass
:
https://stackoverflow.com/a/18451114/11989864
But all the enclosing-tree style API is deprecated:
https://www.scala-lang.org/api/2.13.0/scala-reflect/scala/reflect/macros/blackbox/Context.html
Is there a way to implement the functionality of enclosingClass
? Or to get a tree from a symbol?

- 56,719
- 10
- 49
- 73

- 11
- 1
1 Answers
Reasons for deprecation are
Starting from Scala 2.11.0, the APIs to get the trees enclosing by the current macro application are deprecated, and the reasons for that are two-fold. Firstly, we would like to move towards the philosophy of locally-expanded macros, as it has proven to be important for understanding of code. Secondly, within the current architecture of scalac, we are unable to have
c.enclosingTree
-style APIs working robustly. Required changes to the typechecker would greatly exceed the effort that we would like to expend on this feature given the existence of more pressing concerns at the moment. This is somewhat aligned with the overall evolution of macros during the 2.11 development cycle, where we played withc.introduceTopLevel
andc.introduceMember
, but at the end of the day decided to reject them.If you're relying on the now deprecated APIs, consider using the new
c.internal.enclosingOwner
method that can be used to obtain the names of enclosing definitions. Alternatively try reformulating your macros in terms of completely local expansion...
https://www.scala-lang.org/api/2.13.0/scala-reflect/scala/reflect/macros/Enclosures.html
Regarding getting a tree from a symbol
there's no standard way to go from a symbol to a defining tree
https://stackoverflow.com/a/13768595/5249621
Why do you need def macro to get the enclosing val
/var
definition?
Maybe macro annotatations can be enough https://docs.scala-lang.org/overviews/macros/annotations.html

- 48,194
- 3
- 28
- 66
-
Thanks Dmytro. I have multiple methods that are macro-expanded and can be chained or nested and I want to attach the name of the declared value to the final object. I can use run-time reflection to do that, but it only works in the class constructor scope, i.e. if I have nested scopes, I can not reflect on the declared values inside these scopes. – Muhammad Soliman Oct 08 '19 at 19:01
-
@MuhammadSoliman You can try macro annotations, compiler plugin or rewriting sources with Scalameta/Scalafix. Although `c.enclosingClass` is depecated it still seems to work (at least in some cases), you can try to continue using it so far (anyway current macros will be deprecated in Scala 3). – Dmytro Mitin Oct 08 '19 at 19:20
-
I wanted to avoid explicit annotations. I will probably use the `enclosingClass` for now. Thanks. – Muhammad Soliman Oct 08 '19 at 20:45