javamavengroovyabstract-syntax-treegmavenplus

How to conduct Groovy compile-time error check, but without @TypeChecked or @CompileStatic?


A springboot gateway project, written with Groovy, i.e., all the Controller and Service are in *.groovy.

In fact, the code is totally java-style. Using groovy is only for hot update. So we don't need the dynamic feature of groovy.

But due to the dynamic feature of groovy, although there're some errors in code, the project can pass the compile stage and also can run. Error is not reported until the certain controller is called. Types of code error are simple, such as:

  1. Use an unexisted variable
  2. Call an unexisted method
  3. The declared type doesn't match the return type

Here is a demo:

service code

@Service
public class DemoServiceImpl implements DemoService {
    @Override
    public void serviceMethod() {
        System.out.println("hello");
    }
}

controller code

@RestController
public class DemoController {
    @Autowired
    private DemoService demoService;

    @RequestMapping("/path")
    public Integer controllerMethod() {

        // unexisted method in service
        demoService.serviceMethod222();

        char c = 'c';
        // unexisted variable in service
        System.out.println(c222);

        // declared type doesn't match return type
        int a = new Date();

        // return type also not match
        return "hahaha";
    }
}

Actually, the @TypeChecked or @CompileStatic can fully satisfy my need. However, my leader doesn't allow me to add the annotation to each class.

Now I'm thinking about using some maven plugin, but I don't have an idea.

I've hear about AST, and I'm tring to write a groovy script, such as:

AST script demo

@GroovyASTTransformation
class MyASTTransformation implements ASTTransformation {
    @Override
    void visit(ASTNode[] nodes, SourceUnit source) {
        
        // When I write this, can I see the error at compile?
        source.addError("should report error!")
    }
}

But I don't know how to make the script work when compiling, and what the script logic should be?

So my questions is:

  1. How to use the AST script? Now I'm using GMavenPlus plugin. May I configure the plugin to let AST script to be executed when compiling?
  2. What should the script logic be like? I'm sorry for my poor knowledge on compiling.

Solution

  • You can enable either by default in the compiler settings:

    Normally, classes in Groovy are compiled with a dynamic runtime. You can activate static compilation by placing an annotation named @CompileStatic on any class. Some people would like to have this mode activated by default, that is to say not having to annotate (potentially many) classes. Using configscript, makes this possible. First of all, you need to create a file named config.groovy into say src/conf with the following contents:

    withConfig(configuration) { 
       ast(groovy.transform.CompileStatic)
    }
    

    Source: https://docs.groovy-lang.org/docs/latest/html/documentation/#_configscript_example_static_compilation_by_default

    This describes the generic approach; the integration of the groovy compiler in build-tools usually comes with a way you can set this.

    On places, you don't want to use it, you can then opt-out by annotating with @CompileDynamic.