Spec-Zone.ru › Kotlin 1.7

Обработка по нескольким раундам

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 предоставляет реализацию по умолчанию no-op для onError() как части интерфейса SymbolProcessor. Вы можете переопределить этот метод, чтобы реализовать собственную логику обработки ошибок.

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

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

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

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

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

Последнее изменение: 11 января 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