Enclosing class, what's available from the Universe?


I’ve been eagerly waiting for the new macros to see how migrating my two bigger open-source projects which use them: quicklens and macwire might go. While quicklens should be relatively easy (a blackbox macro manipulating the AST of the code passed as the argument), I’m not so sure of macwire.

I’m not sure if I understand the proposed capabilities of the new API correctly (I’m looking at the Universe from https://github.com/scalacenter/macros), but I think there’s no way currently to obtain information about the surrounding environment?

More specifically, what macwire relies on is the capability to browse the enclosing method/class/object & its parents for defined values of a specific type; once that’s available, then it’s a pretty straightforward black-box macro.

Is such functionality planned, or maybe on the opposite, deliberately not planned?


It’s still to be decided what exact methods end up in Universe. In theory, we can expose the same capabilities as the existing macro API. The challenge is to strike a right balance genericity and portability. We want to avoid APIs that encourage coding against implementation details of individual compilers.

Can you share links to where you inspect the enclosing class members in macwire?

ScalaCache has a scala-reflect macro that depends on gathering knowledge about the surrounding environment in order to build up a cache key (see here for the source, which uses c.internal.enclosingOwner).

The other project off the top of my head that definitely requires knowledge of the macro’s surroundings is Enumeratum, which calls c.enclosingClass.

I know that Eugene was never that keen on letting macros gather this kind of information, for portability reasons I guess, but it’s really useful for certain use cases.

Sure, here’s where enclosingClass is used:

These are indeed deprecated since the last release I think, but nonetheless without them macwire wouldn’t be possible.

As an alternative to exposing the whole enclosing tree, the API could provide a way to obtain accessible values of a given type, together with information where they are coming from - their scope. Not sure, however, how that would work for other usages mentioned.


@olafurpg please comment on @adamw examples? what is new pattern to replace enclosingClass?

@adamw @Andrei-Pozolotin I apologize for the slow response, I had a draft comment that never went out!

The API for the new macros hasn’t been decided yet, so it’s too early to say what the new pattern is. We’ve been exploring the past weeks hygiene, mixing of untyped/typed trees and owner chain corruptions that plague many scala-reflect macros.

@adamw what do you think: https://github.com/scalacenter/macros/issues/35

I’m not sure if that would be sufficient - how would we get the available symbols (eg in the enclosing class) in the first place?