Skip to content

KSP 快速入门

为了快速入门,你可以创建自己的处理器或获取一个示例处理器

添加处理器

要添加处理器,你需要包含 KSP Gradle 插件并添加对该处理器的依赖项:

  1. 将 KSP Gradle 插件 com.google.devtools.ksp 添加到你的 build.gradle(.kts) 文件中:

    kotlin
    plugins {
        id("com.google.devtools.ksp") version "2.2.0-2.0.2"
    }
    groovy
    plugins {
        id 'com.google.devtools.ksp' version '2.2.0-2.0.2'
    }
  2. 添加对该处理器的依赖项。 此示例使用 Dagger。请将其替换为你想要添加的处理器。

    kotlin
    dependencies {
        implementation("com.google.dagger:dagger-compiler:2.51.1")
        ksp("com.google.dagger:dagger-compiler:2.51.1")
    }
    groovy
    dependencies {
        implementation 'com.google.dagger:dagger-compiler:2.51.1'
        ksp 'com.google.dagger:dagger-compiler:2.51.1'
    }
  3. 运行 ./gradlew build。你可以在 build/generated/ksp 目录中找到生成的代码。

以下是一个完整示例:

kotlin
plugins {
    id("com.google.devtools.ksp") version "2.2.0-2.0.2"
    kotlin("jvm")
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib-jdk8"))
    implementation("com.google.dagger:dagger-compiler:2.51.1")
    ksp("com.google.dagger:dagger-compiler:2.51.1")
}
groovy
plugins {
    id 'com.google.devtools.ksp' version '2.2.0-2.0.2'
    id 'org.jetbrains.kotlin.jvm' version '2.2.10'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.2.10'
    implementation 'com.google.dagger:dagger-compiler:2.51.1'
    ksp 'com.google.dagger:dagger-compiler:2.51.1'
}

创建自己的处理器

  1. 创建一个空的 Gradle 项目。

  2. 在根项目中指定 Kotlin 插件的 2.2.0 版本,以便在其他项目模块中使用:

    kotlin
    plugins {
        kotlin("jvm") version "2.2.0" apply false
    }
    
    buildscript {
        dependencies {
            classpath(kotlin("gradle-plugin", version = "2.2.0"))
        }
    }
    groovy
    plugins {
        id 'org.jetbrains.kotlin.jvm' version '2.2.0' apply false
    }
    
    buildscript {
        dependencies {
            classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0'
        }
    }
  3. 添加一个承载处理器的模块。

  4. 在模块的构建脚本中,应用 Kotlin 插件并将 KSP API 添加到 dependencies 代码块中。

    kotlin
    plugins {
        kotlin("jvm")
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation("com.google.devtools.ksp:symbol-processing-api:2.2.0-2.0.2")
    }
    groovy
    plugins {
        id 'org.jetbrains.kotlin.jvm' version '2.2.10'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'com.google.devtools.ksp:symbol-processing-api:2.2.0-2.0.2'
    }
  5. 你需要实现 com.google.devtools.ksp.processing.SymbolProcessorcom.google.devtools.ksp.processing.SymbolProcessorProvider。你的 SymbolProcessorProvider 实现将被作为服务加载,以实例化你实现的 SymbolProcessor。请注意以下几点:

    • 实现 SymbolProcessorProvider.create() 来创建 SymbolProcessor。通过 SymbolProcessorProvider.create() 的实参传递处理器所需的依赖项(例如 CodeGenerator、处理器选项)。
    • 你的主要逻辑应该位于 SymbolProcessor.process() 方法中。
    • 使用 resolver.getSymbolsWithAnnotation() 来获取要处理的符号,给定注解的完全限定名。
    • KSP 的一个常见用例是为操作符号实现定制的访问者(接口 com.google.devtools.ksp.symbol.KSVisitor)。一个简单的模板访问者是 com.google.devtools.ksp.symbol.KSDefaultVisitor
    • 有关 SymbolProcessorProviderSymbolProcessor 接口的示例实现,请参阅示例项目中的以下文件。
      • src/main/kotlin/BuilderProcessor.kt
      • src/main/kotlin/TestProcessor.kt
    • 编写自己的处理器后,通过在 src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider 中包含其完全限定名,将处理器提供者注册到包中。

