Hi,

I think you are having a detail problem are your description is a bit too generic for that.

```groovy
import org.codehaus.groovy.macro.runtime.Macro
import org.codehaus.groovy.macro.runtime.MacroContext
import org.codehaus.groovy.ast.expr.Expression
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.expr.ArgumentListExpression
import org.codehaus.groovy.ast.stmt.BlockStatement
import static org.codehaus.groovy.macro.runtime.MacroGroovyMethods.macro

class GuardMacros {

    @Macro
static Expression NOT_NULL(MacroContext ctx, MethodCallExpression call) {

        List<Expression> expressions = argList.getExpressions()
        Expression finalExp = expressions.last()
        List<Expression> checks = expressions.subList(0,
        Expression resultAST = finalExp

        for (int i = checks.size() - 1; i >= 0; i--) {
            Expression currentCheck = checks[i]

            resultAST = macro {
                $v{currentCheck} != null ? $v{resultAST} : null
            }
        }

        return resultAST
    }
}
```

If you are using that kind of structure, then the possible problem is that the ternary expression historically had some problems with using the right type. But normally
On 9/23/26 22:45, MG wrote:
[...]
 5. Question: How do I get the actual type of method parameters as given
    in the source code (hope they have not been erased at this point,
    since then I would be back to square one...) ?
     1. e.g. (nonsensical, just to show the problem):
        void foo(BigDecimal x0, BigDecimal x1) {
             final BigDecimal x = NULL_TO(x0,  x1)  // still fails with
        "cannot assign Object to BigDecimal", since the Expression#type
        of the x0 and x1 Expression|s is a class node of type
        java.lang.Object...
        }

should then work. you can test it without the macro by actually writing it as ternary expression in the source code. Just once. To verify.

 6. Bonus question: What one evidently would want is not the type of one
    of the Expression|s passed to NULL_TO, but instead the common
    supertype of all the Expression|s - is there any accessible existing
    functionality to get that ?-)
Eric already mentioned WideningCategories.lowestUpperBound. But I am not sure if INFERRED_TYPE is available at the time the macro is executed.

If you really want to enforce the cast, I would consider a local transform instead of a macro. Then you can work on the declaration itself and use the left type to enforce a cast - maybe.

bye Jochen

Reply via email to