Search code examples
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

  • If the type checker is too strict for you have basically the options of reproducing partially or to extend the type checker. I do not advise the first option, it is a black hole for your development time... well unless you are really willing to invest a lot of time of course. The second option is described here: https://docs.groovy-lang.org/docs/groovy-4.0.22/html/documentation/#_type_checking_extensions Type checking extension not only allow dynamic code to pass static compilation by custom resolving, you can also make code dynamic.

    Actually there is a possible option 3. you can use @CompileDynamic on the methods you want the static type checker to ignore. But from your leader not allowing @CompileStatic I assume