簡體   English   中英

來自 String 的 Java AST 表單注釋

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM