如何使用Java编译器插件编写setter方法?

问题描述

我最近发现了这个演示demonstration,该示例使用Java编译器插件界面为getter方法注入样板。

所以我也很简洁地编写了一个setter方法

并且我在尝试初始化参数时从编译器获取AssertionError。

赋值语句总是产生NullPointerException。

这是createSetter方法

private JCTree.JcmethodDecl createSetter(JCTree.JCVariableDecl jcVarDecl) {
    String name = jcVarDecl.getName().toString();
    JCTree.JCIdent varIdent = treeMaker.Ident(jcVarDecl.getName());
    
    String camelCasedParamName = "p" + Character.toupperCase(name.charat(0)) + name.substring(1);
    Name methodName = names.fromString("set" + camelCasedParamName.substring(1));
    
    JCTree.JCVariableDecl paramVarDecl = treeMaker.VarDef(treeMaker.Modifiers(Flags.ParaMETER),names.fromString(camelCasedParamName),jcVarDecl.vartype,null);
    JCTree.JCIdent paramIdent = treeMaker.Ident(paramVarDecl.getName());
//      Assignment statement triggers NullPointerException  
//      JCTree.JCStatement assign = treeMaker.Assignment(varIdent.sym,paramIdent);
//      JCTree.JCBlock methodBody = treeMaker.Block(0,List.of(assign));
//
    JCTree.JCBlock methodBody = treeMaker.Block(0,List.nil());
    
    return treeMaker.MethodDef(
            treeMaker.Modifiers(Flags.PUBLIC),methodName,treeMaker.TypeIdent(TypeTag.VOID),List.nil(),List.of(paramVarDecl),methodBody,null
    );
}

插件的完整来源为here on github

除了this之外,我还没有找到关于Javac内部API的任何好的文档。 如果您知道一些好的资源,请参考。

这是一个简单的用法类Person

import noman.main.annotations.Setter;

public class Person {

    @Setter
    private String name;

    @Setter
    private int age;

    @Setter
    private String address;

    public Person(String name,int age,String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

}

使用 javac -Xplugin:GetterSetter -cp路径/至/plugin.jar路径/至/Person.java

这是编译器的输出错误

==============================无需分配的输出========= ============================

Before:
package Chapter_12_Codes.Annotation.plugin;

import noman.main.annotations.Setter;

public class Person {
    @Setter()
    private String name;
    @Setter()
    private int age;
    @Setter()
    private String address;

    public Person(String name,String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

After:
package Chapter_12_Codes.Annotation.plugin;

import noman.main.annotations.Setter;

public class Person {
    @Setter()
    private String name;
    @Setter()
    private int age;
    @Setter()
    private String address;

    public Person(String name,String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public void setName(String pName) {
    }

    public void setAge(int pAge) {
    }

    public void setAddress(String pAddress) {
    }
}

An exception has occurred in the compiler (11.0.8). Please file a bug against the Java compiler via the Java bug reporting page (http
://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following
diagnostic in your report. Thank you.
java.lang.AssertionError
        at jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155)
        at jdk.compiler/com.sun.tools.javac.util.Assert.check(Assert.java:46)
        at jdk.compiler/com.sun.tools.javac.util.Bits.incl(Bits.java:186)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$AssignAnalyzer.initParam(Flow.java:1933)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitMethodDef(Flow.java:1882)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JcmethodDecl.accept(JCTree.java:866)
        at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:398)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1453)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitClassDef(Flow.java:1824)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JcclassDecl.accept(JCTree.java:774)
        at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:398)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1453)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:2510)
        at jdk.compiler/com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:2493)
        at jdk.compiler/com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:217)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1401)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1375)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:973)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:311)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:170)
        at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:57)
        at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:43)

在对AST类进行注入之后,编译器将报告错误

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)