在项目中运用自己的处理器

  1. 创建另一个模块,其中包含你希望试用处理器的“工作负载”。

    kotlin
    pluginManagement { 
        repositories { 
            gradlePluginPortal()
        }
    }
    groovy
    pluginManagement {
        repositories {
            gradlePluginPortal()
        }
    }
  2. 在模块的构建脚本中,应用 com.google.devtools.ksp 插件并指定版本,然后将你的处理器添加到依赖项列表中。

    kotlin
    plugins {
        id("com.google.devtools.ksp") version "2.2.0-2.0.2"
    }
    
    dependencies {
        implementation(kotlin("stdlib-jdk8"))
        implementation(project(":test-processor"))
        ksp(project(":test-processor"))
    }
    groovy
    plugins {
        id 'com.google.devtools.ksp' version '2.2.0-2.0.2'
    }
    
    dependencies {
        implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.2.10'
        implementation project(':test-processor')
        ksp project(':test-processor')
    }
  3. 运行 ./gradlew build。你可以在 build/generated/ksp 下找到生成的代码。

以下是将 KSP 插件应用到工作负载的示例构建脚本:

kotlin
plugins {
    id("com.google.devtools.ksp") version "2.2.0-2.0.2"
    kotlin("jvm") 
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib-jdk8"))
    implementation(project(":test-processor"))
    ksp(project(":test-processor"))
}
groovy
plugins {
    id 'com.google.devtools.ksp' version '2.2.0-2.0.2'
    id 'org.jetbrains.kotlin.jvm' version '2.2.10'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.2.10'
    implementation project(':test-processor')
    ksp project(':test-processor')
}

向处理器传递选项

SymbolProcessorEnvironment.options 中的处理器选项在 Gradle 构建脚本中指定:

none
ksp {
    arg("option1", "value1")
    arg("option2", "value2")
    ...
}

让 IDE 识别生成的代码

生成的源文件自 KSP 1.8.0-1.0.9 起已自动注册。 如果你使用的是 KSP 1.0.9 或更高版本,并且不需要让 IDE 识别生成的资源, 可以跳过此部分。

默认情况下,IntelliJ IDEA 或其他 IDE 不识别生成的代码。因此,它会将对生成符号的引用标记为无法解析。为了让 IDE 能够理解生成的符号,请将以下路径标记为生成源代码根目录:

text
build/generated/ksp/main/kotlin/
build/generated/ksp/main/java/

如果你的 IDE 支持资源目录,也请标记以下目录:

text
build/generated/ksp/main/resources/

在 KSP 消费者模块的构建脚本中配置这些目录也可能是必要的:

kotlin
kotlin {
    sourceSets.main {
        kotlin.srcDir("build/generated/ksp/main/kotlin")
    }
    sourceSets.test {
        kotlin.srcDir("build/generated/ksp/test/kotlin")
    }
}
groovy
kotlin {
    sourceSets {
        main.kotlin.srcDirs += 'build/generated/ksp/main/kotlin'
        test.kotlin.srcDirs += 'build/generated/ksp/test/kotlin'
    }
}

如果你在 Gradle 插件中使用 IntelliJ IDEA 和 KSP,那么上述代码片段将给出以下警告:

text
Execution optimizations have been disabled for task ':publishPluginJar' to ensure correctness due to the following reasons:
Gradle detected a problem with the following location: '../build/generated/ksp/main/kotlin'. 
Reason: Task ':publishPluginJar' uses this output of task ':kspKotlin' without declaring an explicit or implicit dependency.

在这种情况下,请改用以下脚本:

kotlin
plugins {
    // ...
    idea
}

idea {
    module {
        // Not using += due to https://github.com/gradle/gradle/issues/8749
        sourceDirs = sourceDirs + file("build/generated/ksp/main/kotlin") // or tasks["kspKotlin"].destination
        testSourceDirs = testSourceDirs + file("build/generated/ksp/test/kotlin")
        generatedSourceDirs = generatedSourceDirs + file("build/generated/ksp/main/kotlin") + file("build/generated/ksp/test/kotlin")
    }
}
groovy
plugins {
    // ...
    id 'idea'
}

idea {
    module {
        // Not using += due to https://github.com/gradle/gradle/issues/8749
        sourceDirs = sourceDirs + file('build/generated/ksp/main/kotlin') // or tasks["kspKotlin"].destination
        testSourceDirs = testSourceDirs + file('build/generated/ksp/test/kotlin')
        generatedSourceDirs = generatedSourceDirs + file('build/generated/ksp/main/kotlin') + file('build/generated/ksp/test/kotlin')
    }
}