0

Say I have an expression whose tree I want to capture (without evaluating it!) and then pass it into a another macro sometime later:

// capture a tree from some arbitrary expression
val capturedTree = captureMacro( some(expression(tree())) )

// plug the tree into here
val result = processMacro(capturedTree, otherStuff)

Is there any way to do this? I've tried making capturedTree a refined type hoping that this would preserve the initial tree but that did not happen:

trait WithCapturedTree { def tree:Any }
class ReturnTreeMacro(val c:MacroContext) {
    import c.universe._

    def run(expression: Tree) =
        q"new WithCapturedTree {val tree = ${expression}}"
    }
def returnTree(expression:String):WithCapturedTree = macro ReturnTreeMacro.run

reify { returnTree("foo"+"bar") }
// returns Expr[WithCapturedTree{val tree: java.lang.String}](returnTree("foobar"))
// I.e. the result of "foo"+"bar" has already been evaluated!

Is there a way to get this approach to work? Is there a better appraoch for this problem?

  • 1
    Could you describe your real high-level problem of why do you need this at all? Macro can contain main functions that call each other inside one macro invocation. Why do you need to pass some data between macro invocations? – SergGr Jan 04 '19 at 01:34
  • @SergGr The 'capturedTree' is a tree that I want to search inside of 'otherStuff' in processMacro. Actually I want to define multiple capturedTrees which to search for inside of 'otherStuff' and replace in some situations.I don't want my users to be forced to define all the capturedTrees directly inside of the processMacro function, because there will be multiple processMacro invocations with different 'otherStuff' in each one. – Choppy The Lumberjack Jan 04 '19 at 02:41
  • Sorry, your description is still not clear to me. If the user can pass some `capturedTree` to your `processMacro` macro, why he can't pass the data used to build it and let the `processMacro` macro build the same `capturedTree` inside using the same call? Or is it just an attempt of a performance optimization? – SergGr Jan 04 '19 at 04:26
  • 1
    Reusing code in different macros is normally done by macro bundles https://docs.scala-lang.org/overviews/macros/bundles.html – Dmytro Mitin Jan 04 '19 at 18:29
  • https://stackoverflow.com/questions/64950654/how-to-use-a-universe-tree-created-and-type-checked-in-one-scala-macro-executi – Dmytro Mitin Sep 12 '22 at 21:46

0 Answers0