Ist es möglich, innerhalb von javac.exe programmgesteuert auf den Abstract Syntax Tree (AST) zuzugreifen? Können Sie ein Beispiel geben?javac.exe Beispiel für programmgesteuerten Zugriff auf AST
Antwort
Ja, es ist möglich, aber nur seit Java 6. Peter von der Ahé spricht über die beiden JSRs in this interview. JSR 199:
Die JSR 199 Compiler-API besteht aus drei Dingen: Der erste ermöglicht es Ihnen grundsätzlich, einen Compiler über die API aufzurufen. Zweitens können Sie mit der API anpassen, wie der Compiler Dateien findet und ausschreibt. Ich meine Dateien im abstrakten Sinne, da die Dateien, mit denen der Compiler zu tun hat, nicht unbedingt auf dem Dateisystem liegen. Mit der Dateiabstraktion von JSR 199 können Sie Dateien in einer Datenbank speichern und beispielsweise direkt in den Speicher ausgeben. Schließlich können Sie mit der JSR 199-API strukturierte Diagnosen aus dem Compiler sammeln, so dass Sie beispielsweise Fehlermeldungen problemlos in Zeilen im IDE-Editor umwandeln können.
JSR 269 ist die Annotationsverarbeitungs-API.
This article gibt einen hervorragenden Überblick über den Zugriff auf die Compiler Tree API. Der Abschnitt "Accessing the Abstract Syntax Tree: The Compiler Tree API" scheint für Ihre Frage besonders geeignet zu sein.
Je nachdem, was Sie tun, können Sie auch die Jackpot Rule Language betrachten, die eine eigenständige Refactoring-Engine ist, die in den Compiler-Baum integriert wird.
Kompilieren Sie und führen Sie dies mit -cp tools.jar
(wo müssen Sie natürlich den Speicherort Ihrer tools.jar
angeben).
import com.sun.source.util.Trees;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class JCTreeTest {
private static final JavaCompiler javac
= ToolProvider.getSystemJavaCompiler();
public static void main(String[] args) {
final StandardJavaFileManager jfm
= javac.getStandardFileManager(null, null, null);
final JavaCompiler.CompilationTask task
= javac.getTask(null, jfm, null, null, null,
jfm.getJavaFileObjects(args));
final Trees trees = Trees.instance(task);
// Do stuff with "trees"
}
}
Es kompiliert und läuft für mich, obwohl ich mit den Bäumen nicht gespielt haben stopfen mich, so dass Sie read the javadoc selbst haben werden. :-) Viel Glück!