0

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

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

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

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

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

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

ответ

0

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

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

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

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

Смежные вопросы