Boa*_*ann 20 java code-generation annotation-processing
我正在尝试编写一个注释处理器来在类上插入方法和字段......而且文档非常稀疏.我没有走得太远,我不知道我是否正确接近它.
处理环境提供了一个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;
}
Run Code Online (Sandbox Code Playgroud)
我的第一个窘境是我不禁感到element.asType().toString().replace(".", "/") + ".java"(获取合格的类型名称并将其转换为包和源文件路径)并不是解决问题的好方法.API的其余部分是如此过度设计,但似乎没有一个方便的方法来检索原始源代码.
真正的问题是,然后编译器会被输出目录中的第二个源文件("错误:重复类")自发地打乱,现在我被卡住了.
我已经编写了其余部分 - 宏词法分析器和解析器以及用于计算某些数据和插入字段值和方法的内容 - 但它作为编译器之外的第一步操作.除了原始文件不能具有.java扩展名(以防止编译器看到它们)之外,这很好用.然后我听说注释可以做代码生成,我认为它会更合适和方便,但我找不到很多指导.
Joh*_*sen 19
注释处理器背后的意图是允许开发人员添加新类,而不是替换现有类.话虽这么说,但是有一个错误允许您向现有类添加代码. 龙目岛项目已利用这getter和setter(除其他事项外)添加到您的编译的Java类.
我用来'替换'方法/字段的方法是从输入类扩展或委托给输入类.这允许您覆盖/转移对目标类的调用.
所以如果这是你的输入类:
InputImpl.java:
public class InputImpl implmements Input{
public void foo(){
System.out.println("foo");
}
public void bar(){
System.out.println("bar");
}
}
Run Code Online (Sandbox Code Playgroud)
您可以生成以下内容来"替换"它:
InputReplacementImpl.java:
public class InputReplacementImpl implmements Input{
private Input delegate;
//setup delegate....
public void foo(){
System.out.println("foo replacement");
}
public void bar(){
delegate.bar();
}
}
Run Code Online (Sandbox Code Playgroud)
这引出了一个问题,你如何引用InputReplacementImpl而不是InputImpl.您可以生成更多代码来执行包装,也可以只调用期望生成的代码的构造函数.
我不确定你的问题是什么,但我希望这会对你的问题有所了解.