Esempio di accesso programmatico AST javac.exe
-
10-07-2019 - |
Domanda
È possibile accedere all'albero della sintassi astratta (AST) all'interno di javac.exe a livello di codice? Potresti fornire un esempio?
Soluzione
Sì, è possibile, ma solo da Java 6. Peter von der Ahé parla dei due JSR in questa intervista . Di JSR 199:
L'API del compilatore JSR 199 è composta da tre elementi: il primo consente sostanzialmente di invocare un compilatore tramite l'API. In secondo luogo, l'API consente di personalizzare il modo in cui il compilatore trova e scrive i file. Intendo i file in senso astratto, poiché i file di cui il compilatore si occupa non sono necessariamente nel file system. L'astrazione dei file di JSR 199 consente di avere file in un database e di generare output direttamente in memoria, ad esempio. Infine, l'API JSR 199 consente di raccogliere la diagnostica dal compilatore in modo strutturato in modo da poter trasformare facilmente i messaggi di errore, ad esempio, in righe nell'editor di un IDE.
JSR 269 è l'API di elaborazione delle annotazioni.
Questo articolo offre un'eccellente panoramica dell'accesso a API dell'albero del compilatore . La sezione " Accesso all'albero di sintassi astratto: l'API dell'albero del compilatore " sembra particolarmente adatto alla tua domanda.
A seconda di ciò che stai facendo, potresti anche voler guardare il Jackpot Rule Language , che è un motore di refactoring autonomo che si inserisce nell'albero del compilatore.
Altri suggerimenti
Compilalo ed eseguilo con -cp tools.jar
(dove devi specificare la posizione del tuo tools.jar
, ovviamente).
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"
}
}
Compila e corre per me, anche se non ho giocato con la roba degli alberi da solo, quindi dovrai leggi tu stesso il javadoc . :-) Buona fortuna!