Как 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