Как KSP моделирует код Kotlin
Определение API вы можете найти в репозитории KSP на GitHub. Диаграмма демонстрирует общий обзор того, как Kotlin моделируется в KSP:
Тип и разрешение
Разрешение занимает большую часть затрат на реализацию базового API. Поэтому ссылки на типы предназначены для явного разрешения процессорами (с несколькими исключениями). Когда ссылаются на тип (например, KSFunctionDeclaration.returnType или KSAnnotation.annotationType), это всегда KSTypeReference, который является KSReferenceElement с аннотациями и модификаторами.
interface KSFunctionDeclaration : ... {
val returnType: KSTypeReference?
// ...
}
interface KSTypeReference : KSAnnotated, KSModifierListOwner {
val type: KSReferenceElement
}
KSTypeReference может быть разрешен в KSType, который ссылается на тип в системе типов Kotlin.
У KSTypeReference есть KSReferenceElement, который моделирует структуру программы Kotlin: а именно, как записана ссылка. Она соответствует элементу type в грамматике Kotlin.
KSReferenceElement может быть KSClassifierReference или KSCallableReference, которые содержат много полезной информации без необходимости разрешения. Например, у KSClassifierReference есть referencedName, а у KSCallableReference есть receiverType, functionArguments и returnType.
Если требуется исходное объявление, на которое ссылается KSTypeReference, его обычно можно найти, разрешив в KSType и получив доступ через KSType.declaration. Переход от места упоминания типа к месту определения его класса выглядит так:
val ksType: KSType = ksTypeReference.resolve() val ksDeclaration: KSDeclaration = ksType.declaration
Разрешение типов дорогостоящее, поэтому имеет явную форму. Часть информации, полученная при разрешении, уже доступна в KSReferenceElement. Например, KSClassifierReference.referencedName может отфильтровать множество элементов, которые не представляют интереса. Вы должны разрешить тип только в том случае, если вам нужна определенная информация из KSDeclaration или KSType.
KSTypeReference, указывающий на тип функции, содержит большую часть своей информации в своем элементе. Хотя его можно разрешить в семейство Function0, Function1 и т. д., эти разрешения не добавляют никакой дополнительной информации по сравнению с KSCallableReference. Один из вариантов использования разрешения ссылок на типы функций — работа с идентичностью прототипа функции.
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/ksp-additional-details.html