我编写了一个
AnnotationProcessor
,它扫描代码中的某个注释并从中生成一个 Java 类。
它基本上做了这样的事情:
private Multimap<String, Element> elements;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(Factory.class)) {
elements.put(annotatedElement.getSimpleName());
}
generateCode(elements);
}
以防万一它很重要:
generateCode()
将迭代elements
(这是一个多重映射),并为每个键创建一个类(键+后缀是我想要生成的文件的名称),并使用根据元素列表的信息创建的代码(与 key 关联的某个 key 的 multimap 的值。
显然我会在每轮注释处理时调用
generateCode()
。因此,我会收到一个编译错误,表明在上一轮中已经生成了同名文件。
正确的处理方法是什么?我认为收集所有注释并仅在最后一轮生成类是个好主意,如下所示:
private Multimap<String, Element> elements;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(Factory.class)) {
elements.put(annotatedElement.getSimpleName());
}
if (roundEnv.processingOver()){
generateCode(elements);
}
}
这解决了多次生成相同文件的问题,但现在我收到以下警告:
警告:java:上一轮创建的类型为[生成的java文件的路径]的文件将不会进行注释处理。
javadoc 指出您不应该在上一轮中生成代码。 我应该什么时候生成我的文件?
此外,如果我单击重建项目,我也会在 IntelliJ 14 中收到此警告: 警告:输出路径 [生成的 java 文件的路径] 与源根目录相交。只有由构建创建的文件才会被清理。
如果您为每个密钥生成单个文件,我想您只需将代码重写为如下所示:
警告: 伪代码
private Multimap<String, Element> elements;
private Set<String> files = new HashSet<String>();
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(Factory.class)) {
elements.put(annotatedElement.getSimpleName());
}
for (Element e : elements) {
String file = resolveFile(e);
if (files.contains(file)) continue;
generateCodeForFile(file, e);
files.add(file);
}
}