クラスにメソッドとフィールドを挿入する注釈プロセッサを作成しようとしています...ドキュメントは非常にまばらです。私は遠くに行っていませんし、正しく近づいているかどうかもわかりません。
処理環境は、Filer
新しいソース ファイルとクラス ファイルを作成するための便利なメソッドを持つオブジェクトを提供します。それらは正常に機能しますが、既存のソースファイルを読み取る方法を理解しようとしましたが、それが提供するのは「getResource」だけです。したがって、私の Processor 実装では、次のようにしました。
@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 の残りの部分は過剰に設計されていますが、元のソース コードを取得するための便利な方法はないようです。
本当の問題は、コンパイラが出力ディレクトリの 2 番目のソース ファイル (「エラー: クラスの重複」) によって自発的に動揺し、スタックしてしまうことです。
この残りの部分 (マクロ lexer とパーサー、および一部のデータを計算し、フィールド値とメソッドを挿入するためのもの) は既に作成しましたが、コンパイラの外部で最初のステップとして動作します。元のファイルに .java 拡張子を付けることができないという事実 (コンパイラがそれらを認識できないようにするため) を除いて、これはうまく機能します。それから、注釈がコード生成を行うことができると聞きました。これはより適切で便利であると思いますが、それに関するガイダンスはあまり見つかりません。