我正在嘗試編寫一個annotation processor以在類上插入方法和字段...並且文檔非常稀疏。我沒有走得太遠,我不知道我是否正確接近它。使用註釋處理器替換代碼
處理環境提供了一個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的其餘部分過於工程化,但似乎沒有一種方便的方法來檢索原始源代碼。
真正的問題是編譯器會在輸出目錄中的第二個源文件(「error:duplicate class」)中自發地產生不滿,現在我被卡住了。
我已經編寫了剩下的這部分 - 一個宏詞法分析器和解析器,以及用於計算某些數據和插入字段值和方法的東西 - 但它作爲編譯器之外的初始步驟運行。除了原始文件不能具有.java擴展名(以防止編譯器看到它們)之外,這很好地工作。然後我聽說註釋可以做代碼生成,我認爲它會更加正確和方便,但是我找不到很多指導。
請參閱:http://techbitsfromsridhar.blogspot.ca/2013/02/java-compiler-plug-ins-in-java-8-use.html –