Процесс аннотации 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, поскольку он еще не был создан), поэтому генерируется ошибка. в IntA. Если я изменю что-то в классе A (затем сохраню, что заставит Eclipse постепенно генерировать файлы, что повлияет только на файлы, сгенерированные аннотацией в классе A), эта ошибка будет решена, так как IntB уже сгенерирован и может напишите полное имя как возвращаемое значение этого метода.
Я обнаружил, что, написав полное имя для возвращаемого значения метода, возвращающего IntB в классе A, я могу избежать этой проблемы. Тем не менее, я бы хотел, чтобы в этом случае процессор обрабатывал этот класс позднее, когда IntB уже сгенерирован.
Как я могу отложить процесс аннотации на класс A?
PS: до сих пор я создал механизм, где он проверяет возвращаемое значение каждого метода для следующего оператора (element.getReturnType(). GetKind() == TypeKind.ERROR), и в этом случае я выбрасываю исключение и добавляю это элемент в списке, который будет обработан в другом раунде. Это не сработало, так как обрабатывало элемент еще несколько раз с теми же проблемами. Также я попытался вернуть false в метод process(), переопределенный из AbstractProcessor, но все еще не работал.
1 ответ
Соберите информацию обо всех интерфейсах, которые должны быть сгенерированы первыми, поскольку вы, скорее всего, будете иметь доступ к обоим классам A и B в одном раунде обработки аннотаций
Ваш процессор аннотаций будет создаваться только один раз в начале обработки, поэтому вы можете использовать его атрибуты для хранения мета-информации о классах, для которых нужны сгенерированные интерфейсы.
Затем, после того, как вы обработали все классы с вашей аннотацией, используйте эту информацию для создания ваших интерфейсов сразу.
Если вы хотите отложить генерацию ваших интерфейсов до последней секунды, посмотрите на RoundEnvironment.processingOver()
,