Javac.exe Пример доступа к программному обеспечению AST

Возможно ли получить доступ к абстрактному дереву синтаксиса (AST) внутри программы javac.exe? Не могли бы вы привести пример?

Ответ 1

Да, это возможно, но только с тех пор, как Java 6. Питер фон дер Ае рассказывает о двух JSR в это интервью. JSR 199:

API компилятора JSR 199 состоит из трех вещей: первый из них в основном позволяет вызывать компилятор через API. Во-вторых, API позволяет вам настроить, как компилятор находит и записывает файлы. Я имею в виду файлы в абстрактном смысле, поскольку файлы, с которыми работает компилятор, необязательно находятся в файловой системе. Абстракция файла JSR 199 позволяет вам иметь файлы в базе данных и, например, генерировать выходные данные непосредственно в памяти. Наконец, JSR 199 API позволяет собирать диагностику из компилятора структурированным способом, чтобы вы могли легко преобразовывать сообщения об ошибках, например, в строки в редакторе среды разработки.

JSR 269 - это API обработки аннотации.

Эта статья дает отличный обзор доступа к API-интерфейс компилятора. Раздел "Доступ к абстрактному дереву синтаксиса: API дерева компилятора кажется особенно подходящим для вашего вопроса.

В зависимости от того, что вы делаете, вы также можете посмотреть Язык правил Джекпота, который является автономным механизмом рефакторинга, который плагины в Дереве компилятора.

Ответ 2

Скомпилируйте и запустите это с помощью -cp tools.jar (где вам нужно указать расположение вашего tools.jar, очевидно).

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"
    }
}

Он компилируется и работает для меня, хотя я сам не играл с деревьями, поэтому вам нужно прочитать javadoc самостоятельно,:-) Удачи!