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
ASTで作るコンストラクタジェネレータ
Search
Takeru Furuse
August 08, 2024
Programming
89
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ASTで作るコンストラクタジェネレータ
Takeru Furuse
August 08, 2024
Other Decks in Programming
See All in Programming
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1k
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
130
Verilogで学ぶCPU自作入門.pdf
uyuki234
7
3.8k
iOSDCのペンライトを自動制御したい!
akkeylab
0
200
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
4
190
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2k
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
8
5.2k
Webの地図
yosuke_furukawa
PRO
6
5k
FreeBSDでZabbixを動かす
kenkino
0
340
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
750
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
460
Featured
See All Featured
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
Mobile First: as difficult as doing things right
swwweet
225
10k
Building Adaptive Systems
keathley
44
3.2k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.2k
The Curse of the Amulet
leimatthew05
3
15k
Raft: Consensus for Rubyists
vanstee
142
7.7k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
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