模块  java.compiler

Interface Processor

  • 所有已知实现类:
    AbstractProcessor

    public interface Processor
    注释处理器的接口。

    注释处理按照rounds的顺序进行。 在每一轮中,可以向处理器询问process在前一轮产生的源文件和类文件上找到的注释的子集。 第一轮处理的输入是工具运行的初始输入; 这些初始输入可以被视为虚拟第0轮处理的输出。 如果要求处理器在给定轮次上进行处理,则会要求处理后续轮次,包括最后一轮,即使没有要处理的注释。 工具基础结构还可以要求处理器处理由工具的操作隐式生成的文件。

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

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

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

    如果在圆形的根元素内包含的元素上存在至少一个该类型的注释,则认为注释类型存在。 为此,类型参数被视为由其generic element包围 为此, 考虑将package元素包含在该包中的顶级类型。 (处理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多个注释类型,这些注释类型位于不同的模块中。 要仅支持a.B模块中的Foo ,请改用"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 ,则注释类型无人认领,可能会要求后续处理器处理它们。 处理器可以总是返回相同的布尔值,或者可以根据其自己选择的标准改变结果。

        如果处理器支持"*"且根元素没有注释,则输入集将为空。 Processor必须正常处理一组空注释。

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

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

        由于未完成的程序正在建模,因此某些参数可能只有部分信息,或者可能是null elementuserText至少一个必须是非null 如果element是非nullannotationmember可能是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 - 要完成的源代码文本
        结果
        建议完成注释