Spec-Zone.ru › OpenJDK 21

Интерфейс процессора аннотаций

Все известные реализующие классы:
AbstractProcessor
public interface Processor
Интерфейс для процессора аннотаций.

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

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

  1. Если используемый объект Processor не существует, для создания экземпляра процессора инструмент вызывает конструктор без аргументов класса процессора.
  2. Далее, инструмент вызывает метод init с соответствующей ProcessingEnvironment.
  3. Затем инструмент вызывает методы getSupportedAnnotationTypes, getSupportedOptions и getSupportedSourceVersion. Эти методы вызываются только один раз за выполнение, а не в каждом раунде.
  4. В соответствии с ситуацией инструмент вызывает метод process объекта Processor; новый объект Processor не создаётся для каждого раунда.
Если объект процессора создаётся и используется без соблюдения вышеуказанного протокола, то поведение процессора не определено этим интерфейсом.

Инструмент использует процесс обнаружения для поиска процессоров аннотаций и определения того, следует ли их запускать. Настройка инструмента позволяет контролировать набор потенциальных процессоров. Например, для JavaCompiler список кандидатных процессоров для запуска может быть установлен напрямую или контролироваться с помощью пути поиска, используемого для поиска в стиле сервиса. Другие реализации инструментов могут иметь разные механизмы конфигурации, такие как параметры командной строки; подробности см. в документации конкретного инструмента. Какие процессоры инструмент запросит на запуск, зависит от интерфейсов аннотаций присутствующих в корневых элементах, от того, какие интерфейсы аннотаций поддерживает процессор, и от того, заявляет ли процессор о поддержке интерфейсов аннотаций, которые он обрабатывает. Процессору будет предложено обработать подмножество поддерживаемых им интерфейсов аннотаций, возможно, пустой набор. Для данного раунда инструмент вычисляет набор интерфейсов аннотаций, присутствующих в элементах, вложенных в корневые элементы. Если присутствует хотя бы один интерфейс аннотации, то по мере того, как процессоры заявляют о поддержке интерфейсов аннотаций, они удаляются из набора несопоставленных интерфейсов аннотаций. Когда набор становится пустым или больше нет доступных процессоров, раунд завершен. Если интерфейсов аннотаций нет, обработка аннотаций все равно происходит, но только универсальные процессоры, которые поддерживают обработку всех интерфейсов аннотаций, "*", могут заявить о поддержке (пустого) набора интерфейсов аннотаций.

Интерфейс аннотации считается присутствующим, если на элементе, вложенном в корневые элементы раунда, присутствует хотя бы одна аннотация этого интерфейса. Для этой цели параметр типа считается вложенным в его обобщённый элемент. Для этой цели элемент пакета не считается включающим в себя верхнеуровневые классы и интерфейсы в этом пакете. (Корневой элемент, представляющий пакет, создаётся при обработке файла package-info) Аналогично, для этой цели элемент модуля не считается включающим пакеты в этом модуле. (Корневой элемент, представляющий модуль, создаётся при обработке файла module-info) Аннотации на использовании типов, в отличие от аннотаций на элементах, игнорируются при вычислении того, присутствует ли интерфейс аннотации.

Аннотация присутствует, если она соответствует определению присутствия, данному в AnnotatedConstruct. Вкратце, аннотация считается присутствующей для целей обнаружения, если она непосредственно присутствует или присутствует через наследование. Аннотация не считается присутствующей в силу того, что она обернута контейнерной аннотацией. Оперативно это эквивалентно тому, что аннотация присутствует на элементе тогда и только тогда, когда она будет включена в результаты вызова Elements.getAllAnnotationMirrors(Element) на этом элементе. Так как аннотации внутри контейнерных аннотаций не считаются присутствующими, для правильной обработки повторяемых интерфейсов аннотаций, процессорам рекомендуется включать как сам повторяемый интерфейс аннотации, так и содержащий его интерфейс аннотации в набор поддерживаемых интерфейсов аннотаций процессора.

Обратите внимание, что если процессор поддерживает "*" и возвращает true, то все аннотации считаются обработанными. Следовательно, универсальный процессор, используемый, например, для реализации дополнительных проверок на корректность, должен возвращать false, чтобы не препятствовать работе других таких проверяющих механизмов.

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

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

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

