Skip to content

KSP의 Kotlin 코드 모델링 방식

KSP GitHub 저장소에서 API 정의를 찾을 수 있습니다. 다음 다이어그램은 KSP에서 Kotlin이 어떻게 모델링되는지 개요를 보여줍니다.

class diagram

타입 및 해석 (Resolution)

해석(Resolution)은 기반 API 구현에서 대부분의 비용을 차지합니다. 따라서 타입 참조는 (몇 가지 예외를 제외하고) 프로세서에 의해 명시적으로 해석되도록 설계되었습니다. KSFunctionDeclaration.returnType 또는 KSAnnotation.annotationType과 같은 _타입_이 참조될 때, 이는 항상 어노테이션과 수정자를 포함하는 KSReferenceElementKSTypeReference입니다.

kotlin
interface KSFunctionDeclaration : ... {
  val returnType: KSTypeReference?
  // ...
}

interface KSTypeReference : KSAnnotated, KSModifierListOwner {
  val type: KSReferenceElement
}

KSTypeReference는 Kotlin의 타입 시스템에 있는 타입을 참조하는 KSType으로 해석될 수 있습니다.

KSTypeReferenceKSReferenceElement를 가지며, 이는 Kotlin의 프로그램 구조, 즉 참조가 작성된 방식을 모델링합니다. 이는 Kotlin 문법의 type 요소에 해당합니다.

KSReferenceElementKSClassifierReference 또는 KSCallableReference가 될 수 있으며, 이들은 해석할 필요 없이 많은 유용한 정보를 포함합니다. 예를 들어, KSClassifierReferencereferencedName을 가지며, 반면에 KSCallableReferencereceiverType, functionArguments, returnType을 가집니다.

KSTypeReference가 참조하는 원래 선언이 필요한 경우, 일반적으로 KSType으로 해석한 다음 KSType.declaration을 통해 접근하여 찾을 수 있습니다. 타입이 언급된 위치에서 해당 클래스가 정의된 위치로 이동하는 과정은 다음과 같습니다.

kotlin
val ksType: KSType = ksTypeReference.resolve()
val ksDeclaration: KSDeclaration = ksType.declaration

타입 해석은 비용이 많이 들며 따라서 명시적인 형태를 가집니다. 해석을 통해 얻을 수 있는 정보 중 일부는 이미 KSReferenceElement에서 사용 가능합니다. 예를 들어, KSClassifierReference.referencedName은 흥미롭지 않은 많은 요소를 걸러낼 수 있습니다. KSDeclaration 또는 KSType에서 특정 정보가 필요한 경우에만 타입을 해석해야 합니다.

함수 타입을 가리키는 KSTypeReference는 대부분의 정보를 자체 요소 내에 가지고 있습니다. 비록 Function0, Function1 등과 같은 함수 패밀리로 해석될 수 있지만, 이러한 해석들은 KSCallableReference보다 더 많은 정보를 제공하지 않습니다. 함수 타입 참조를 해석하는 한 가지 사용 사례는 함수의 프로토타입의 정체성(identity)을 다루는 것입니다.