groovyscriptingabstract-syntax-treegroovyscriptengine

Groovy: how to override time unit of @TimedInterrupt in an ASTTransformationCustomizer?


I'm using Groovy 4.0.2 as a runtime scripting environment for my application. My goal is to introduce timeout handling into user-provided scripts, but depending on what the script is used for, different timeouts should apply. My compiler configuration looks as follows:

var config = new CompilerConfiguration();
var extensions = new ArrayList<String>()
var timedInterruptParams = new HashMap<String, Object>()
// TimedInterrupt is an annotation with multiple parameters. We're only interested
// in the "value" and the "unit" parameters. For now, let's only set the "value"...
timedInterruptParams.put("value", myTimeout);

config.addCompilationCustomizers(
    new ASTTransformationCustomizer(CompileStatic.class),
    new ASTTransformationCustomizer(timedInterruptParams, TimedInterrupt.class)
);

The above configuration works, but it fixes the unit of the TimedInterrupt to its default (which is TimeUnit.SECONDS). I would like to overwrite this value in the timedInterruptParams map. However, none of the following works:

So... I'm running out of options here. Which value am I supposed to pass into the "unit" value of the parameter map?


Solution

  • It took quite a bit of digging, but the answer lied within TimedInterruptibleASTTransformation, the class which actually interprets the @TimedInterrupt annotation. There, the unit value was interpreted as follows:

    Expression unit = node.getMember('unit') ?: propX(classX(TimeUnit), 'SECONDS')
    

    ... and propX and classX are static helper methods from org.codehaus.groovy.ast.tools.GeneralUtils. With this information, it was relatively easy to make my code work. The line I was missing is:

    timedInterruptParams.put("unit", propX(classX(TimeUnit.class), TimeUnit.MILLISECONDS.toString()),
    

    It turns out that groovy interprets enum literals not as constants, but as properties of a class. This case sadly isn't covered by the auto-converter that applies to the object values of the parameter maps.