1

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?

Pᴇʜ
  • 56,719
  • 10
  • 49
  • 73

1 Answers1

2

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 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 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

Dmytro Mitin
  • 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