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
0
53
ASTで作るコンストラクタジェネレータ
Takeru Furuse
August 08, 2024
Tweet
Share
Other Decks in Programming
See All in Programming
Claude Codeセッション現状確認 2026福岡 / fukuoka-aicoding-00-beacon
monochromegane
4
410
Agentic AI: Evolution oder Revolution
mobilelarson
PRO
0
150
Go1.26 go fixをプロダクトに適用して困ったこと
kurakura0916
0
360
LangChain4jとは一味違うLangChain4j-CDI
kazumura
1
170
どんと来い、データベース信頼性エンジニアリング / Introduction to DBRE
nnaka2992
1
280
AWS Infrastructure as Code の新機能 2025 総まとめ 〜SA 4人による怒涛のデモ祭り〜
konokenj
10
3.3k
Cyrius ーLinux非依存にコンテナをネイティブ実行する専用OSー
n4mlz
0
130
Codex の「自走力」を高める
yorifuji
0
1.2k
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
400
株式会社 Sun terras カンパニーデック
sunterras
0
2.1k
ベクトル検索のフィルタを用いた機械学習モデルとの統合 / python-meetup-fukuoka-06-vector-attr
monochromegane
2
390
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
510
Featured
See All Featured
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
440
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.5k
Building an army of robots
kneath
306
46k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
380
How Software Deployment tools have changed in the past 20 years
geshan
0
32k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.1k
Facilitating Awesome Meetings
lara
57
6.8k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
390
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.1k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
140
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
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