字符串中的Java AST表单注释

时间:2018-07-26 18:59:33

标签: java annotations abstract-syntax-tree

我正在尝试从包含其他注释的内部字符串创建注释。

这是应该处理的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");
        }

    }
}

问题是要从“类”类型中获取信息,以创建用于创建JCA注释的com.sun.tools.javac.code.Type.ClassType。

感谢您的帮助。

0 个答案:

没有答案