后面有些凭空出现的变量可以从这找类型和获取方式:
JavacTrees trees = JavacTrees.instance(processingEnv);
Context context = ((JavacProcessingEnvironment)processingEnv).getContext();
TreeMaker treeMaker = TreeMaker.instance(context);
Names names = Names.instance(context);
JCTree jcTree = trees.getTree(element);
JCTree.JCCompilationUnit imports = (JCTree.JCCompilationUnit) trees.getPath(element).getCompilationUnit();
后面无论加接口还是加注解,都需要先导包:
JCTree.JCCompilationUnit imports = (JCTree.JCCompilationUnit) trees.getPath(element).getCompilationUnit();
imports.defs = imports.defs.append(
treeMaker.Import(
treeMaker.Select(
treeMaker.Ident(names.fromString("cn.lzxz1234.somepackage")),
names.fromString("ClassName")),
false)
);
类添加继承序列化接口等操作
JCClassDecl var1 = xxxx;
var1.implementing = var1.implementing.append(treeMaker.Ident(names.fromString("Serializable")));
类声明的前面添加 @Service
@Compoent
等各种类型的各种注解:
JCClassDecl var1 = xxxx;
var1.mods.annotations = var1.mods.annotations.append(treeMaker.Annotation(
treeMaker.Ident(names.fromString("Api")),
List.nil()
));
当前类上可能已经有注解了,如 @Api(version=1.0),要取 version 的值 1.0 那么可以通过 k.mods.annotations 过滤找到 JCAssign 然后取 rhs 的值即可:
JCVariableDecl decl = xxxx;
decl.mods.annotations.stream()
.filter(k -> k.annotationType.toString().contains("Api"))
.flatMap(k -> k.args.stream())
.forEach(k -> {
if(k.getKind().equals(Kind.ASSIGNMENT)) {
JCAssign assign = (JCAssign)k;
if(assign.lhs.getKind().equals(Kind.IDENTIFIER) && (((JCIdent)assign.lhs).name).toString().equals("version")) {
double version = (double)(((JCLiteral)assign.rhs).value);
}
}
});
主要用于判断成员变量是不是静态的或者 final 的之类的
JCVariableDecl k;
k.mods.getFlags().contains(Modifier.STATIC);
k.mods.getFlags().contains(Modifier.FINAL);
基本的类型判断和是否已经存在注解就跳过了,直接展示操作:
JCVariableDecl decl = xxxx;
decl.mods.annotations = decl.mods.annotations.append(
treeMaker.Annotation(
treeMaker.Ident(names.fromString("Api")),
List.of(treeMaker.Assign(treeMaker.Ident(names.fromString("version")),
treeMaker.Literal(sortId.incrementAndGet())))
)
);