Module  java.compiler

Interface Processor

  • 所有已知实现类:
    AbstractProcessor


    public interface Processor
    注释处理器的界面。

    注释处理按rounds的顺序进行。 在每一轮中,可能会要求处理器process在上一轮产生的源文件和类文件上发现的注释的一个子集。 第一轮处理的输入是工具运行的初始输入; 这些初始输入可以被认为是虚拟第五轮处理的输出。 如果一个处理器被要求在给定的一轮进行处理,那么将被要求处理后续的回合,包括最后一轮,即使没有注释来处理它。 工具基础设施还可能要求处理器处理由工具操作隐含生成的文件。

    Processor每个实现Processor必须提供一个公共的无参数构造函数,供工具用来实例化处理器。 工具基础设施将与实现此接口的类进行交互,如下所示:

    1. 如果没有使用现有的Processor对象,要创建一个处理器的实例,该工具将调用处理器类的无参数构造函数。
    2. 接下来,该工具使用适当的ProcessingEnvironment调用init方法。
    3. 此后,工具调用getSupportedAnnotationTypesgetSupportedOptions ,并getSupportedSourceVersion 这些方法只能在每次运行时调用一次,而不是每轮调用。
    4. 适当时,该工具在Processor对象上调用process方法; 不会为每一轮创建一个新的Processor对象。
    如果在没有遵循上述协议的情况下创建和使用处理器对象,则该接口规范未定义处理器的行为。

    该工具使用发现过程来查找注释处理器并决定是否应该运行它们。 通过配置工具,可以控制一组潜在的处理器。 例如,对于JavaCompiler ,候选处理器的运行列表可以是set directly或由用于service-style查询的search path控制。 其他工具实现可能具有不同的配置机制,如命令行选项; 有关详细信息,请参阅特定工具的文档。 哪个处理器的工具要求runroot elements上的注释类型270729923870703 ,什么是annotation types a processor supports ,以及是否处理器claims the annotation types it processes 处理器将被要求处理其支持的注释类型的子集,可能是一个空集。 对于给定的一轮,该工具计算出在根元素中包含的元素上的注释类型集合。 如果存在至少一个注释类型,那么当处理器声明注释类型时,它们将从一组不匹配的注释类型中移除。 当该组为空或没有更多的处理器可用时,该轮已经运行完成。 如果没有注释类型,则注释处理仍然发生,但只有支持处理所有注释类型的通用处理器"*" )可以声明(空)注释类型集。

    如果存在于包含在一个回合的根元素内的元素上存在该类型的至少一个注释,则认为注释类型存在。 为此,一个类型参数被认为是由它的generic element包围 为此, 不会将包元素封装在该包中的顶级类型。 (当处理package-info文件时,将创建一个表示包的根元素。)同样,为此, 不会将模块元素封装在该模块中。 (当处理module-info文件时,会创建表示模块的根元素。)在计算是否存在注释类型时,将忽略type uses上的注释 ,而不是元素上的注释。

    如果符合AnnotatedConstruct给出的定义,则存在注释 简而言之,如果通过继承直接存在或存在,则认为出于发现的目的存在注释。 通过由容器注释包装,注释被认为是存在的。 在操作上,这相当于一个元素上存在的注释,当且仅当它被包含在该元素上调用的Elements.getAllAnnotationMirrors(Element)的结果中时。 由于容器注释中的注释不被认为是存在的,为了正确处理repeatable annotation types ,建议处理器将可重复的注释类型及其包含的注释类型同时包含在处理器的一组supported annotation types中。

    请注意,如果处理器支持"*"并返回true ,则会声明所有注释。 因此,用于例如实现附加有效性检查的通用处理器应该返回false ,以便不阻止其他这样的检查器能够运行。

    如果处理器引发未捕获的异常,则该工具可能会停止其他活动注释处理器。 如果处理器出现错误,则当前轮次将完成,后续轮次将显示为error was raised 由于注释处理器在协作环境中运行,所以处理器只能在没有错误恢复或报告可行的情况下抛出未捕获的异常。

    工具环境不需要支持以多线程方式访问环境资源的注释处理器( per roundcross-round)

    如果返回有关注解处理器的配置信息的方法返回null ,则返回其他无效输入或抛出异常,则工具基础结构必须将其视为错误条件。

    为了在不同的工具实现中运行时保持稳定,注释处理器应具有以下属性:

    1. 处理给定输入的结果不是存在或不存在其他输入(正交性)的函数。
    2. 处理相同的输入产生相同的输出(一致性)。
    3. 处理输入A后跟处理输入B相当于处理B然后A (交换)
    4. 处理输入并不依赖于其他注释处理器的输出(独立性)

    Filer接口讨论了处理器如何对文件进行操作的限制。

    API Note:
    该接口的实现者可能会发现扩展AbstractProcessor而不是直接实现该接口是方便的。
    从以下版本开始:
    1.6
    • 方法详细信息

      • getSupportedOptions

        Set<String> getSupportedOptions​()
        返回此处理器识别的选项。 处理工具的实现必须提供一种从处理器特定的选项中传递到工具本身的选项的方式,参见getOptions

        在集合中返回的每个字符串必须是一个周期分隔的序列identifiers

        SupportedOptionString:
        Identifiers
        Identifiers:
        Identifier
        Identifier . Identifiers
        Identifier:
        Syntactic identifier, including keywords and literals

        工具可能会使用这些信息来确定用户提供的任何选项是否被任何处理器无法识别,在这种情况下,它可能希望报告警告。

        结果
        此处理器识别的选项或空集合(如果没有)
        另请参见:
        SupportedOptions
      • getSupportedAnnotationTypes

        Set<String> getSupportedAnnotationTypes​()
        返回此处理器支持的注释类型的名称。 结果的元素可能是支持的注释类型的规范(完全限定)名称。 或者它可能是形式“的name.* ”代表了集中的所有注释类型的规范名称以“开头的name. ”。 在任何一种情况下,注释类型的名称可以前面加上一个模块名称,后跟一个"/"字符。 例如,如果处理器支持"a.B" ,则可以包括多个名为a.B注释类型,它们位于不同的模块中。 要在Foo模块中只支持a.B ,而是使用"Foo/a.B" 如果包含模块名称,则只匹配该模块中的注释。 特别地,如果在不支持模块的环境中给出模块名称,例如为没有模块的source version配置的注释处理环境,则具有模块名称的注释类型匹配。 最后, "*"本身表示所有注释类型的集合,包括空集合。 请注意,处理器不应要求"*"除非它实际上处理所有文件; 声称不必要的注释可能会导致某些环境中的性能下降。

        在集合中返回的每个字符串必须被以下语法接受:

        SupportedAnnotationTypeString:
        ModulePrefix opt TypeName DotStar opt
        *
        ModulePrefix:
        ModuleName /
        DotStar:
        . *
        其中TypeNameModuleNameThe Java™ Language Specification中所定义。
        API Note:
        当在支持模块的环境中运行时,鼓励处理器在描述支持的注释类型时包含模块前缀。 方法AbstractProcessor.getSupportedAnnotationTypes提供了在没有模块的环境中运行时剥离模块前缀的支持。
        结果
        该处理器支持的注释类型的名称
        另请参见:
        SupportedAnnotationTypes
        See The Java™ Language Specification:
        3.8标识符,6.5确定名称的含义
      • init

        void init​(ProcessingEnvironment processingEnv)
        使用处理环境初始化处理器。
        参数
        processingEnv - 工具框架为处理器提供的设施的环境
      • process

        boolean process​(Set<? extends TypeElement> annotations,
                        RoundEnvironment roundEnv)
        对来自前一轮的类型元素处理一组注释类型,并返回此处理器是否声明这些注释类型。 如果返回true ,则会声明注释类型,并且不会要求后续处理器处理它们; 如果返回false ,则注释类型是无人认领的,并且后处理器可能被要求处理它们。 处理器可以总是返回相同的布尔值,或者可以根据其自己选择的标准来改变结果。

        如果处理器支持"*"且根元素没有注释,输入集将为空。 A Processor必须优雅地处理一组空的注释。

        参数
        annotations - 请求处理的注释类型
        roundEnv - 有关当前和前一轮的信息的环境
        结果
        该处理器是否声明该组注释类型
      • getCompletions

        Iterable<? extends Completion> getCompletions​(Element element,
                                                      AnnotationMirror annotation,
                                                      ExecutableElement member,
                                                      String userText)
        返回到工具基础结构,可以对注释的建议完成进行迭代。 由于要求完成,关于注释提供的信息可能不完整,就像源代码片段一样。 处理器可能返回一个空的迭代。 注解处理器应集中努力于提供完井用于注释成员已知的处理器附加有效性约束,例如int构件,其值应在1和10或应用公知的语法来识别,诸如字符串构件之间位于正则表达式或URL。

        由于不完整的程序被建模,一些参数可能只有部分信息,或可能是null elementuserText至少一个必须是非null 如果element是非null ,则annotationmember可以是null 处理器可能不会抛出NullPointerException如果某些参数是null ; 如果处理器根据提供的信息没有提供完成,则可以返回空的迭代。 处理器还可以使用空值字符串返回单个完成,并且描述为什么没有完成。

        完成信息丰富,并可能反映注释处理器执行的其他有效性检查。 例如,考虑简单的注释:

         @MersennePrime {
            int value();
         }
         
        (A Mersenne素数是素数的形式的2 N - 1)给定一个AnnotationMirror此注释类型,在所有这样的素数的列表int范围而不检查任何其他参数可以返回getCompletions
         import static javax.annotation.processing.Completions.*;
         ...
         return Arrays.asList(of("3"),
                              of("7"),
                              of("31"),
                              of("127"),
                              of("8191"),
                              of("131071"),
                              of("524287"),
                              of("2147483647"));
         
        一整套完整的数据将包括每个素材的数量:
         return Arrays.asList(of("3",          "M2"),
                              of("7",          "M3"),
                              of("31",         "M5"),
                              of("127",        "M7"),
                              of("8191",       "M13"),
                              of("131071",     "M17"),
                              of("524287",     "M19"),
                              of("2147483647", "M31"));
         
        但是,如果userText可用,则可以检查是否只有Mersenne素数的一个子集是有效的。 例如,如果用户键入
        @MersennePrime(1
        价值userText将为"1" ; 只有两个素数是可能的完成:
         return Arrays.asList(of("127",        "M7"),
                              of("131071",     "M17"));
         
        有时没有有效的完成是可能的。 例如,从9开始,没有范围内的梅森素食
        @MersennePrime(9
        在这种情况下,适当的回应是返回一个空的完成列表,
         return Collections.emptyList();
         
        或一个空的完成与一个有用的消息
         return Arrays.asList(of("", "No in-range Mersenne primes start with 9"));
         
        参数
        element - 要注释的元素
        annotation - (可能是部分的)注释被应用于元素
        member - 注释成员返回可能的完成
        userText - 要完成的源代码文本
        结果
        建议完成注释