I have a macro annotation which is intended to be applied to class definitions. Its purpose is an almost-but-not-quite serialization tool. It inspects the class's constructor parameters and then creates a factory method on the companion object which in turn supplies values for the parameters. It needs to know the types of the parameters in order to do this, so I've been calling Context.typeCheck on them.

The problem occurs when the annotated class's constructor takes a parameter of the same type as itself, or in other similar situations (for instance, if type A and type B both are annotated, and A has a parameter of B, and B has a parameter of A. Type parameters applied to the formal parameters count also). Any of these situations will result in the annotation being recursively invoked until StackOverflowError occurs.

I tried using "withMacrosDisabled=true" as an argument to c.typeCheck, and while this solves the problem, it introduces a different one. If the type being checked has not been previously seen, then the compiler remembers its definition, and its macros are never invoked at all. This isn't a problem for the self-reference case, but it does happen in the mutual reference case.

So I'm stuck. Is there a workaround? Can I solve this with c.openMacros?

Another option, if available, is that I don't strictly need the full definition of the type, I could get by with just its fully qualified name (scala.xml.NodeSeq instead of just NodeSeq). I get the TypeName in the AST, but these are rarely fully qualified, and I don't know how to get the fully qualified name without doing a full typeCheck.

As a side question, what is "withMacrosDisabled" good for? If using it prevents all macro expansion forever on the types found in the passed tree, not just for the current c.typeCheck, that seems like too big of a hammer. And you can't really use it even if that's actually what you want, because the macro evaluation would then depend on the order the types are encountered in their own source.

**Edit**: Thinking about it, I think the compiler should ensure that each macro is expanded exactly once. In the case of a cycle, as in my example, at least one of the macros involved would still see an incompletely-processed class, which seems unavoidable in a case like this as it is, in effect, a circular dependency. I guess, a flag on the resulting Type to indicate that macro processing is not final would be the best way to deal with it, but that probably can't be done in Paradise.