public interface Processor
注释 Processor 的接口。
注释处理是按照 round 的顺序进行的。在每次进行 round 操作时,都会请求 Processor 处理在前一个处理轮次生成的源文件和类文件上找到的注释子集。第一轮次处理的输入是工具运行的初始输入值;这些初始输入值可视为虚拟的第 0 轮次处理的输出。如果请求 Processor 在给定轮次上进行处理,那么它将被要求处理后续轮次,包括最后的轮次,即使没有要处理的注释也一样。工具框架可能还会请求 Processor 处理由工具的操作隐式生成的文件。
Processor
的每次实现都必须提供一个公共的无参数构造方法,工具将使用该构造方法实例化 Processor。工具框架将与实现此接口的类交互,如下所示:
Processor
对象,若要创建 Processor 实例,则工具将调用 Processor 类的无参数构造方法。 ProcessingEnvironment
的 init
方法。 getSupportedAnnotationTypes
、getSupportedOptions
和 getSupportedSourceVersion
。这些方法只在每次运行时调用一次,并非对每个处理轮次调用。 Processor
对象上调用 process
方法;无需 为每个处理轮次创建新的 Processor
对象。 该工具使用一个搜索过程 来查找注释 Processor,并确定是否应该运行它们。通过配置该工具,可以控制潜在的 Processor 集合。例如,对于 JavaCompiler
,要运行的候选 Processor 列表可以是直接设置的,也可以是通过用于服务样式查找的搜索路径所控制的 Processor 列表。其他工具实现可能有不同的配置机制,比如命令行选项;有关详细信息,请参考特定工具的文档。工具请求运行哪一个 Processor 取决于根元素上出现哪些注释、Processor 处理哪些注释类型以及 Processor 是否声明它所处理的注释。Processor 将被要求处理它所支持的注释类型的子集,该集合可能是一个空集。 对于给定的 round,工具计算根元素上的注释类型集。如果至少存在一个注释类型,那么当 Processor 声明注释类型时,将从不匹配的注释集移除它们。当该集合为空或者没有更多 Processor 可用时,round 将运行完成。如果不存在注释类型,注释处理仍然会发生,但只有支持处理 "*"
的通用 Processor 可以声明(空)注释类型集。
注意,如果 Processor 支持 "*"
并返回 true
,则声明所有注释。因此,通用 Processor(例如,用来实现其他有效性检查的通用 Processor)应该返回 false
,以便允许运行其他这类检查器。
如果 Processor 抛出一个未捕获的异常,那么工具可能停止其他活动的注释 Processor。如果某一 Processor 产生错误,那么当前 round 将运行完成,并且后续 round 将指示产生了错误。因为注释 Processor 是在协作环境下运行的,所以 Processor 只在错误恢复和报告都不可行的情况下才会抛出一个未捕获的异常。
不要求工具环境支持以多线程方式访问环境资源(每个 round 或跨 round)的注释 Processor。
如果返回有关注释 Processor 配置信息的方法返回 null
、返回其他无效输入,或者抛出一个异常,则工具框架必须将此视为一种错误状态。
为了可靠起见,当在不同工具实现中运行时,注释 Processor 应该具有以下属性:
Filer
接口讨论了关于 Processor 如何在文件上进行操作的限制。
注意,此接口的实现者可能会发现扩展 AbstractProcessor
比直接实现此接口更便捷。
方法摘要 | |
---|---|
Iterable<? extends Completion> |
getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) 向工具框架返回某一注释的建议 completion 迭代。 |
Set<String> |
getSupportedAnnotationTypes() 返回此 Processor 支持的注释类型的名称。 |
Set<String> |
getSupportedOptions() 返回此 Processor 识别的选项。 |
SourceVersion |
getSupportedSourceVersion() 返回此注释 Processor 支持的最新的源版本。 |
void |
init(ProcessingEnvironment processingEnv) 用处理环境初始化 Processor。 |
boolean |
process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) 处理先前 round 产生的类型元素上的注释类型集,并返回这些注释是否由此 Processor 声明。 |
方法详细信息 |
---|
Set<String> getSupportedOptions()
getOptions
。
集合中返回的每个字符串都必须是句点分隔的标识符序列:
- SupportedOptionString:
- 标识符
- 标识符:
- 标识符
- 标识符
.
标识符
- 标识符:
- 语法标识符,包括关键字和字面值
工具可以使用此信息来确定用户提供的任意选项是否无法被任何 Processor 识别,在这种情况下,可能希望它报告警报。
SupportedOptions
Set<String> getSupportedAnnotationTypes()
"*"
自身表示所有注释类型的集合,包括空集。注意,Processor 不应声明
"*"
,除非它实际处理了所有文件;声明不必要的注释可能导致在某些环境中的性能下降。
集合中返回的每个字符串必须符合以下语法:
其中 TypeName 在 Java 语言规范 中定义。
- SupportedAnnotationTypeString:
- TypeName DotStar opt
- *
- DotStar:
- . *
SupportedAnnotationTypes
SourceVersion getSupportedSourceVersion()
SupportedSourceVersion
,
ProcessingEnvironment.getSourceVersion()
void init(ProcessingEnvironment processingEnv)
processingEnv
- 工具框架提供给 Processor 的设施的环境
boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
true
,则这些注释已声明并且不要求后续 Processor 处理它们;如果返回
false
,则这些注释未声明并且可能要求后续 Processor 处理它们。Processor 可能总是返回相同的 boolean 值,或者可能基于所选择的标准而返回不同的结果。
如果 Processor 支持 "*"
并且根元素没有注释,则输入集合将为空。Processor
必须妥善处理空注释集。
annotations
- 请求处理的注释类型
roundEnv
- 有关当前和以前 round 的信息的环境
Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText)
int
成员,或者应该由已知语法识别的字符串成员,比如正则表达式或者 URL。
因为将为不完整的程序建立模型,所以某些参数可能只有部分信息,或者可能为 null
。element
和 userText
中必须至少有一个不为 null
。如果 element
不为 null
,则 annotation
和 member
可以为 null
。如果某些参数为 null
,Processor 可能不会抛出 NullPointerException
;如果 Processor 基于所提供的信息不提供 completion,则可能返回一个空迭代。Processor 也可能返回一个具有空值字符串的单个 completion,以及描述不提供 completion 的原因的消息。
completion 包含许多信息,它可以反映注释 Processor 执行的其他有效性检查。例如,考虑以下简单注释:
(素数 Mersenne 是 2 n - 1 形式的素数。)如果给定此注释类型的@MersennePrime { int value(); }
AnnotationMirror
,则可以返回
int
范围内所有这类素数的列表,而无需检查
getCompletions
的其他任何参数:
包含更多信息的 completion 集合还包括每个素数的数量: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"
;并且只有两个素数可能是 completion:
有时可能不是有效的 completion。例如,范围内没有以 9 开头的 Mersenne 素数:return Arrays.asList(of("127", "M7"), of("131071", "M17"));
@MersennePrime(9
在这种情况下,适当的响应是返回一个空的 completion 列表,
或者返回一个包含帮助消息的单个空 completionreturn Collections.emptyList();
return Arrays.asList(of("", "No in-range Mersenne primes start with 9"));
element
- 将被注释的元素
annotation
- 将应用于元素的注释(可能是一部分)
member
- 为其返回可能 completion 的注释成员
userText
- 将补充完整的源代码文本