KSP 예제

KSP 예제 (KSP examples)

KSP를 쓸 때 자주 필요한 코드 조각들을 모아봤어요. 각 예제가 어떤 상황에서 쓰이는지 하나씩 짚어볼게요.

출처: Kotlin 공식 문서

본문

모든 멤버 함수 가져오기

클래스 선언에서 정의된 모든 멤버 함수를 가져오는 확장 함수예요. declarations를 돌면서 KSFunctionDeclaration인 것만 걸러내요.

fun KSClassDeclaration.getDeclaredFunctions(): Sequence<KSFunctionDeclaration> =
    declarations.filterIsInstance<KSFunctionDeclaration>()

클래스나 함수가 로컬인지 확인하기

선언이 로컬(어떤 함수 안에 중첩되어 선언된 것)인지 판별해요. parentDeclaration이 있고 그게 클래스 선언이 아니면 로컬로 봐요.

fun KSDeclaration.isLocal(): Boolean =
    parentDeclaration != null && parentDeclaration !is KSClassDeclaration

타입 별칭이 가리키는 실제 클래스나 인터페이스 선언 찾기

타입 별칭(typealias)은 다른 타입 별칭을 가리킬 수도 있어요. 그래서 별칭을 계속 따라가다가 실제 타입 별칭이 아닌 선언이 나오면 그때 그 선언을 돌려줘요.

fun KSTypeAlias.findActualType(): KSClassDeclaration {
    val resolvedType = this.type.resolve().declaration
    return if (resolvedType is KSTypeAlias) {
        resolvedType.findActualType()
    } else {
        resolvedType as KSClassDeclaration
    }
}

파일 애노테이션에서 억제된 이름들 수집하기

파일 레벨 애노테이션에 적힌 kotlin.Suppress의 인자들(억제된 이름들)을 모아서 문자열 시퀀스로 돌려주는 확장 함수예요.

// @file:kotlin.Suppress("Example1", "Example2")
fun KSFile.suppressedNames(): Sequence<String> = annotations
    .filter {
        it.shortName.asString() == "Suppress" &&
        it.annotationType.resolve().declaration.qualifiedName?.asString() == "kotlin.Suppress"
    }.flatMap {
        it.arguments.flatMap {
            (it.value as Array<String>).toList()
        }
    }