Kotlin Academy · Lekcja

Pisanie pierwszego SymbolProcessor

Zaimplementuj procesor KSP, który wyszukuje klasy z adnotacjami i rejestruje je w logach.

Lekcja 2 z 413 kroki

Pisanie pierwszego SymbolProcessor to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Struktura projektu

Procesor KSP znajduje się w osobnym module Gradle (np. :processor). Moduł korzystający z procesora stosuje wtyczkę KSP i deklaruje zależność ksp od modułu procesora. Sam moduł procesora ma zwykłą zależność implementation od API KSP.

Dodawanie zależności KSP

W pliku build.gradle.kts modułu procesora:

plugins { kotlin("jvm") }
dependencies {
    implementation("com.google.devtools.ksp:symbol-processing-api:2.0.0-1.0.21")
}

Interfejs SymbolProcessor

Należy zaimplementować SymbolProcessor. Głównym punktem wejścia jest process(resolver: Resolver): List. Należy zwrócić symbole, których nie udało się przetworzyć, np. te, których zależności nie zostały jeszcze rozwiązane, aby można je było przetworzyć w drugiej rundzie.

import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.*

class MyProcessor(private val logger: KSPLogger,
                  private val codeGenerator: CodeGenerator) : SymbolProcessor {
    override fun process(resolver: Resolver): List<KSAnnotated> {
        val symbols = resolver.getSymbolsWithAnnotation("com.example.MyAnnotation")
        // process symbols here
        return emptyList()
    }
}

SymbolProcessorProvider

KSP wykrywa procesor za pośrednictwem SymbolProcessorProvider. Należy zarejestrować go w pliku resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider:

class MyProcessorProvider : SymbolProcessorProvider {
    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor =
        MyProcessor(
            logger = environment.logger,
            codeGenerator = environment.codeGenerator
        )
}

Plik rejestracji usługi

Należy utworzyć plik w dokładnej lokalizacji w zasobach modułu procesora:

  • Ścieżka: src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
  • Zawartość: w pełni kwalifikowana nazwa klasy SymbolProcessorProvider

Rozwiązywanie symboli według adnotacji

Należy użyć resolver.getSymbolsWithAnnotation(fqn), aby pobrać wszystkie deklaracje opatrzone daną adnotacją. Następnie należy ograniczyć wynik do oczekiwanego rodzaju deklaracji, np. deklaracji klas:

val classes = resolver
    .getSymbolsWithAnnotation("com.example.MyAnnotation")
    .filterIsInstance<KSClassDeclaration>()

Walidowanie symboli

Przed przetwarzaniem należy sprawdzić, czy każdy symbol można w pełni rozwiązać. Symbol, którego odwołania do typów nie zostały jeszcze skompilowane, nie jest prawidłowy. Takie symbole należy zwrócić z process(), aby ponowić próbę w następnej rundzie:

val (valid, deferred) = classes.partition { it.validate() }
// process valid; return deferred

Odwiedzanie deklaracji klasy

Należy użyć wzorca odwiedzającego KSVisitorVoid, aby przejść po strukturze klasy. Należy przesłonić visitClassDeclaration, aby uzyskać dostęp do właściwości, funkcji i klas zagnieżdżonych:

class MyVisitor : KSVisitorVoid() {
    override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
        val name = classDeclaration.simpleName.asString()
        val props = classDeclaration.getAllProperties().toList()
        println("Class: $name, props: ${props.size}")
    }
}

Rejestrowanie komunikatów z procesora

Należy użyć KSPLogger do emitowania komunikatów na różnych poziomach. logger.error() powoduje niepowodzenie kompilacji; logger.warn() wyświetla ostrzeżenie; logger.info() wyświetla komunikat informacyjny widoczny z użyciem --info.

logger.info("Processing class: ${classDeclaration.simpleName.asString()}")
logger.error("Missing required annotation", classDeclaration)

Dostęp do adnotacji symbolu

Każdy KSDeclaration ma sekwencję annotations. Należy użyć filter i arguments, aby odczytać wartości adnotacji:

val ann = classDeclaration.annotations
    .first { it.shortName.asString() == "MyAnnotation" }
val value = ann.arguments.first { it.name?.asString() == "value" }.value as String

Wskazówki dotyczące przetwarzania przyrostowego

Należy poinformować KSP, od których symboli wejściowych zależą poszczególne pliki wynikowe, wiążąc je za pomocą CodeGenerator.createNewFile(dependencies = ...). Dzięki temu KSP może pominąć procesor, gdy żadne z jego danych wejściowych się nie zmieniły.

Szybkie sprawdzenie

Jak KSP wykrywa implementację SymbolProcessorProvider?

Podsumowanie: pisanie pierwszego SymbolProcessor

Najważniejsze informacje:

  • Należy zaimplementować SymbolProcessor i SymbolProcessorProvider w osobnym module
  • Należy zarejestrować provider za pomocą META-INF/services/
  • Należy użyć resolver.getSymbolsWithAnnotation(), aby znaleźć symbole opatrzone adnotacjami
  • Należy zwalidować symbole przed przetwarzaniem i zwracać nierozwiązane symbole do ponownej próby
  • Należy używać KSPLogger do komunikatów podczas kompilacji, a CodeGenerator do zapisywania plików
Bezpłatny start

Ucz się Kotlin dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
51
Lekcje
203

Często zadawane pytania

Czy lekcja „Pisanie pierwszego SymbolProcessor” jest bezpłatna?

Tak — pełny tekst „Pisanie pierwszego SymbolProcessor” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Pisanie pierwszego SymbolProcessor”?

Zaimplementuj procesor KSP, który wyszukuje klasy z adnotacjami i rejestruje je w logach. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Pisanie pierwszego SymbolProcessor”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. KSP a KAPT: dlaczego KSP jest szybsze
  2. Pisanie pierwszego SymbolProcessor
  3. Generowanie plików źródłowych Kotlina za pomocą KotlinPoet
  4. Integracja procesorów KSP z kompilacją Gradle
← Powrót do Kotlin Academy