Почему KSP
Плагины компилятора — это мощные инструменты метапрограммирования, которые могут значительно улучшить ваш способ написания кода. Плагины компилятора напрямую вызывают компиляторы как библиотеки для анализа и редактирования входных программ. Эти плагины также могут генерировать выходные данные для различных целей. Например, они могут генерировать шаблонный код, а также генерировать полные реализации для специальных элементов программы, таких как Parcelable. Плагины имеют различные другие применения и могут даже использоваться для реализации и настройки функций, которые не предоставляются напрямую в языке.
Хотя плагины компилятора мощные, эта мощь имеет свою цену. Чтобы написать даже самый простой плагин, вам необходимы базовые знания компиляторов, а также определенный уровень знакомства с реализацией деталей вашего конкретного компилятора. Ещё одна практическая проблема заключается в том, что плагины часто тесно связаны с определёнными версиями компилятора, что означает необходимость обновления вашего плагина каждый раз, когда вам нужно будет поддерживать более новую версию компилятора.
KSP упрощает создание лёгких плагинов компилятора
KSP разработан для скрытия изменений в компиляторе, минимизируя усилия по техническому обслуживанию для процессоров, которые его используют. KSP разработан так, чтобы не быть привязанным к JVM, что позволит проще адаптировать его к другим платформам в будущем. KSP также разработан для минимизации времени сборки. Для некоторых процессоров, таких как Glide, KSP сокращает полное время компиляции на 25% по сравнению с kapt.
KSP сам реализован как плагин компилятора. В репозитории Maven Google есть предварительно собранные пакеты, которые вы можете загрузить и использовать, не выполняя сборку проекта самостоятельно.
Сравнение с плагинами компилятора kotlinc
Плагины компилятора kotlinc имеют доступ практически ко всему, что есть в компиляторе, и поэтому обладают максимальной мощностью и гибкостью. С другой стороны, поскольку эти плагины потенциально могут зависеть от чего угодно в компиляторе, они чувствительны к изменениям компилятора и нуждаются в частом техническом обслуживании. Эти плагины также требуют глубокого понимания реализации kotlinc, поэтому кривая обучения может быть крутой.
KSP стремится скрыть большинство изменений в компиляторе с помощью хорошо определённого API, хотя крупные изменения в компиляторе или даже в языке Kotlin могут потребовать раскрытия для пользователей API.
KSP пытается удовлетворить общие сценарии использования, предоставив API, который жертвует мощностью ради простоты. Его возможности представляют собой строгую подмножество общего плагина kotlinc. Например, в то время как kotlinc может анализировать выражения и операторы, а также может даже изменять код, KSP этого не может.
Хотя написание плагина kotlinc может быть очень интересным, это также может занять много времени. Если у вас нет возможности изучить реализацию kotlinc и вам не нужно изменять исходный код или читать выражения, KSP может подойти вам.
Сравнение с рефлексией
API KSP похож на kotlin.reflect. Основное различие между ними заключается в том, что ссылки на типы в KSP необходимо разрешать явно. Это одна из причин, почему интерфейсы не объединены.
Сравнение с kapt
kapt — замечательное решение, которое позволяет большому количеству процессоров аннотаций Java работать с Kotlin-программами «из коробки». Основные преимущества KSP по сравнению с kapt — это улучшенная производительность сборки, отсутствие привязки к JVM, более естественный Kotlin API и возможность понимания только Kotlin-символов.
Для запуска Java-процессоров аннотаций без модификаций kapt компилирует код Kotlin в Java-заглушки, которые сохраняют информацию, интересующую Java-процессоры аннотаций. Для создания этих заглушек kapt необходимо разрешить все символы в Kotlin-программе. Время генерации заглушек составляет примерно 1/3 времени полного анализа kotlinc и того же порядка kotlinc кодогенерации. Для многих процессоров аннотаций это значительно больше времени, чем потраченное на сами процессоры. Например, Glide рассматривает очень ограниченное количество классов с предопределённой аннотацией, а его кодогенерация довольно быстрая. Практически вся нагрузка на сборку приходится на фазу генерации заглушек. Переход на KSP немедленно сократит время, затрачиваемое на компилятор, на 25%.
Для оценки производительности мы реализовали упрощённую версию Glide в KSP, чтобы она генерировала код для проекта Tachiyomi. Хотя общее время компиляции Kotlin проекта на нашем тестовом устройстве составляет 21,55 секунды, kapt потребовало 8,67 секунды для генерации кода, а наша реализация KSP — всего 1,15 секунды.
В отличие от kapt, процессоры в KSP не видят входные программы с точки зрения Java. API более естественен для Kotlin, особенно для функций Kotlin, таких как функции верхнего уровня. Поскольку KSP не делегирует javac, как kapt, он не предполагает JVM-специфичных действий и может потенциально использоваться с другими платформами.
Ограничения
Хотя KSP пытается быть простым решением для большинства распространённых случаев использования, он пожертвовал чем-то по сравнению с другими решениями для плагинов. Следующее не является целью KSP:
Анализ информации на уровне выражений исходного кода.
Изменение исходного кода.
100% совместимость с API для обработки аннотаций Java.
Мы также исследуем несколько дополнительных функций. Эти функции в настоящее время недоступны:
Интеграция в IDE: в настоящее время IDE не знают ничего о сгенерированном коде.
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/ksp-why-ksp.html