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
380
java.timeをAndroidで使う
takuji31
0
200
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
440
Other Decks in Technology
See All in Technology
SoccerMaster: A Vision Foundation Model for Soccer Understanding
kzykmyzw
0
140
「早く出す」より「事業に効く」 ── 顧客の業務サイクルから逆算するAI時代の二重ループ開発と「変化の設計者」 / devsumi2026
rakus_dev
1
400
Control Planeで育てるBtoB SaaSの認証基盤 - SRE NEXT 2026
pokohide
1
2.6k
Playwright × AI Agent でE2Eテストはどう変わるか AI駆動テストの可能性と実用検証の結果
taiga7543
1
300
SREとQA 二人三脚で進めるSLO運用/sre-qa-slo
sugitak
0
950
CDKで書くECSのベストプラクティス、 改めて考え直す2026 #cdkconf2026
makies
3
820
AI時代の開発生産性は、個人技からチーム設計へ
moongift
PRO
4
2.4k
Genie Ontologyは銀の弾丸かを考える / Is Genie Ontology a Silver Bullet?
nttcom
0
410
「AIに依存している」と 「AIを使いこなしている」の違い
k8yasuma
0
120
[2026-07-15] AI Ready なはずだったアーキテクチャと、見えてきた課題・次に目指す状態
wxyzzz
9
4k
AI時代のYAGNI:「爆速で無駄になった機能」からの学び / 20260720 Naoki Takahashi
shift_evolve
PRO
2
320
ファミコンでPHPを動かす / PHP on the Famicom
tomzoh
2
430
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Claude Code のすすめ
schroneko
67
230k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
770
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
180
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
190
4 Signs Your Business is Dying
shpigford
187
22k
Unsuck your backbone
ammeep
672
58k
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