Spec-Zone.ru › Kotlin 2

Начало работы с KSP

В этом руководстве вы узнаете:

  • Как добавить в проект процессоры аннотаций на основе KSP.

  • Как создать собственный процессор аннотаций с помощью API KSP.

  • Где найти код, созданный процессором.

Добавление в проект процессора на основе KSP

Чтобы использовать в проекте внешний процессор, добавьте KSP в блок plugins {} в файле build.gradle(.kts). Если процессор нужен только в определённом модуле, добавьте его вместо этого в файл build.gradle(.kts) этого модуля:

// build.gradle.kts

plugins {  
    kotlin("jvm") version "2.4.20"  
    id("com.google.devtools.ksp") version "2.3.10"
}
// build.gradle

plugins {
    id 'org.jetbrains.kotlin.jvm' version '2.4.20'
    id 'com.google.devtools.ksp' version '2.3.10'
}

Чтобы узнать последнюю версию KSP, посетите страницу релизов на GitHub.

В блоке dependencies {} верхнего уровня добавьте процессор, который хотите использовать. В этом примере используется Moshi, но для других процессоров применяется тот же подход:

// build.gradle.kts

dependencies {
    ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.2")
}
// build.gradle

dependencies {
    ksp 'com.squareup.moshi:moshi-kotlin-codegen:1.15.2'
}

Конфигурация ksp(...) применяет процессор только к исходному коду приложения. Чтобы обрабатывать исходный код тестов, добавьте процессор с конфигурацией kspTest(...).

Конфигурация ksp(...) доступна только в проектах с одной платформой. Сведения о настройке процессоров для отдельных целевых платформ и компиляций Kotlin Multiplatform см. в разделе KSP с Kotlin Multiplatform.

Создание собственного процессора

Выполнив следующие действия, вы создадите простой процессор аннотаций, который сгенерирует функцию helloWorld(). Хотя на практике она не очень полезна, на её примере можно изучить основы создания собственных процессоров и аннотаций.

Добавление KSP в проект

Создайте новый проект Kotlin и добавьте плагин KSP:

  1. В IntelliJ IDEA выберите Файл | Создать | Проект.

  2. В списке слева выберите Kotlin.

  3. В качестве системы сборки выберите Gradle и нажмите Создать.

    Creating a new project
  4. Добавьте плагин KSP в файл build.gradle(.kts):

    // build.gradle.kts
    
    plugins { 
        kotlin("jvm") version "2.4.20"
        id("com.google.devtools.ksp") version "2.3.10" apply false
    }
    
    // build.gradle
    
    plugins {
        id 'org.jetbrains.kotlin.jvm' version '2.4.20'
        id 'com.google.devtools.ksp' version '2.3.10' apply false
    }
    

Создание аннотации

Создайте новый модуль в корне проекта и объявите аннотацию:

  1. Выберите Файл | Создать | Модуль.

  2. В списке слева выберите Kotlin.

  3. Укажите следующие параметры и нажмите Создать:

    • Имя: annotations

    • Система сборки: Gradle

    Creating a new module
  4. В модуле создайте файл HelloWorldAnnotation.kt и объявите аннотацию с именем HelloWorldAnnotation:

    // annotations/src/main/kotlin/com/example/annotations/HelloWorldAnnotation.kt
    
    package com.example.annotations
    
    annotation class HelloWorldAnnotation
    