Для обеспечения надёжности при работе в разных реализациях инструментов процессор аннотаций должен обладать следующими свойствами:

  1. Результат обработки заданных входных данных не зависит от присутствия или отсутствия других входных данных (ортогональность).
  2. Обработка одних и тех же входных данных даёт одинаковые выходные данные (согласованность).
  3. Обработка входных данных A, за которой следует обработка входных данных B, эквивалентна обработке B, за которой следует обработка A (коммутативность).
  4. Обработка входных данных не зависит от присутствия выходных данных других процессоров аннотаций (независимость).

Интерфейс Filer обсуждает ограничения на то, как процессоры могут работать с файлами.

Примечание к API:
Реализаторам этого интерфейса может быть удобно расширить AbstractProcessor, а не реализовывать этот интерфейс напрямую.
С:
1.6

Краткое описание методов

Модификатор и тип Метод Описание
Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText)
Возвращает инфраструктуре инструмента итерируемый набор предложенных завершений для аннотации.
Set<String> getSupportedAnnotationTypes()
Возвращает имена поддерживаемых этим процессором интерфейсов аннотаций.
Set<String> getSupportedOptions()
Возвращает опции, распознаваемые этим процессором.
SourceVersion getSupportedSourceVersion()
Возвращает последнюю поддерживаемую версию исходного кода этим процессором аннотаций.
void init(ProcessingEnvironment processingEnv)
Инициализирует процессор с помощью среды обработки.
boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
Обрабатывает набор интерфейсов аннотаций в корневых элементах, полученных из предыдущего раунда, и возвращает, заявляет ли этот процессор о поддержке этих интерфейсов аннотаций.

Подробное описание методов

getSupportedOptions

Set<String> getSupportedOptions()
Возвращает опции, распознаваемые этим процессором. Реализация инструмента обработки должна предоставить способ передачи опций, специфичных для процессора, отдельно от опций, передаваемых самому инструменту, см. getOptions.

Каждая возвращаемая строка в наборе должна быть последовательностью идентификаторов, разделенных точкой:

SupportedOptionString:
Identifiers
Identifiers:
Identifier
Identifier . Identifiers
Identifier:
Синтаксический идентификатор, включая ключевые слова и литералы

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

Возвращает:
опции, распознаваемые этим процессором, или пустой набор, если таковых нет
См. также:
  • SupportedOptions

getSupportedAnnotationTypes

Set<String> getSupportedAnnotationTypes()
Возвращает имена поддерживаемых этим процессором интерфейсов аннотаций. Элемент результата может быть каноническим (полностью квалифицированным) именем поддерживаемого интерфейса аннотации. В качестве альтернативы, он может иметь вид "name.*" , представляющий набор всех интерфейсов аннотаций с каноническими именами, начинающимися с "name.". В любом из этих случаев имя интерфейса аннотации может быть необязательно предварено именем модуля, за которым следует символ "/". Например, если процессор поддерживает "a.B", это может включать несколько интерфейсов аннотаций с именем a.B, которые находятся в разных модулях. Для поддержки только a.B в модуле foo вместо этого используйте "foo/a.B". Если имя модуля указано, будет соответствовать только аннотация в этом модуле. В частности, если имя модуля указано в среде, где модули не поддерживаются, например, в среде обработки аннотаций, настроенной для версии исходного кода без модулей, то интерфейсы аннотаций с именем модуля не соответствуют. Наконец, "*" само по себе представляет набор всех интерфейсов аннотаций, включая пустой набор. Обратите внимание, что процессор не должен заявлять о "*" , если он фактически не обрабатывает все файлы; объявление ненужных аннотаций может привести к замедлению производительности в некоторых средах.

Каждая возвращаемая строка в наборе должна быть принята следующей грамматикой:

SupportedAnnotationTypeString:
ModulePrefixopt TypeName DotStaropt
*
ModulePrefix:
ModuleName /
DotStar:
. *
где TypeName и ModuleName определены в Спецификации языка Java (6.5 Определение значения имени).
Примечание API:
При работе в среде, которая поддерживает модули, процессорам рекомендуется включать префикс модуля при описании поддерживаемых ими интерфейсов аннотаций. Метод AbstractProcessor.getSupportedAnnotationTypes предоставляет поддержку для удаления префикса модуля при работе в среде без модулей.
Возвращает:
имена поддерживаемых этим процессором интерфейсов аннотаций или пустой набор, если таковых нет
См. Спецификацию языка Java:
3.8 Идентификаторы
См. также:
  • SupportedAnnotationTypes

getSupportedSourceVersion

SourceVersion getSupportedSourceVersion()
Возвращает последнюю поддерживаемую версию исходного кода этим процессором аннотаций.
Возвращает:
последнюю поддерживаемую версию исходного кода этим процессором аннотаций
См. также:
  • SupportedSourceVersion
  • ProcessingEnvironment.getSourceVersion()

