Java code transform at compile time

前端 未结 4 1877
太阳男子
太阳男子 2020-12-24 13:10

I would like to transform java source code at compile time just before passing the source code to the compiler. In other word I would like

4条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-24 13:24

    Perhaps reconsider Spoon? It is intuitive once you know what an abstract syntax tree is. You basically navigate, filter and replace nodes on the AST representing your code until you have your desired transformation.

    If we have the following class:

    public class Test {
        Object method(){
            return "bla bla bla";
        }
    }
    

    a possible Spoon solution to your example would be:

    Launcher spoon = new Launcher();
    spoon.addInputResource("./src/main/java/Test.java");
    spoon.buildModel();
    CtClass ctClass = spoon.getModel().getRootPackage().getType("Test");
    CtLiteral match = ctClass.filterChildren((CtLiteral l) -> l.getType().getSimpleName().equals("String") && l.getValue().equals("bla bla bla")).first();
    Factory factory = spoon.getFactory();
    match.replace(factory.createCodeSnippetExpression("new MyClass(\"bla\", 3)"));
    System.out.println(ctClass);
    

    The first four lines build the Spoon model of the input program and retrieve the class element of interest.

    Next the literal to be modified is retrieved with a filter that returns the first and only literal of type name "String" and value "bla bla bla".

    Last the matched literal is replaced in the AST to the desired code snippet. The code snippet is automatically parsed from a string to a Spoon model using the code construction class Factory.

    When the class model is printed, the desired transformation is given:

    public class Test {
        java.lang.Object method() {
            return new MyClass("bla", 3);
        }
    }
    

提交回复
热议问题