Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
KSPを使ってコード生成
Search
Takuji Nishibayashi
December 05, 2023
Technology
500
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
170
CameraX使ってみた
takuji31
0
330
kotlinx.datetime 使ってみた
takuji31
0
1.2k
HiltのCustom Componentについて
takuji31
0
450
java.timeをAndroidで使う
takuji31
0
220
Kotlin Symbol Processing API (KSP) を使って Kotlin ア プリケーションの開発を効率化する
takuji31
1
3.3k
kotlinx.serialization
takuji31
0
720
kanmoba-returns-02.pdf
takuji31
0
310
AndroidXとKotlin Coroutines
takuji31
0
460
Other Decks in Technology
See All in Technology
二歩目のフロントエンド・ウェブアクセシビリティ
camiha
2
390
FOSS4Gを活用した自治体業務DXの試み
470715
0
150
Getting Started with Google Antigravity
glaforge
0
220
AgentCoreで実践するハーネスエンジニアリング
yakumo
1
300
⾮構造化データを価値に変える AI エージェント基盤とその組織
ivry_presentationmaterials
0
140
生成AIで高い生産性を求められて、 悩み、乗り越えた話
mot_techtalk
2
170
DWH の限界突破! AI エージェント向け爆速リアルタイムデータ基盤 ClickHouse
jozono
1
390
DGX Spark でどこまでハッキングができるのか?
kash1064
0
950
Snapshot Testing in Practice: Predictable and Reliable SwiftUI Views
fespinoza
0
200
【Data Engineering Summit2026_登壇資料】医療ビッグデータ×AIエージェントを支えるデータ基盤とハーネスエンジニアリング
jmdc_presentation
0
130
メルペイ 会計システム概要と歴史
mewuto
1
210
AI 時代の Azure エンジニアリング ~ 私たちは何を磨き、何を任せるのか ~
chack411
1
600
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.1k
Color Theory Basics | Prateek | Gurzu
gurzu
1
490
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
The SEO identity crisis: Don't let AI make you average
varn
0
590
Deep Space Network (abreviated)
tonyrice
0
370
Design in an AI World
tapps
1
350
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
280
Six Lessons from altMBA
skipperchong
29
4.5k
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