Spec-Zone.ru › Kotlin 1.6

Обработка в несколько раундов

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

Изменения в вашем обработчике

Для использования обработки в несколько раундов функция SymbolProcessor.process() должна возвращать список отложенных символов (List<KSAnnotated>) для недопустимых символов. Используйте KSAnnotated.validate() для фильтрации недопустимых символов, которые будут отложены до следующего раунда.

Следующий пример кода демонстрирует, как откладывать недопустимые символы с помощью проверки валидности:

override fun process(resolver: Resolver): List<KSAnnotated> {
    val symbols = resolver.getSymbolsWithAnnotation("com.example.annotation.Builder")
    val result = symbols.filter { !it.validate() }
    symbols
        .filter { it is KSClassDeclaration && it.validate() }
        .map { it.accept(BuilderVisitor(), Unit) }
    return result
}

Поведение при обработке в несколько раундов

Откладывание символов на следующий раунд

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

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

Проверка символов

Удобный способ определить, следует ли откладывать символ, — это валидация. Обработчик должен знать, какая информация необходима для правильной обработки символа. Обратите внимание, что валидация обычно требует разрешения, что может быть дорогостоящим, поэтому мы рекомендуем проверять только необходимое. Продолжая предыдущий пример, идеальная валидация для обработчика билдера проверяет только, содержат ли все разрешенные типы параметров конструкторов аннотированных символов isError == false.

KSP предоставляет утилиту проверки по умолчанию. Дополнительную информацию см. в разделе Дополнительно.

Условие завершения

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

Доступные файлы в каждом раунде

Как вновь сгенерированные, так и существующие файлы доступны через Resolver. KSP предоставляет два API для доступа к файлам: Resolver.getAllFiles() и Resolver.getNewFiles(). getAllFiles() возвращает объединенный список существующих файлов и вновь сгенерированных файлов, в то время как getNewFiles() возвращает только вновь сгенерированные файлы.

Изменения в getSymbolsAnnotatedWith()

Чтобы избежать ненужной повторной обработки символов, getSymbolsAnnotatedWith() возвращает только те символы, которые найдены в новых сгенерированных файлах, вместе с символами из отложенных символов из последнего раунда.

Инициализация обработчика

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

Согласованность информации между раундами

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

Обработка ошибок и исключений

При возникновении ошибки (определенной обработчиком при вызове KSPLogger.error()) или исключения обработка останавливается после завершения текущего раунда. Все обработчики вызовут метод onError() и не вызовут метод finish().

Обратите внимание, что даже если произошла ошибка, другие обработчики продолжают нормальную обработку в рамках этого раунда. Это означает, что обработка ошибок происходит после завершения обработки раунда.

При возникновении исключений KSP попытается отличить исключения KSP от исключений обработчиков. Исключения приведут к немедленному прекращению обработки и будут записаны как ошибка в KSPLogger. Об исключениях KSP следует сообщать разработчикам KSP для дальнейшего изучения. В конце раунда, где произошли исключения или ошибки, все обработчики вызовут функцию onError(), чтобы выполнить свою собственную обработку ошибок.

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

Дополнительно

Поведение по умолчанию для проверки

Логика проверки по умолчанию, предоставляемая KSP, проверяет все непосредственно достижимые символы внутри области видимости символа, который проверяется. Проверка по умолчанию проверяет, разрешаются ли ссылки в области видимости до конкретного типа, но не выполняет рекурсивный спуск по ссылаемым типам для выполнения проверки.

Напишите свою логику проверки

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

Последнее изменение: 07 апреля 2022 г.
Инкрементная обработка KSP с Kotlin Multiplatform

© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/ksp-multi-round.html

Spec-Zone.ru

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