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
方法的参数,就知道我们需要干什么了;
用于创建字段/变量定义
语法树节点(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) // 初始化语句
创建 返回值类型
语法节点 (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);
}
}
创建一个方法定义 语法节点(JCMethodDecl
),
treeMaker.MethodDef(
treeMaker.Modifiers(Flags.PUBLIC), //访问标志
names.fromString("" ), //名字
treeMaker.TypeIdent(TypeTag.VOID), //返回类型
List.nil(), //泛型形参列表
List.nil(), //参数列表
List.nil(), //异常列表
jcBlock, //方法体
null //默认方法(可能是interface中的那个default)
);
类定义
语法树节点
能够得到 类中 所有的定义,如:变量、方法等;
我们自定义注解,想添加方法,就是通过下面这个方法来的:
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/