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
ASTで作るコンストラクタジェネレータ
Search
Takeru Furuse
August 08, 2024
Programming
69
0
Share
ASTで作るコンストラクタジェネレータ
Takeru Furuse
August 08, 2024
Other Decks in Programming
See All in Programming
実践ハーネスエンジニアリング:ステアリングループを実例から読み解く / Practical Harness Engineering: Understanding Steering Loops Through Real-World Examples
nrslib
5
5.8k
UaaL×Androidアプリのメモリ計測 — Memory Profilerの先へ
rio432
0
160
Migrations : C'est une question d'hygiène !
vinceamstoutz
0
680
Agentic UI in the Frontend: Architectures with Open Standards @JAX 2026 in Mainz
manfredsteyer
PRO
0
120
Structured Concurrency, Scoped Values and Joiners in the JDK 25 26 27
josepaumard
1
160
【ディップ|26年新卒研修資料】TDD実装演習
dip_tech
PRO
0
280
iOS26時代の新規アプリ開発
yuukiw00w
0
160
サーバーレスで作る、動画データ管理基盤
oyasumipants
0
230
AIチームを指揮するOSS「TAKT」活用術 / How to Use “TAKT,” an OSS Tool for Orchestrating AI Teams
nrslib
0
150
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
590
密結合なバックエンドから TypeScript のコードを生成する
kemuridama
1
260
なぜあなたのコードには「コシ」がないのか?〜AI時代に問う、最後まで美味しい設計と戦略〜 #phpconkagawa / phpconkagawa2026
shogogg
0
210
Featured
See All Featured
Utilizing Notion as your number one productivity tool
mfonobong
4
300
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
110k
Code Reviewing Like a Champion
maltzj
528
40k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Building the Perfect Custom Keyboard
takai
2
770
RailsConf 2023
tenderlove
30
1.4k
Un-Boring Meetings
codingconduct
0
290
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
180
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
230
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
170
Transcript
ASTで作るコンストラクタジェネレータ 2024/08/08 golang.tokyo #36
About me 古瀬 たける / Takeru Furuse • 株式会社enechain (2023/12〜)
• エンジニア歴は約10年 • Go / Python / Typescriptをよく書きます • https://github.com/tsuperis3112 2024/8/8 1 Introduction
Todayʼs topic • コンストラクタジェネレータを作った話 • go/ast, go/types, golang.org/x/tools/go/packages等の使い分け • Genericsへの対応
• ASTでコード⽣成するときのハマりどころ 2024/8/8 2 Introduction
コンストラクタジェネレータとは What is a Constructor Generator? 3
モチベーション • ドメイン知識が複雑でエンティティのフィールドに変更が多数発 ⽣し構造体の初期化箇所でデグレが頻発 • Pythonのdataclass/pydantic(下図)やJavaのlombokのように⾃動で コンストラクタを⽣成してほしい 2024/8/8 4 コンストラクタジェネレータとは
概要 • 構造体に定義されたフィールド名、型を引数に取る関数 • embedされた構造体の各フィールドについても構造体名+フィール ド名のlower camel-caseを引数に取る • 構造体のポインタを返す •
同名の関数がパッケージ内に存在していれば、⽣成をスキップ 2024/8/8 5 コンストラクタジェネレータとは
出⼒イメージ 2024/8/8 6 コンストラクタジェネレータとは
設計・実装 Design and implementation 7
ファイル単位 パッケージ単位 AST関連のパッケージ群の役割 - 1 • golang.org/x/tools/go/packages • パッケージ情報を持つ •
*types.Scopeや[]*ast.Fileを参照 • go/types • 型情報 • *packages.Packageを参照 • go/ast • 構⽂の情報を持つ • 型の情報は含まない • go/token • リテラルや演算⼦などの構⽂中のトークン 2024/8/8 8 golang.org/x/tools/go/packages go/types go/ast go/token 設計・実装
AST関連のパッケージ群の役割 - 2 • golang.org/x/tools/go/packages • 何よりもまず*packages.Packageが起点になる • Embeddedされた構造体で利⽤されるフィールドの型など、不⾜しているimportを補う際に 利⽤
• Scopeを利⽤してgo/astとgo/typesの紐づけを⾏う • go/types • 構造体やフィールドの型情報を取得するために利⽤ • go/ast • Genericsの型引数に再帰的に値をアサインしていく 2024/8/8 9 設計・実装
型情報をトラ バース 型情報を⽊構 造のノードに 格納 ルートノード から型引数を マッピングし ていく リーフノード
から引数の情 報を⽣成する astutilで関数 を⽣成 全体の処理フロー 2024/8/8 設計・実装 10
構造体の定義 • StructMap • 必要な構造体の情報をキャッシュ • キーは「パッケージパス.構造体名」 • types.TypeName.Idと⼀致 •
依存関係を元に*ast.Fileにimportを追加する • Node • StructMapを元に出⼒される構造体 • この構造体を元にASTを構築してでコンストラクタを⽣成 2024/8/8 設計・実装 11
型情報のトラバース • *packages.Packageを起点にし て依存関係のあるパッケージ に含まれる構造体情報を取得 する 2024/8/8 12 設計・実装
Generics対応 • ここでも再帰的に型引数をアサ インしていく • ここでアサインした型引数を更 にネストされたGenerics構造体 にも適⽤する • 型パラメータ名を取得するため
にStructInfoにtypes.TypeSpecを 持たせている 2024/8/8 設計・実装 13
AST構築 • typeParamsはルートノードか ら取得 • Paramsはリーフノードから ⽣成 • compositeFieldsはルート ノードから再帰的に⽣成する
2024/8/8 設計・実装 14
振り返り Reflection 15
実装してみて • 複数のパッケージをまたぐことで型情報のパースが単純にはでき なかった • embedの循環参照が可能であったりと制約が⽐較的緩めなので、 ⾃前で制御する必要がある箇所が多かった • 再帰、再帰、再帰、再帰、、、 2024/8/8
振り返り 16
今後の展望 • OSS化 • フィールド値の⽣成関数対応 • UUIDなどを⾃動で⽣成してアサインさせる • バリデーション対応 •
現在は⽣成対象外フィールドだけタグで指定できるようにしている • go-playground/validatorなどをラップする形? • プラグイン対応 • 初期化時になにかの処理をHookさせられるようにしたい 2024/8/8 振り返り 17
ご清聴ありがとうございました Thank you for your attention 18