Hi
On 9/24/26 23:07, MG wrote:
Hi Jochen,
1. I checked today, and INFERRED_TYPE unfortunately does not seem to be
filled at this point, in fact all the metaDataMap|s I checked on
different Expression|s that appear in my test code were null...
yes, I mentioned that may be the case. The macros run before this
information is added
[...]> 3. Anyways, I actually have 2 NULL_TO macro implementations:
1. One based on the ternary operator, which I had discarded, and
which I just checked again and saw that it behaves the way you
describe also under static compilation, i.e. it does not require
a cast and works under @CompileStatic as expected.
1. The reason I discarded it, was that I did not know how to
avoid the double evaluation inside a macro when doing a
ternary null check, i.e.:
1. exp0 !== null ? exp0 : exp1 // exp0 gets evaluated 2x,
unless there is a way to store its result inside a
macro... (?)
That is vastly different from what I understood... ok... so normally you
want Elvis instead, but:
2. And one based on the Elvis operator - this one of course looks
no good at first glance, since it uses Groovy truth, which is
exactly what we do not want.
yeah, exactly.
1. To get around this, I introduced a
simple NullToMacroWrapper helper class which stores the
result, with an overridden asBoolean method that checks its
stored value against null, i.e.:
1. wrapInNullToMacroWrapper(exp0) ?: exp1
2. ...but that helper class (which currently is not generic, so
it can resuse a thread local singleton) is exactly what
requires the cast (as I saw when rechecking the ternary
operator NULL_TO version).
I don't think macros are a good fit for this
4. So as far as I can see either:
1. There is a way to store the exp0 evaluation result inside the
macro, then the rest is trivial.
temporary variables maybe, but frankly that does not look like it will
work well as the right side of an assignment/declaration
2. There is a way to get the right type to do the cast of the Elvis
operator based result.
the "right" type is the left side type I assume, which you have no
access to in the macro
3. Turning NullToMacroWrapper into a generic class fixes the cast
problem - but this approach would create (short lived, i.e. gen
zero) NullToMacroWrapper instances on the heap...
I thought that also created a casting problem?
4. Or one can ditch the macro approach and go down the local
transform route (have never done this, so no idea how much
effort this is and what small, unexpected snags await there ;-) ).
macros are basically specialized local transforms. You have a slightly
different interface and you can choose the compilation phase... but most
importantly you have more context to work with and can place them at
other source positions.
So yes, they