JCTree方法说明

环境

MacBook Pro
Java:1.8

前言

想弄懂抽象语法树,还得明白相关方法;

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

如何写新方法呢?
① 生成表达式 — 其实就是方法体的内容
例如:

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

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

② 生成方法体;

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

{
	this.name = name;
}

③ 生成入参

上例中就是String name

④ 生成返回值

上例中就是void

⑤ 生成最终方法

利用方法treeMaker.MethodDef就可以生成了;

treeMaker.MethodDef(
        treeMaker.Modifiers(Flags.PUBLIC), //访问标志
        names.fromString(""), //名字
        treeMaker.TypeIdent(TypeTag.VOID), //返回类型
        List.nil(), //泛型形参列表
        List.nil(), //参数列表
        List.nil(), //异常列表
        jcBlock, //方法体
        null //默认方法(可能是interface中的那个default)
);

其实通过MethodDef方法的参数,就知道我们需要干什么了;

TreeMaker

treeMaker.VarDef()

用于创建字段/变量定义语法树节点(JCVariableDecl);
源码:

public JCVariableDecl VarDef(JCModifiers mods,
						    Name name,
						    JCExpression vartype,
						    JCExpression init) {
    JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, (VarSymbol)null);
    tree.pos = this.pos;
    return tree;
}

例如:
在这里插入图片描述

treeMaker.VarDef(treeMaker.Modifiers(Flags.PARAMETER), // 访问标识
                jcVariableDecl.getName(), // 名称
                jcVariableDecl.vartype, // 类型
                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);
        }
    }

treeMaker.MethodDef()

创建一个方法定义 语法节点(JCMethodDecl),

treeMaker.MethodDef(
        treeMaker.Modifiers(Flags.PUBLIC), //访问标志
        names.fromString(""), //名字
        treeMaker.TypeIdent(TypeTag.VOID), //返回类型
        List.nil(), //泛型形参列表
        List.nil(), //参数列表
        List.nil(), //异常列表
        jcBlock, //方法体
        null //默认方法(可能是interface中的那个default)
);

JCClassDecl

类定义语法树节点

jcClassDecl.defs

能够得到 类中 所有的定义,如:变量、方法等;

我们自定义注解,想添加方法,就是通过下面这个方法来的:

jcClassDecl.defs.prepend()

其源码是:

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

参考地址:

https://liuyehcf.github.io/2018/02/02/Java-JSR-269-%E6%8F%92%E5%85%A5%E5%BC%8F%E6%B3%A8%E8%A7%A3%E5%A4%84%E7%90%86%E5%99%A8/

你可能感兴趣的:(Java)