Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
KSPを使ってコード生成
Search
Takuji Nishibayashi
December 05, 2023
Technology
480
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
KSPを使ってコード生成
Takuji Nishibayashi
December 05, 2023
More Decks by Takuji Nishibayashi
See All by Takuji Nishibayashi
compose-hot-reload を試そうとした話
takuji31
0
160
CameraX使ってみた
takuji31
0
310
kotlinx.datetime 使ってみた
takuji31
0
1.1k
HiltのCustom Componentについて
takuji31
0
390
java.timeをAndroidで使う
takuji31
0
210
Kotlin Symbol Processing API (KSP) を使って Kotlin ア プリケーションの開発を効率化する
takuji31
1
3.2k
kotlinx.serialization
takuji31
0
700
kanmoba-returns-02.pdf
takuji31
0
300
AndroidXとKotlin Coroutines
takuji31
0
450
Other Decks in Technology
See All in Technology
攻撃と防御で学ぶAI時代のプロダクトセキュリティ演習
recruitengineers
PRO
8
2.2k
【CEDEC2026】グラフィックスエンジニアのためのニューラルシェーディング入門
cygames
PRO
0
130
モバイルアプリ開発概論2026
recruitengineers
PRO
4
500
DatadogのBits Chatが開発組織にもたらしたもの / What Bits Chat Has Brought Us
sms_tech
0
120
新しい SLO が良い感じにハマっている話
z63d
5
2.1k
Invisible to AI? Making TYPO3 Sites Quotable by AI Search Systems
wolfgangwagner
0
170
Agent 時代の Kaggle 展望 / kaggle-in-the-agentic-era
upura
1
670
個人OSSが、机の上から世界に広がるまでの話
shinyasaita
1
370
社内の7割が使うデータ基盤を、 データチーム2人で回すためにやったこと
koh_yoshi
4
1.2k
システム思考で問題に対処する
yussak
0
210
20分でわかるセキュアAPI
nwiizo
1
200
『三匹の子ぶた』から学ぶネットワークセキュリティの昔と今 / Network Security: Then and Now Through the Lens of The Three Little Pigs
nttcom
1
1.8k
Featured
See All Featured
Optimizing for Happiness
mojombo
378
71k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
How to build a perfect <img>
jonoalderson
1
5.9k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
Technical Leadership for Architectural Decision Making
baasie
3
470
Writing Fast Ruby
sferik
630
63k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
210
The Mindset for Success: Future Career Progression
greggifford
PRO
0
440
Transcript
KSP を使ってコード生成 関西モバイルアプリ研究会 A @takuji31
自己紹介 西林 拓志(にしばやし たくじ) Twitter/GitHub takuji31 株式会社はてな Android アプリケーションエンジ ニア
Android (2009〜) Kotlin (2014〜) 2
KSP 使ってますか? 3
今日は KSP のプロセッサーの作り方(≠ 使い方)について話 します 4
KSP? 5
Kotlin Symbol Processor 6
google/ksp 7
コードにつけられたアノテーションを処理する 8
Kotlin friendly 9
Incremental proccessing 10
KMP 対応 11
Supported libs Dagger / Hilt (alpha) Room Moshi Glide etc.
12
プロセッサーの 作り方 13
source code // これを @SimpleGeneration interface Hoge // こうだ abstract
class AbstractHoge: Hoge 14
build.gradle.kts // ... dependencies { // KSP のAPI implementation("com.google.devtools.ksp:symbol-processing-api:1.9.21-1.0.15") //
KotlinPoet implementation("com.squareup:kotlinpoet:1.15.3") // KotlinPoet のKSP 用拡張 implementation("com.squareup:kotlinpoet-ksp:1.15.3") } 15
SymbolProcessor class ExampleSymbolProcessor( private val codeGenerator: CodeGenerator, private val logger:
KSPLogger ) : SymbolProcessor { override fun process(resolver: Resolver): List<KSAnnotated> { resolver .getSymbolsWithAnnotation(SimpleGeneration::class.qualifiedName!!) .filterIsInstance<KSClassDeclaration>() .forEach { it.accept(SimpleGenerationVisitor(codeGenerator, logger), Unit) } return emptyList() } } 16
Visitor class SimpleGenerationVisitor( private val codeGenerator: CodeGenerator, private val logger:
KSPLogger ) : KSVisitorVoid() { override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) { if (classDeclaration.classKind != ClassKind.INTERFACE) { logger.error("Only interface allowed", classDeclaration) return } val packageName = classDeclaration.packageName.asString() val className = ClassName(packageName, "Abstract" + classDeclaration.simpleName.asString()) val typeSpec = TypeSpec.classBuilder(className) .addModifiers(KModifier.ABSTRACT) .addSuperinterface(classDeclaration.toClassName()) FileSpec.builder(packageName, className.simpleName) .addType(typeSpec.build()) .build() .writeTo( codeGenerator, Dependencies( aggregating = false, classDeclaration.containingFile!! ) ) } } 17
SymbolProcessorProvider class ExampleSymbolProcessorProvider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment):
SymbolProcessor { return ExampleSymbolProcessor(environment.codeGenerator, environment.logger) } } 18
Service Provider // resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider jp.takuji31.kotlinfest2022.compiler.ExampleSymbolProcessorProvider 19
Incremental Processing 20
生成するファイルの依存を定義すれば Processor 側で適 切に処理される 21
Isolated 22
1:N 23
Isolated Dependencies(aggregating = false, classDeclaration.containingFile!!) 24
Aggregated 25
N:1 26
Aggregated (集約) val dependencies: Array<KSAnnotated> = // ... Dependencies(aggregating =
true, *dependencies.mapNotNull { it.containingFile }) 27
依存をちゃんと指定しないと「なぜかコード生成されな い」みたいな事態になる 28
テスト 29
tschuchortdev/kotlin-compile-testing 30
テストコード val source = SourceFile.kotlin( "ExampleClass.kt", """ package jp.takuji31.kotlinfest2022.compiler import
jp.takuji31.kotlinfest2022.compiler.annotation.SimpleGeneration @SimpleGeneration interface SimpleInterface { fun printHelloWorld() } """.trimIndent() ) 31
テストコード val compilation = KotlinCompilation().apply { sources = listOf(source) inheritClassPath
= true symbolProcessorProviders = listOf(ExampleSymbolProcessorProvider()) kspWithCompilation = true } val result = compilation.compile() assertThat(result.exitCode) .isEqualTo(KotlinCompilation.ExitCode.OK) 32
ドキュメント/サンプルコード https://kotlinlang.org/docs/ksp-overview.html 公式ドキュメント https://github.com/google/ksp/tree/main/examples/playground 公式サンプル https://github.com/takuji31/kotlinfest2022-ksp-example 今回のスライドに出てきたソースコード https://github.com/takuji31/navigation-compose-screen 複雑な例 https://speakerdeck.com/takuji31/kotlin-symbol-processing-api-ksp-woshi-tute-
kotlin-a-purikesiyonnokai-fa-woxiao-lu-hua-suru Kotlin Fest 2022 で発表した時のスライド もう少し踏み込んだ話はこちら 33
Enjoy KSP Life! 34