Martin Häusler
Martin Häusler

Reputation: 7254

Embedded Groovy: How to use static type checking with external variables?

I want to embed Groovy to enable scripting capabilities in my Java application. I want to use static type checking, and in addition I want to pass some additional (global) variables to the script. Here is my configuration:

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

As you can see, the user-provided script uses the global variable name, which is injected via script.setBinding(...). Now there is a problem:

The question is: how do I solve this? How can I tell the type checker that the script will receive a global variable of a certain type when it is called?

Upvotes: 4

Views: 1196

Answers (1)

aristotll
aristotll

Reputation: 9177

From the doc, You can use extensions parameter,

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

Then add robotextension.groovy to your classpath:

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

Here, we’re telling the compiler that if an unresolved variable is found and that the name of the variable is name, then we can make sure that the type of this variable is String.

Upvotes: 1

Related Questions