Groovy:如何在ASTTransformationCustomizer中覆盖@TimedInterrupt时间单位?

niknxzdl  于 2022-11-01  发布在  其他
关注(0)|答案(1)|浏览(170)

我使用Groovy 4.0.2作为我的应用程序的运行时脚本环境。我的目标是在用户提供的脚本中引入超时处理,但是根据脚本的用途,应该应用不同的超时。我的编译器配置如下所示:

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)
);

上面的配置可以工作,但是它将TimedInterruptunit固定为默认值(即TimeUnit.SECONDS)。我想在timedInterruptParamsMap中覆盖这个值。但是,下面的配置都不起作用:

  • timedInterruptParams.put("unit", TimeUnit.MILLISECONDS)

在脚本编译期间产生错误,声称MILLISECONDS不是支持的常量表达式。

  • timedInterruptParams.put("unit", new ConstantExpression(TimeUnit.MILLISECONDS)

同上

  • timedInterruptParams.put("unit", "MILLISECONDS")

导致Groovy编译器完全错误,并显示“不应调用此方法”。

  • timedInterruptParams.put("unit", "java.util.concurrent.TimeUnit.MILLISECONDS")

同上
所以......我的选项已经用完了,我应该把哪个值传递给参数map的"unit"值呢?

fxnxkyjh

fxnxkyjh1#

我们花了很多时间去挖掘,但答案就在TimedInterruptibleASTTransformation中,这个类实际上解释了@TimedInterrupt注解,其中unit值被解释为:

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

......而propXclassX是来自org.codehaus.groovy.ast.tools.GeneralUtils的静态helper方法。有了这些信息,让我的代码工作起来就相对容易了。我遗漏的代码行是:

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

事实证明,groovy并不将枚举字面量解释为常量,而是将其解释为类的属性。遗憾的是,应用于参数Map的对象值的自动转换器并没有涵盖这种情况。

相关问题