Создание и регистрация процессора

  1. Создайте ещё один модуль в корне проекта с именем processor.

  2. Добавьте API KSP и объявленную вами аннотацию в качестве зависимостей в файл build.gradle(.kts) модуля:

    // processor/build.gradle.kts
    
    plugins {  
        kotlin("jvm")
    }
    
    dependencies {
        implementation(project(":annotations"))
        implementation("com.google.devtools.ksp:symbol-processing-api:2.3.6")  
    }
    
    // processor/build.gradle
    
    plugins {
        id 'org.jetbrains.kotlin.jvm'
    }
    
    dependencies {
        implementation project ':annotations'
        implementation 'com.google.devtools.ksp:symbol-processing-api:2.3.6'
    }
    
  3. В модуле процессора создайте файл HelloWorldProcessor.kt и добавьте следующий код:

    // processor/src/main/kotlin/HelloWorldProcessor.kt
    
    class HelloWorldProcessor(val codeGenerator: CodeGenerator) : SymbolProcessor {
        // 1️⃣ process() function
        override fun process(resolver: Resolver): List<KSAnnotated> {
            resolver
                .getSymbolsWithAnnotation("com.example.annotations.HelloWorldAnnotation")
                .filter { it.validate() }
                .filterIsInstance<KSFunctionDeclaration>()
                .forEach { it.accept(HelloWorldVisitor(), Unit) }
    
           return emptyList()
        }
    
       // 2️⃣ Visitor
       inner class HelloWorldVisitor : KSVisitorVoid() {
           override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
               createNewFileFrom(function).use { file ->
                   file.write(
                       """
                           fun helloWorld(): Unit {
                               println("Hello world from function generated by KSP")
                           }
                       """.trimIndent()
                   ) 
               } 
           } 
       }
    
       // 3️⃣ createNewFileFrom() function
       private fun createNewFileFrom(function: KSFunctionDeclaration): OutputStream { 
           return codeGenerator.createNewFile(
              dependencies = createDependencyOn(function),
              packageName = "",
              fileName = "GeneratedHelloWorld"
           )
       }
    
       // 3️⃣ createDependencyOn() function
       private fun createDependencyOn(function: KSFunctionDeclaration): Dependencies {
           return Dependencies(aggregating = false, function.containingFile!!)
       }
    }
    
    // Utility function for writing string to OutputStream
    fun OutputStream.write(string: String): Unit {
        this.write(string.toByteArray())
    }
    

    Добавьте импорты, предложенные IDE. Убедитесь, что импортированы классы Resolver и Dependencies из com.google.devtools.ksp.processing. Также можно скопировать эти строки в начало файла HelloWorldProcessor.kt:

    // processor/src/main/kotlin/HelloWorldProcessor.kt import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.Dependencies import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.symbol.KSAnnotated import com.google.devtools.ksp.symbol.KSFunctionDeclaration import com.google.devtools.ksp.symbol.KSVisitorVoid import com.google.devtools.ksp.validate import java.io.OutputStream

    Рассмотрим код подробнее:

    • 1️⃣ Функция process() содержит основную логику процессора. Она получает все символы, помеченные аннотацией HelloWorldAnnotation, и вызывает для каждого из них HelloWorldVisitor.

      Функция process() возвращает список необработанных символов, которые будут обработаны в следующем раунде. В этом примере она безопасно возвращает emptyList(). Подробнее см. в разделе Обработка в несколько раундов.

    • 2️⃣ Процессоры обходят представление абстрактного синтаксического дерева Kotlin (AST) в KSP с помощью посетителей. Внутри класса HelloWorldPocessor класс HelloWorldVisitor выполняет роль посетителя. Поскольку HelloWorldAnnotation используется только для функции, переопределяется только visitFunctionDeclaration().

      KSVisitorVoid — один из классов посетителей, предоставляемых KSP, который можно переопределить и адаптировать. Можно также создать собственный класс посетителя, реализовав интерфейс KSVisitor<D, R>.

    • 3️⃣ createNewFileFrom() создаёт файл, в который KSP генерирует код. createDependencyOn() связывает выходной файл с исходным файлом, в котором используется аннотация.

      Подробнее о том, как KSP создаёт файлы и управляет ими, см. исходный код интерфейса CodeGenerator

  4. Создайте файл HelloWorldProcessorProvider.kt. Объявите в нём класс HelloWorldProcessorProvider, наследующий SymbolProcessorProvider:

    // processor/src/main/kotlin/HelloWorldProcessorProvider.kt
    
    import com.google.devtools.ksp.processing.SymbolProcessor
    import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
    import com.google.devtools.ksp.processing.SymbolProcessorProvider
    
    class HelloWorldProcessorProvider : SymbolProcessorProvider {  
        override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {  
            return HelloWorldProcessor(environment.codeGenerator)  
        }  
    }
    
  5. Зарегистрируйте поставщик процессора. В каталоге resources/META-INF/services создайте файл com.google.devtools.ksp.processing.SymbolProcessorProvider и укажите полное имя поставщика:

    ## processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
    
    HelloWorldProcessorProvider
    

Использование процессора

Теперь можно протестировать процессор. Выполните следующие действия, чтобы создать клиентский модуль и сгенерировать код на основе элемента с аннотацией:

  1. Создайте модуль с именем app в корне проекта.

  2. В файле build.gradle(.kts) этого модуля:

    • Добавьте плагин KSP в блок plugins {}.

    • Добавьте процессор и аннотацию в блок dependencies {}.

    Например:

    // app/build.gradle.kts
    
    plugins {
        kotlin("jvm")
        id("com.google.devtools.ksp")
    }
    
    dependencies { 
        implementation(project(":annotations"))
        ksp(project(":processor"))
    }
    
    // app/build.gradle
    
    plugins {
        id 'com.google.devtools.ksp'
    }
    
    dependencies {
        implementation project (':annotations')
        ksp project (':processor')
    }
    
  3. Убедитесь, что все подмодули автоматически включены в файл settings.gradle(.kts) на уровне проекта:

    // settings.gradle.kts
    
    include("annotations")
    include("app")
    include("processor")
    
    // settings.gradle
    
    include 'processor'
    include 'annotations'
    include 'app'
    
  4. В модуле app создайте файл Main.kt и добавьте следующий код:

    // app/src/main/kotlin/Main.kt
    
    import com.example.annotations.HelloWorldAnnotation
    
    @HelloWorldAnnotation
    fun main() {
        helloWorld()
    }
    

    Функция main() вызывает helloWorld(), хотя этой функции ещё не существует. IDE выделит helloWorld() как неразрешённую ссылку. Это ожидаемо: KSP сгенерирует функцию helloWorld() при сборке и запуске проекта.

  5. Запустите программу. В консоли отобразится результат выполнения функции helloWorld():

    Hello world from function generated by KSP
    

    KSP генерирует код в файле GeneratedHelloWorld.kt:

    app/build/generated/ksp/main/kotlin/GeneratedHelloWorld.kt
    

Изучение структуры проекта

Итоговая структура файлов проекта должна выглядеть так:

. ├── app │ ├── build.gradle.kts │ └── src │ └── main │ └── kotlin │ └── Main.kt ├── annotations │ ├── build.gradle.kts │ └── src │ └── main │ └── kotlin | └── com | └── example | └── annotations | └── HelloWorldAnnotation.kt ├── processor │ ├── build.gradle.kts │ └── src │ └── main │ ├── kotlin │ │ ├── HelloWorldProcessor.kt │ │ └── HelloWorldProcessorProvider.kt │ └── resources/META-INF/services | └── com.google.devtools.ksp.processing.SymbolProcessorProvider ├── build.gradle.kts └── settings.gradle.kts

У вас могут быть дополнительные файлы и каталоги.

Что дальше?

  • Изучите полный код этого примера в репозитории KSP.

  • Найдите более сложные примеры из реальных проектов в репозитории KSP.

  • Просмотрите список библиотек, поддерживаемых KSP.

12 августа 2026 г.
API обработки символов KotlinПереход с kapt на KSP

© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/ksp-quickstart.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API