我正在尝试编写一个注解处理器,在类上插入方法和字段...但文档很匮乏。我没有进展,也不知道我是否正确地接近它。
处理环境提供了一个Filer
对象,其中有方便的方法来创建新的源代码和类文件。这些方法很好用,但是我试图弄清楚如何读取现有的源代码文件,它只提供了“getResource”。因此,在我的处理器实现中,我已经这样做:
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
try {
for (TypeElement te : annotations) {
for (Element element : roundEnv.getElementsAnnotatedWith(te)) {
FileObject in_file = processingEnv.getFiler().getResource(
StandardLocation.SOURCE_PATH, "",
element.asType().toString().replace(".", "/") + ".java");
FileObject out_file = processingEnv.getFiler().getResource(
StandardLocation.SOURCE_OUTPUT, "",
element.asType().toString().replace(".", "/") + ".java");
//if (out_file.getLastModified() >= in_file.getLastModified()) continue;
CharSequence data = in_file.getCharContent(false);
data = transform(data); // run the macro processor
JavaFileObject out_file2 = processingEnv.getFiler().createSourceFile(
element.asType().toString(), element);
Writer w = out_file2.openWriter();
w.append(data);
w.close();
}
}
} catch (Exception e) {
e.printStackTrace();
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());
}
return true;
}
我的第一个难题是我无法摆脱这种感觉:element.asType().toString().replace(".", "/") + ".java"
(获取限定类型名称并将其转换为包和源文件路径)不是解决问题的好方法。 API 的其余部分都过度设计,但似乎没有方便的方法来检索原始源代码。
真正的问题是编译器会因为输出目录中的第二个源文件而自动出现问题(“错误:重复的类”),现在我陷入了困境。
我已经写了其余部分 - 宏 lexer 和 parser 以及计算一些数据并插入字段值和方法的等等,但它作为初始步骤在编译器之外运行。除了原始文件不能具有 .java 扩展名(以防止编译器看到它们)之外,这很好地工作。然后我听说注释可以进行代码生成,我假设这会更加恰当和方便,但我找不到太多关于它的指导。