[英]Java AST form annotation from String
我正在嘗試從包含其他注釋的內部字符串創建注釋。
這是應該處理的 SimpleAnnotation:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface SimpleAnnotation {
String[] value() default {};
}
這是帶注釋的類
@SimpleAnnotation({
"@com.demo.annotations.Entity(name = \"simple_name\")",
"@com.demo.annotations.CustomAnnotation"
})
public class Simple {
}
注解類的編譯結果應該是
@com.demo.annotations.Entity(name = "simple_name")
@com.demo.annotations.CustomAnnotation
public class Simple {
}
我嘗試使用處理類聲明的自定義注釋處理器。 它獲取帶有注釋的類修飾符並將派生的注釋分析為樹
public class SimpleAnnotationProcessor extends AbstractProcessor {
private Messager messager;
private Trees trees;
private ChangeTranslator visitor;
@Override
public Set<String> getSupportedAnnotationTypes() {
return Collections.singleton(SimpleAnnotation.class.getCanonicalName());
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.RELEASE_8;
}
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
............
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> elementsAnnotatedWith = roundEnv.getElementsAnnotatedWith(SimpleAnnotation.class);
for (Element element : elementsAnnotatedWith) {
Name simpleName = element.getSimpleName();
System.out.println(simpleName);
messager.printMessage(Diagnostic.Kind.NOTE, "found with annotation " + simpleName);
JCTree tree = (JCTree) trees.getTree(element);
visitor.setElement(element);
tree.accept(visitor);
}
return true;
}
public class ChangeTranslator extends TreeTranslator {
private JavacProcessingEnvironment javacProcessingEnvironment;
private TreeMaker treeMaker;
private Messager messager;
public ChangeTranslator(JavacProcessingEnvironment javacProcessingEnvironment, TreeMaker treeMaker, Messager messager) {
this.javacProcessingEnvironment = javacProcessingEnvironment;
this.treeMaker = treeMaker;
this.messager = messager;
}
@Override
public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
super.visitClassDef(jcClassDecl);
if (isNeedProcessing(jcClassDecl)) {
JCTree.JCModifiers modifiers = jcClassDecl.getModifiers();
List<JCTree.JCAnnotation> annotations = modifiers.getAnnotations();
List<JCTree.JCAnnotation> jcAnnotations = List.nil();
for (JCTree.JCAnnotation a : annotations) {
if (a.getAnnotationType().toString().contains(SimpleAnnotation.class.getSimpleName())) {
List<JCTree.JCExpression> arguments = a.getArguments();
for (JCTree.JCExpression arg : arguments) {
JCTree.JCNewArray expressions = (JCTree.JCNewArray) ((JCTree.JCAssign) arg).getExpression();
List<JCTree.JCExpression> elems = expressions.elems;
for (JCTree.JCExpression expression : elems) {
// parse annotation from string
String value = (String) ((JCTree.JCLiteral) expression).getValue();
// e.g com.demo.annotations.Entity
String substringName = value.trim().substring(1, 28);
Class<? extends Class> aClass = null;
try {
aClass = Class.forName(substringName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 1 - attribute to create annotation from
Attribute attribute = new Attribute.Compound(aClass, null);
// 2 - place where annotation should be created
treeMaker.Annotation(attribute);
}
}
}
}
modifiers.annotations = jcAnnotations;
System.out.println(result);
}
}
private boolean isNeedProcessing(JCTree.JCClassDecl jcClassDecl) {
return jcClassDecl.getModifiers().toString().contains("@SimpleAnnotation");
}
}
}
問題是從類類型中獲取信息以創建用於創建 JCAnnotation 的 com.sun.tools.javac.code.Type.ClassType。
任何幫助表示贊賞。
public class SimpleAnnotationProcessor extends AbstractProcessor {
...
@Override
public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
...
ListBuffer<JCTree.JCExpression> params = new ListBuffer<JCTree.JCExpression>();
params.append(treeMaker.Assign(treeMaker.Ident(names.fromString("name")), treeMaker.Literal("simple_name")));
JCTree.JCAnnotation entity = treeMaker.Annotation(select("com.demo.annotations.Entity"), params.toList());
JCTree.JCAnnotation customAnnotation = treeMaker.Annotation(select("com.demo.annotations.CustomAnnotation"), List.nil());
// then append annotation to modifiers of you want
// NOTE: List<A>.append() method will return a new List in javac
...
}
JCTree.JCExpression select(String path) {
JCTree.JCExpression expression = null;
int i = 0;
for (String split : path.split("\\.")) {
if (i == 0)
expression = treeMaker.Ident(names.fromString(split));
else {
expression = treeMaker.Select(expression, names.fromString(split));
}
i++;
}
return expression;
}
}
希望對遇到同樣問題的人有所幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.