init

void init(ProcessingEnvironment processingEnv)
Инициализирует процессор с помощью среды обработки.
Параметры:
processingEnv - среда для средств, которые фреймворк обработки предоставляет процессору

process

boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
Обрабатывает набор интерфейсов аннотаций на корневых элементах, полученных из предыдущего раунда, и возвращает, заявляет ли данный процессор о принадлежности этих интерфейсов аннотаций. Если true возвращается, интерфейсы аннотаций заявляются о принадлежности, и последующие процессоры не будут запрошены для их обработки; если false возвращается, интерфейсы аннотаций не заявляются о принадлежности, и последующие процессоры могут быть запрошены для их обработки. Процессор может всегда возвращать то же булево значение или изменять результат на основе своих собственных критериев.

Входной набор будет пустым, если процессор поддерживает "*" , а корневые элементы не имеют аннотаций. Процессор Processor должен корректно обрабатывать пустой набор аннотаций.

Параметры:
annotations - интерфейсы аннотаций, запрошенные для обработки
roundEnv - среда для получения информации о текущем и предыдущем раунде
Возвращает:
указывает, объявляет ли данный процессор о принадлежности набора интерфейсов аннотаций

getCompletions

Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText)
Возвращает инфраструктуре инструмента итератор предлагаемых завершений аннотации. Поскольку запрашиваются завершения, предоставленная информация об аннотации может быть неполной, как если бы это был фрагмент исходного кода. Процессор может вернуть пустой итератор. Процессоры аннотаций должны сосредоточить свои усилия на предоставлении завершений для членов аннотаций с дополнительными ограничениями на валидность, известными процессору, например, членом int , значение которого должно лежать между 1 и 10, или членом строки, который должен быть распознан известной грамматикой, такой как регулярное выражение или URL.

Поскольку моделируются неполные программы, некоторые параметры могут иметь только частичную информацию или быть null. По крайней мере, один из element и userText должен быть не-null. Если element не-null, annotation и member могут быть null. Процессоры не должны выбрасывать NullPointerException , если некоторые параметры null; если у процессора нет завершений, которые можно предложить на основе предоставленной информации, можно вернуть пустой итератор. Процессор также может вернуть одно завершение со строкой значения по умолчанию и сообщением, объясняющим, почему завершений нет.

Завершения информативны и могут отражать дополнительные проверки валидности, выполняемые процессорами аннотаций. Например, рассмотрим простую аннотацию:

 @MersennePrime {
    int value();
 }
 
(Простое число Мерсенна — это простое число вида 2n - 1.) Учитывая интерфейс аннотации для этой аннотации, можно вернуть список всех таких простых чисел в int диапазоне, не проверяя другие аргументы для getCompletions:
 import static javax.annotation.processing.Completions.*;
 ...
 return List.of(of("3"),
                of("7"),
                of("31"),
                of("127"),
                of("8191"),
                of("131071"),
                of("524287"),
                of("2147483647"));
 
Более информативный набор завершений будет включать количество каждого простого числа:
 return List.of(of("3",          "M2"),
                of("7",          "M3"),
                of("31",         "M5"),
                of("127",        "M7"),
                of("8191",       "M13"),
                of("131071",     "M17"),
                of("524287",     "M19"),
                of("2147483647", "M31"));
 
Однако, если userText доступен, можно проверить, являются ли только подмножество простых чисел Мерсенна допустимыми. Например, если пользователь набрал
@MersennePrime(1
значение userText будет "1"; и только два из простых чисел являются возможными завершениями:
 return Arrays.asList(of("127",        "M7"),
                      of("131071",     "M17"));
 
Иногда не существует допустимых завершений. Например, нет простого числа Мерсенна в диапазоне, начинающегося с 9:
@MersennePrime(9
Соответствующим ответом в этом случае является либо возврат пустого списка завершений,
 return Collections.emptyList();
 
либо единственное пустое завершение с полезным сообщением
 return Arrays.asList(of("", "No in-range Mersenne primes start with 9"));
 
Параметры:
element - элемент, к которому применяется аннотация
annotation - (возможно, частичная) аннотация, применяемая к элементу
member - член аннотации, для которого требуется вернуть возможные завершения
userText - текст исходного кода, который нужно завершить
Возвращает:
предлагаемые завершения аннотации

© 1993, 2023, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/21/docs/api/java.compiler/javax/annotation/processing/Processor.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API