Процесс аннотации Java еще не сгенерировал элементы

Я использую последние версии eclipse, java и https://marketplace.eclipse.org/content/m2e-apt для обработки аннотаций. У меня есть процессор, который обрабатывает одну аннотацию и просматривает методы в аннотированном классе, берет все неприватные методы и создает интерфейс, содержащий их (который будет реализовывать аннотированный класс). Таким образом, в основном этот класс реализует интерфейс, который будет сгенерирован. Допустим, у нас есть классы A и B, которые, аннотированные, будут генерировать интерфейсы IntA и IntB в том же пакете, что и соответствующие методы. Допустим, у меня есть метод в классе A с типом возвращаемого значения IntB.

В своих процессорах аннотаций я расширяю AbstractProcessor и использую такие вещи, как TypeElement и TypeMirror ( ((ExecutableElement)element).getReturnType(), чтобы получить TypeMirror возвращаемого значения ExecutableElement, соответствующего методу из аннотированного класса). Затем я использую toString() для этого TypeMirror, чтобы записать возвращаемое значение метода в сгенерированный интерфейс.

Проблема в том, что если IntA сгенерирован до IntB, этот метод, написанный на IntA, будет иметь метод, возвращающий IntB без его полного имени (поскольку процессор ничего не знает о IntB, поскольку он еще не был сгенерирован), поэтому генерируется ошибка в Инта. Если я что-то изменю в классе A (затем сохраню, что заставит Eclipse постепенно генерировать файлы, что повлияет только на файлы, сгенерированные аннотацией в классе A), эта ошибка решается, так как IntB уже сгенерирован и может напишите полное имя в качестве возвращаемого значения этого метода.

Я обнаружил, что, написав полное имя для возвращаемого значения метода, возвращающего IntB в классе A, я могу избежать этой проблемы. Однако я хотел бы, если это так, чтобы процессор обрабатывал этот класс позже, когда IntB уже сгенерирован.

Как я могу задержать процесс аннотации для класса А?

PS: до сих пор я создал механизм, в котором он проверяет возвращаемое значение каждого метода для следующего оператора (element.getReturnType().getKind() == TypeKind.ERROR), и в этом случае я выбрасываю исключение и добавляю это элемент в списке, который будет обработан в другом раунде. Не сработало, так как еще несколько раз обрабатывал элемент с теми же проблемами. Также я попытался вернуть false методу process(), переопределенному из AbstractProcessor, и все равно не сработало.


person Emanuel    schedule 26.01.2017    source источник


Ответы (1)


Соберите информацию обо всех интерфейсах, которые должны быть сгенерированы в первую очередь, поскольку у вас, скорее всего, будет доступ к обоим классам A и B в одном и том же раунде обработки аннотаций.

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

Затем, после того как вы обработаете все классы с помощью своей аннотации, используйте эту информацию для одновременного создания интерфейсов.

Если вы хотите отложить создание своих интерфейсов до последней секунды, посмотрите RoundEnvironment.processingOver().

person PureSpider    schedule 16.02.2017