如果java源调用带注释的方法,如何编写注释处理器以引发警告消息

时间:2012-11-02 19:36:55

标签: compilation annotations warnings processor

这是我在Java 6中的要求:我正在使用Eclipse JUNO。

  1. 使用自定义注释注释方法。
  2. 在编译期间,如果方法正在调用,则引发警告消息 注释方法。
  3. 我正在寻找类似@Deprecated注释的内容。

    这就是我所做的:

    1. 写了一个自定义注释。
    2. 写了一个注释处理器来读取和处理方法 注释。
    3. 创建一个jar并将其添加到注释处理器路径中。我的示例代码(见下文)在注释方法中引发警告消息。但这不是我的要求。

      我不能做的事情:

      1. 我无法获得调用方法。我想提出警告 这些调用方法中的消息。
      2. 我的示例代码:

        自定义注释:

        package tool.apichecks;
        
        import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;
        
        @Retention(RetentionPolicy.SOURCE)
        @Target({ ElementType.METHOD })
        public @interface HighCostMethod {
            String altMethod();
        }
        

        注释处理器:

            package tool.apichecks;
        
        import java.util.Set;
        
        import javax.annotation.processing.AbstractProcessor;
        import javax.annotation.processing.ProcessingEnvironment;
        import javax.annotation.processing.RoundEnvironment;
        import javax.annotation.processing.SupportedAnnotationTypes;
        import javax.lang.model.element.Element;
        import javax.lang.model.element.TypeElement;
        import javax.tools.Diagnostic.Kind;
        
        @SupportedAnnotationTypes({ "tool.apichecks.HighCostMethod" })
        public class MethodProcessor extends AbstractProcessor {
        
            private enum MethodType {
                HIGH_COST(HighCostMethod.class.getName());
        
                private String name;
        
                private MethodType(String name) {
                    this.name = name;
                }
        
                private static MethodType getMethodType(String name) {
                    MethodType methodType = null;
                    for (MethodType methodType2 : MethodType.values()) {
                        if (methodType2.name.equals(name)) {
                            methodType = methodType2;
                            break;
                        }
                    }
                    return methodType;
                }
            }
        
            private ProcessingEnvironment processingEnvironment;
        
            @Override
            public synchronized void init(ProcessingEnvironment processingEnvironment) {
                this.processingEnvironment = processingEnvironment;
            }
        
            @Override
            public boolean process(Set<? extends TypeElement> annotations,
                    RoundEnvironment roundEnvironment) {
                if (!roundEnvironment.processingOver()) {
                    for (TypeElement annotation : annotations) {
                        final Set<? extends Element> elements = roundEnvironment
                                .getElementsAnnotatedWith(annotation);
                        MethodType methodType = MethodType.getMethodType(annotation
                                .toString());
        
                        for (Element element : elements) {
                            switch (methodType) {
                            case HIGH_COST: {
                                processHighCostMethod(element);
                                break;
                            }
                            }
                        }
                    }
                }
                return true;
            }
        
            protected void processHighCostMethod(Element element) {
                HighCostMethod highCostMethod = element
                        .getAnnotation(HighCostMethod.class);
                /* TODO This warns the annotated method itself. I don't want this. I want to warn the methods that calls this method */
                processingEnvironment
                        .getMessager()
                        .printMessage(
                                Kind.WARNING,
                                String.format(
                                        "Do not use high cost method %s. Instead use %s method.",
                                        element, highCostMethod.altMethod()), element);
            }
        
        }
        

1 个答案:

答案 0 :(得分:0)

使用AnnotationProcessor只能处理包含注释或覆盖方法的文件,而不能处理调用方法。也许有一种解决方法,但是你可能会受到项目的限制,因为处理器一次只能查看一个项目。

我想你需要编写一个带有构建器的Eclipse插件,它可以分析所有文件中的代码并检查被称为注释的方法。 这比注释处理器要多得多,但你也有更多的选择。例如。您可以对错误标记实施快速修复。