javac.exe AST пример программного доступа - PullRequest
10 голосов
/ 13 октября 2008

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

Ответы [ 2 ]

14 голосов
/ 13 октября 2008

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

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

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

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

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

6 голосов
/ 13 октября 2008

Скомпилируйте и запустите это с -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 самостоятельно. :-) Удачи!

...