Embedded Groovy: 如何对外部变量使用静态类型检查?
Embedded Groovy: How to use static type checking with external variables?
我想嵌入 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
。
问题是:我该如何解决?如何告诉类型检查器脚本在调用时会接收到某个类型的全局变量?
来自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
.
我想嵌入 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
。
问题是:我该如何解决?如何告诉类型检查器脚本在调用时会接收到某个类型的全局变量?
来自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
.