嵌入式Groovy:如何使用外部变量进行静态类型检查?

时间:2017-08-09 15:19:23

标签: java groovy scripting typechecking

我想嵌入Groovy以在我的Java应用程序中启用脚本功能。我想使用静态类型检查,另外我想将一些额外的(全局)变量传递给脚本。这是我的配置:

    String script = "println(name)";  // this script was entered by the user

    // compiler configuration for static type checking
    CompilerConfiguration config = new CompilerConfiguration();
    config.addCompilationCustomizers(new ASTTransformationCustomizer(CompileStatic.class));

    // compile the script
    GroovyShell shell = new GroovyShell(config);
    Script script = shell.parse(script);

    // later, when we actually need to execute it...
    Binding binding = new Binding();
    binding.setVariable("name", "John");
    script.setBinding(binding);
    script.run();

如您所见,用户提供的脚本使用全局变量name,该变量通过script.setBinding(...)注入。现在有一个问题:

  • 如果我在用户脚本中声明变量name(例如String name;),则绑定无效,因为该变量已存在于脚本中。
  • 如果我没有在脚本中声明变量,静态类型检查器将(正当地)抱怨name未被声明。

问题是:我该如何解决这个问题?如何告诉类型检查器脚本在调用时会收到某种类型的全局变量?

1 个答案:

答案 0 :(得分:1)

来自doc, 您可以使用extensions参数

config.addCompilationCustomizers(
    new ASTTransformationCustomizer(
        TypeChecked,
        extensions:['robotextension.groovy'])
)

然后将 robotextension.groovy 添加到您的类路径中:

unresolvedVariable { var ->
    if ('name'==var.name) {
        storeType(var, classNodeFor(String))
        handled = true
    }
}

在这里,我们告诉编译器,如果找到未解析的变量并且变量的名称是 name ,那么我们可以确保该类型这个变量是String