Spec-Zone.ru › Kotlin 1.7

API обработки символов Kotlin

Kotlin Symbol Processing (KSP) — это API, которое можно использовать для разработки лёгких плагинов компилятора. KSP предоставляет упрощённый API плагинов компилятора, использующий мощь Kotlin, при этом сохраняя минимальный порог вхождения. По сравнению с kapt, обработчики аннотаций, использующие KSP, могут работать до 2 раз быстрее.

Чтобы узнать больше о том, как KSP сравнивается с kapt, ознакомьтесь со статьёй почему KSP. Чтобы начать писать обработчик KSP, ознакомьтесь с быстрым началом работы с KSP.

Обзор

API KSP обрабатывает Kotlin-программы в естественной манере. KSP понимает особенности Kotlin, такие как расширяющие функции, вариативность на уровне объявления и локальные функции. Он также явно моделирует типы и предоставляет базовые проверки типов, такие как эквивалентность и совместимость присваивания.

API моделирует структуры Kotlin-программ на уровне символов в соответствии с грамматикой Kotlin. При обработке программ исходного кода плагинами на основе KSP, такие конструкции, как классы, члены класса, функции и связанные параметры, доступны для обработчиков, в то время как такие вещи, как if блоки и for циклы, недоступны.

По концепции, KSP похож на KType в рефлексии Kotlin. API позволяет обработчикам переходить от объявлений классов к соответствующим типам со специфическими аргументами типа и наоборот. Вы также можете подставлять аргументы типа, указывать вариации, применять проекции звёздочек и отмечать обязательность типов.

Другой способ понять KSP — как фреймворк для предобработки Kotlin-программ. Рассматривая плагины на основе KSP как обработчики символов или просто обработчики, поток данных в компиляции можно описать следующими шагами:

  1. Обработчики считывают и анализируют исходные программы и ресурсы.

  2. Обработчики генерируют код или другие формы вывода.

  3. Компилятор Kotlin компилирует исходные программы вместе с сгенерированным кодом.

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

Вы также можете получить обзор KSP в этом видео:

Как KSP рассматривает исходные файлы

Большинство обработчиков перемещаются по различным структурам программы входного исходного кода. Прежде чем углубиться в использование API, давайте посмотрим, как файл может выглядеть с точки зрения KSP:

KSFile
  packageName: KSName
  fileName: String
  annotations: List<KSAnnotation>  (File annotations)
  declarations: List<KSDeclaration>
    KSClassDeclaration // class, interface, object
      simpleName: KSName
      qualifiedName: KSName
      containingFile: String
      typeParameters: KSTypeParameter
      parentDeclaration: KSDeclaration
      classKind: ClassKind
      primaryConstructor: KSFunctionDeclaration
      superTypes: List<KSTypeReference>
      // contains inner classes, member functions, properties, etc.
      declarations: List<KSDeclaration>
    KSFunctionDeclaration // top level function
      simpleName: KSName
      qualifiedName: KSName
      containingFile: String
      typeParameters: KSTypeParameter
      parentDeclaration: KSDeclaration
      functionKind: FunctionKind
      extensionReceiver: KSTypeReference?
      returnType: KSTypeReference
      parameters: List<KSValueParameter>
      // contains local classes, local functions, local variables, etc.
      declarations: List<KSDeclaration>
    KSPropertyDeclaration // global variable
      simpleName: KSName
      qualifiedName: KSName
      containingFile: String
      typeParameters: KSTypeParameter
      parentDeclaration: KSDeclaration
      extensionReceiver: KSTypeReference?
      type: KSTypeReference
      getter: KSPropertyGetter
        returnType: KSTypeReference
      setter: KSPropertySetter
        parameter: KSValueParameter

Этот вид отображает общие вещи, объявленные в файле: классы, функции, свойства и так далее.

SymbolProcessorProvider: точка входа

KSP ожидает реализацию интерфейса SymbolProcessorProvider для создания экземпляров SymbolProcessor:

interface SymbolProcessorProvider {
    fun create(environment: SymbolProcessorEnvironment): SymbolProcessor
}

В то время как SymbolProcessor определён как:

interface SymbolProcessor {
    fun process(resolver: Resolver): List<KSAnnotated> // Let's focus on this
    fun finish() {}
    fun onError() {}
}

Обработчик Resolver предоставляет SymbolProcessor доступ к деталям компилятора, таким как символы. Обработчик, который находит все функции верхнего уровня и нелокальные функции в классах верхнего уровня, может выглядеть примерно так:

class HelloFunctionFinderProcessor : SymbolProcessor() {
    // ...
    val functions = mutableListOf<String>()
    val visitor = FindFunctionsVisitor()

    override fun process(resolver: Resolver) {
        resolver.getAllFiles().map { it.accept(visitor, Unit) }
    }

    inner class FindFunctionsVisitor : KSVisitorVoid() {
        override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
            classDeclaration.getDeclaredFunctions().map { it.accept(this, Unit) }
        }

        override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
            functions.add(function)
        }

        override fun visitFile(file: KSFile, data: Unit) {
            file.declarations.map { it.accept(this, Unit) }
        }
    }
    // ...
    
    class Provider : SymbolProcessorProvider {
        override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = TODO()
    }
}

Ресурсы

  • Быстрый старт

  • Почему использовать KSP?

  • Примеры

  • Как KSP моделирует Kotlin-код

  • Справочник для авторов обработчиков аннотаций Java

  • Заметки по инкрементальной обработке

  • Заметки по обработке в несколько раундов

  • KSP в многоплатформенных проектах

  • Запуск KSP из командной строки

  • Вопросы и ответы

Поддерживаемые библиотеки

В таблице ниже представлен список популярных библиотек на Android и различные стадии их поддержки KSP.

Библиотека

Статус

Задача отслеживания для KSP

Room

Официально поддерживается

Moshi

Официально поддерживается

RxHttp

Официально поддерживается

Kotshi

Официально поддерживается

Lyricist

Официально поддерживается

Последнее изменение: 23 мая 2022
Плагин компилятора Lombok Быстрый старт KSP

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

Spec-Zone.ru

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