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
fmt
Search
ktr
January 25, 2018
Technology
0
4.1k
fmt
ktr
January 25, 2018
Tweet
Share
More Decks by ktr
See All by ktr
激動の一年を通じて見えてきた「技術でリードする」ということ
ktr_0731
8
9.6k
Monorepo における Go テストの差分実行 / Running Differential Go Tests in a Monorepo
ktr_0731
1
200
Designing libraries in Go way
ktr_0731
7
1.5k
Go Modules and Proxy Walkthrough
ktr_0731
8
27k
ソフトウェアの複雑さに立ち向かう技術 / Tackling software complexity
ktr_0731
0
210
Fuzzy finder as a Go library
ktr_0731
3
6k
つよくてニューゲーム / NewGame++
ktr_0731
0
1k
やはり俺の Go アプリケーション設計はまちがっている。 / My Go Application Design Is Wrong, As I Expected
ktr_0731
13
3.7k
GopherCon2018
ktr_0731
2
1.8k
Other Decks in Technology
See All in Technology
ClaudeCodeにキレない技術
gtnao
0
560
いつの間にか入れ替わってる!?新しいAWS Security Hubとは?
cmusudakeisuke
0
160
推し書籍📚 / Books and a QA Engineer
ak1210
0
120
【LT会登壇資料】TROCCO新コネクタ「スマレジ」を活用した直営店データの分析
kazari0425
1
170
[ JAWS-UG千葉支部 x 彩の国埼玉支部 ]ムダ遣い卒業!FinOpsで始めるAWSコスト最適化の第一歩
sh_fk2
2
150
NewSQLや分散データベースを支えるRaftの仕組み - 仕組みを理解して知る得意不得意
hacomono
PRO
3
230
20250708オープンエンドな探索と知識発見
sakana_ai
PRO
4
860
Delegating the chores of authenticating users to Keycloak
ahus1
0
180
Delta airlines®️ USA Contact Numbers: Complete 2025 Support Guide
airtravelguide
0
350
対話型音声AIアプリケーションの信頼性向上の取り組み
ivry_presentationmaterials
2
690
AIエージェントが書くのなら直接CloudFormationを書かせればいいじゃないですか何故AWS CDKを使う必要があるのさ
watany
18
7k
第64回コンピュータビジョン勉強会「The PanAf-FGBG Dataset: Understanding the Impact of Backgrounds in Wildlife Behaviour Recognition」
x_ttyszk
0
170
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
Fireside Chat
paigeccino
37
3.5k
Designing for humans not robots
tammielis
253
25k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
20
1.3k
Producing Creativity
orderedlist
PRO
346
40k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
181
54k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.6k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Docker and Python
trallard
45
3.5k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
Transcript
fmt fmt 1
$ whoami $ whoami (id:|@)ktr_0731 サーバサイドエンジニ ア STEINS;GATE / 響け!ユーフォニア
ム 2
3
ktr0731/evans ktr0731/evans more expressive gRPC client more expressive gRPC client
4
fmt? fmt? コードフォーマッタ ソースコードを 強制的 に整形してくれ る 5
gofmt YAPF Prettier scalafmt etc. 6
gofmt を読む gofmt を読む golang/go/src/cmd/gofmt 7
前提環境 前提環境 golang/go master (157d8cfbc13fbc4c849075e905b0001fb248b5e6) 8
cmd/gofmt/gofmt.go cmd/gofmt/gofmt.go gofmtMain() gofmtMain() for i := 0; i <
flag.NArg(); i++ { path := flag.Arg(i) switch dir, err := os.Stat(path); { case err != nil: report(err) case dir.IsDir(): walkDir(path) // NOTE; call processFil default: if err := processFile(path, nil, os.St report(err) } } } 9
cmd/gofmt/gofmt.go cmd/gofmt/gofmt.go processFile() processFile() file, sourceAdj, indentAdj, err := parse(fileSet,
filename, sr if err != nil { return err } 10
cmd/gofmt/internal.go cmd/gofmt/internal.go parse() parse() parser.ParseFile file, err = parser.ParseFile(fset, filename,
psrc, parserMode) if err == nil { sourceAdj = func(src []byte, indent int) []byte { src = src[indent+len("package p\n"):] return bytes.TrimSpace(src) } 11
go/parser go/parser ParseFile() ParseFile() go/parser: 構文解析用パッケージ Go ソースコードから AST (
抽象構文木) を生 成 12
cmd/gofmt/gofmt.go cmd/gofmt/gofmt.go processFile() processFile() ast.SortImports(fileSet, file) if *simplifyAST { simplify(file)
} res, err := format(fileSet, file, sourceAdj, indentAdj, src, p if err != nil { return err } 13
cmd/gofmt/internal.go cmd/gofmt/internal.go format format var buf bytes.Buffer err := cfg.Fprint(&buf,
fset, file) if err != nil { return nil, err } return buf.Bytes(), nil 14
go/printer/printer.go go/printer/printer.go Fprint() → Fprint() → fprint() fprint() AST ノードを整形・出力するパッケージ
var p printer p.init(cfg, fset, nodeSizes) if err = p.printNode(node); err != nil { return } 15
go/printer/printer.go go/printer/printer.go printNode() printNode() switch n := node.(type) { case
ast.Expr: p.expr(n) case ast.Stmt: if _, ok := n.(*ast.LabeledStmt); ok { p.indent = 1 } p.stmt(n, false) case ast.Decl: p.decl(n) case ast.Spec: p.spec(n, 1, false) case []ast.Stmt: for _, s := range n { if _, ok := s.(*ast.LabeledStmt); ok { 16
printNode printNode AST を再帰的に辿り、 各ノードの持つ内容を整 形・出力する 17
例: 二項演算子のスペース 例: 二項演算子のスペース fmt.Println("Hello, "+"World") fmt.Println("Hello, " + "World")
18
AST AST の構造 の構造 0 *ast.CallExpr { 1 . Fun:
*ast.SelectorExpr { 2 . . X: *ast.Ident { 3 . . . NamePos: 1 4 . . . Name: "fmt" 5 . . . Obj: *ast.Object { 6 . . . . Kind: bad 7 . . . . Name: "" 8 . . . } 9 . . } 10 . . Sel: *ast.Ident { 11 . . . NamePos: 5 12 . . . Name: "Println" 13 . . } 14 . } 19
20
go/printer/printer.go go/printer/printer.go printNode() printNode() switch n := node.(type) { case
ast.Expr: p.expr(n) func (p *printer) expr(x ast.Expr) { const depth = 1 p.expr1(x, token.LowestPrec, depth) } 21
go/printer/nodes.go go/printer/nodes.go expr1() expr1() switch x := expr.(type) { case
*ast.BinaryExpr: if depth < 1 { p.internalError("depth < 1:", depth) depth = 1 } p.binaryExpr(x, prec1, cutoff(x, depth), depth) 22
go/printer/nodes.go go/printer/nodes.go binaryExpr() binaryExpr() ( 一部略) ( 一部略) // X
評価 p.expr1(x.X, prec, depth+diffPrec(x.X, prec)) if printBlank { // 追加 p.print(blank) } // "+" p.print(x.OpPos, x.Op) if printBlank { // 追加 p.print(blank) } // Y 評価 p.expr1(x.Y, prec+1, depth+1) 23
gofmt のフォーマットルール gofmt のフォーマットルール AST 生成までの過程で取り除かれるも の go/printer によって整形されるもの 24
AST AST 生成までの過程で取り除かれるもの 生成までの過程で取り除かれるもの 改行 スペー ス etc. 25
go/printer によって整形されるもの go/printer によって整形されるもの 二項演算子のスペース ( 前 述) 配列の最後の要素のカンマ etc.
[]string{"foo", "bar",} []string{"foo", "bar"} 26
似たようなのを実装してみる 似たようなのを実装してみる 27
ktr0731/markdownfmt ktr0731/markdownfmt 28
29
30
31
整形ルール 整形ルール 余計な改行・空白は取り除く テキストの最大長を 80 文字 に 32
整形ルール 整形ルール テキストの単語間のスペースは1つ に this is a text! this is
a text! 33
整形ルール 整形ルール 水平線 (hr) の上下に空 行 horizontal --- line horizontal
--- line 34
demo demo 35
これはデモ用のテキストです これはデモ用のテキストです this text is an example text for demonstration.
current version of markdownfmt accepts 80 charactors as the max width. so, maybe this text will be splitted to some lines. 36
まとめ まとめ AST なんでもできてすごい 特に Go は取得できる情報が多い AST を作れれば、フォーマットはそこまで難しく ない
意外と gofmt は読みやすい 37
参考 参考 printer - The Go Programming Language parser -
The Go Programming Language Go のための Go GitHub Flavored Markdown Spec 38