JCTree、TreeMaker的使用

一、JCTree的使用

想要利用自定义注解写方法,就是在重载方法visitClassDef中,利用jcClassDecl.defs.prepend(),把新方法加入到源代码中。

1.如何写新方法呢?

1.生成表达式 — 其实就是方法体的内容
例如:

1 public void getPerson(String name) {
2 this.name = name;
3 }

例子中,this.name = name;就是表达式;

2.生成方法体;

就是在生成表达式的基础上,把{ }补上;

{
  this.name = name;
}

3.生成入参

上例中就是String name

4.生成返回值

上例中就是void;

5. 生成最终方法

利用方法treeMaker.MethodDef就可以生成了一个新的方法。

treeMaker.MethodDef(
        treeMaker.Modifiers(Flags.PUBLIC), //访问标志
        names.fromString("<init>"), //方法名字
        treeMaker.TypeIdent(TypeTag.VOID), //返回类型
        List.nil(), //泛型形参列表
        List.nil(), //参数列表
        List.nil(), //异常列表
        jcBlock, //方法体
        null //默认方法
);

二、TreeMaker的使用

treeMaker.VarDef()用于创建字段/变量定义语法树节点(JCVariableDecl);

1 public JCVariableDecl VarDef(JCModifiers mods,
2                             Name name,
3                             JCExpression vartype,
4                             JCExpression init) {
5     JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, (VarSymbol)null);
6     tree.pos = this.pos;
7     return tree;
8 }
1 treeMaker.VarDef(treeMaker.Modifiers(Flags.PARAMETER), // 访问标识
2                 jcVariableDecl.getName(), // 名称
3                 jcVariableDecl.vartype, // 类型
4                 null) // 初始化语句

treeMaker.Type() 返回值类型:语法节点 (JCExpression

public JCExpression Type(Type var1) {
        if (var1 == null) {
            return null;
        } else {
            Object var2;
            switch(var1.getTag()) {
            case BYTE:
            case CHAR:
            case SHORT:
            case INT:
            case LONG:
            case FLOAT:
            case DOUBLE:
            case BOOLEAN:
            case VOID:
                var2 = this.TypeIdent(var1.getTag());
                break;
            case TYPEVAR:
                var2 = this.Ident((Symbol)var1.tsym);
                break;
            case WILDCARD:
                WildcardType var5 = (WildcardType)var1;
                var2 = this.Wildcard(this.TypeBoundKind(var5.kind), this.Type(var5.type));
                break;
            case CLASS:
                Type var3 = var1.getEnclosingType();
                JCExpression var4 = var3.hasTag(TypeTag.CLASS) && var1.tsym.owner.kind == 2 ? this.Select(this.Type(var3), (Symbol)var1.tsym) : this.QualIdent(var1.tsym);
                var2 = var1.getTypeArguments().isEmpty() ? var4 : this.TypeApply(var4, this.Types(var1.getTypeArguments()));
                break;
            case ARRAY:
                var2 = this.TypeArray(this.Type(this.types.elemtype(var1)));
                break;
            case ERROR:
                var2 = this.TypeIdent(TypeTag.ERROR);
                break;
            default:
                throw new AssertionError("unexpected type: " + var1);
            }

            return ((JCExpression)var2).setType(var1);
        }
    }

jcClassDecl.defs能够得到类中所有的定义,如:变量、方法等;我们自定义注解,想添加方法,就是通过下面这个方法来的:

jcClassDecl.defs.prepend()

//源码:
public List<A> append(A var1) {
    return of(var1).prependList(this);
}

 

posted @ 2021-12-28 16:16  jkbolck  阅读(1783)  评论(0)    收藏  举报