SlideShare a Scribd company logo
1 of 49
Download to read offline
The Go gopher was designed by Renée French.
The gopher stickers was made by Takuya Ueda.
Licensed under the Creative Commons 3.0 Attributions license.
静的解析を使った
開発ツールの開発
@kamakura.go #3
2018年1月20日(土)
自己紹介
上田拓也
@tenntenn
所属
コミュニティ活動
&
Go ビギナーズ
Go Conference
上田拓也
@tenntenn
2
ソウゾウ エキスパートチーム
技術をアウトプットするところに技術は集まる
■ エキスパートチームとは?
● 50%以上の時間を技術コミュニティへの貢献に充てる
■ エキスパートチームの役割
● 社内に新しい技術を取り取り込む
● 社外のコミュニティなどを通じて社会へ還元する
■ エキスパートチームの活動
● カンファレンス・勉強会の開催/運営
● 対外的な講演活動
● 執筆、雑誌への寄稿、インタビュー
● 社内外での担当技術の普及推進
@tenntenn
担当:Go・GCP
@mhidaka
担当:Android
メンバー
3
アジェンダ
■ Gopherを探せ!
■ 静的解析と開発ツール
■ Goにおける静的解析 〜基礎編〜
■ Goにおける静的解析 〜応用編〜
4
Gopherを探せ!
みつけてね
Powered by https://gopherize.me
5
Gopherを探せ!
みつけたかな?
Powered by https://gopherize.me
6
"Gopher"を探せ!
type Gopher struct { Gopher string `json:"gopher"` }
func main() {
const gopher = "GOPHER"
gogopher := GOPHER()
gogopher.Gopher = gopher
fmt.Println(gogopher)
}
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
return
}
7
みんな大好きgrep
$ grep Gopher main.go
type Gopher struct { Gopher string `json:"gopher"` }
gogopher.Gopher = gopher
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
grepで"Gopher"を探す
8
"Gopher" 型を探せ!
type Gopher struct { Gopher string `json:"gopher"` }
func main() {
const gopher = "GOPHER"
gogopher := GOPHER()
gogopher.Gopher = gopher
fmt.Println(gogopher)
}
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
return
}
9
"Gopher"型を探すには?
■ grep だと文字列としてしか検索できない
■ 文字列ではなくGoのソースコードとして
理解しないといけない
■ そこで静的解析を使う!
10
静的解析と開発ツール
11
静的解析と動的解析
■ 静的解析
● プログラムを実行せずに解析すること
● ソースコードを解析する
● 例:lint、コード補完、 コードフォーマッタ
■ 動的解析
● プログラムを実行して解析すること
● 実行時 変数 状態や関数 実行順などを検証
● 例:レースコンディション
12
リフレクション
■ リフレクション
● 実行時に型や値 情報を解析する
■ Goにおけるリフレクション
● reflectパッケージを使う
● 実行時にstructタグにアクセスする唯一の方法
● 出力引数としてポインタを貰ってきた場合に値を入れるために使用
● JSONやXMLなどのエンコードに使用
13
Goと静的解析
■ 静的解析しやすいように設計されている
● 静的型付け
● 文法がシンプル
● 型推論
● 暗黙の型変換がない
● 標準パッケージで静的解析の機能を提供
静的解析では多くの情報を取得できる
14
go パッケージ
go/ast 抽象構文木(AST)を提供
go/build パッケージに関する情報を集める
go/constant 定数に関する型を提供
go/doc ドキュメントをASTから取り出す
go/format コードフォーマッタ機能を提供
go/importer コンパイラに適したImporterを提供
go/parser 構文解析 機能を提供
go/printer AST 表示機能を提供
go/scanner 字句解析 機能を提供
go/token トークンに関する型を提供
go/types 型チェックに関する機能を提供
15
Goの静的解析ツール
■ Goには多くの静的解析ツールが存在する
gofmt/goimports コードフォーマッタ
go vet/golint コードチェッカー、リンター
guru 静的解析
gocode コード補完
errcheck エラー処理のチェック
gorename/gomvpkg リファクタリング
16
開発ツールへ静的解析を使う
■ 自作開発ツールでレビューコストを下げる
● 自動化できることは自動化する(カラクリ)
○ 自分のプロジェクト用にカスタマイズされたリンターを作る
○ よくあるバグを検出するツールを作る
● レビューの時間はもっと重要なことに使う
○ アルゴリズムの検証
○ 設計
○ パフォーマンス
■ コードやドキュメントを自動生成する
● マイグレーション
● ドキュメント生成
17
Goにおける静的解析
〜基礎編〜
18
静的解析の流れ
ソースコード
トークン
抽象構文木
(AST)
型情報
構文解析
字句解析
型チェック
go/scanner
go/token
go/parser
go/ast
go/types
go/constant
19
■ 入力された文字列をトークンとして分解
字句解析- go/scanner,go/token
IDENT ADD INT
トークン
ソースコード: v + 1
20
構文解析 - go/parser,go/ast
■ トークンを抽象構文木(AST)に変換
v + 1
IDENT ADD INT
ソースコード:
+
v 1
BinaryExpr
Ident BasicLit
トークン:
抽象構文(AST):
21
"Hello, World"の抽象構文木
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
Run on Playground
*ast.File
[]ast.Decl
*ast.GenDecl *ast.FuncDecl
22
型チェック - go/types,go/constant
■ 型情報を抽象構文木から抽出
● 識別子の解決
● 型の推論
● 定数の評価
n := 100 + 200
m := n + 300
定数の評価
= 300
型の推論
-> int
識別子の解決
23
ソースコードから抽象構文木の取得
■ parser.Parse* 系の関数を使う
● ParseExpr,ParseExprFrom
○ 式をパースする
○ ParseExpr は ParseExprFrom のシンプルバージョン
● ParseFile
○ ファイルをパースする
● ParseDir
○ ディレクトリ単位でパースする
○ 内部で ParseFile を呼んでいる
24
式の抽象構文木を取得する
expr, err := parser.ParseExpr(`v + 1`)
if err != nil {
/* handling the error */
}
/* use expr */
■ 式単位でパースする
25
ファイル単位で抽象構文木を取得
const src = `
package main
var v = 100
func main() {
fmt.Println(v+1)
}`
fs := token.NewFileSet()
f, err := parser.ParseFile(fs, "my.go", src, 0)
if err != nil {
/* handling the error */
}
/* use f */
srcがnilの場合だと
ファイル名を元にファイルが開かれる
ソースコード
パースモード
26
token.FileSet
■ ファイル中の位置情報を記録する為の型
● token.Posは数値として記録
● 複数ファイル間で共通の値が使われる
● token.FileSet は各ファイルのオフセットを記録
● オフセットはパース時に記録される
● token.FileSet はparser.Parse*系の関数に
出力引数として渡される
● 人間に分かりやすい情報を取得するにはFileSet.Positionを使用
type Pos int
27
func (s *FileSet) Position(p Pos) (pos Position)
デモ 1: 構文解析と抽象構文木の出力
28
https://youtu.be/lM1Pj6xYxZs
Demo Code: https://gist.github.com/tenntenn/833207ce1715089da23936b5dfaebea5
抽象構文木の探索- ast.Inspect
■ Using ast.Inspect
expr, _ := parser.ParseExpr(`v + 1`)
ast.Inspect(expr, func(n ast.Node) bool {
if n != nil { fmt.Printf("%Tn", n) }
return true
})
抽象構文木の探索
*ast.BinaryExpr
*ast.Ident
*ast.BasicLit
Playgroundで実行
ast.Walk はもっと複雑な処理ができる
+
v 1
BinaryExpr
Ident BasicLit
29
抽象構文木の探索 - 再帰
func traverse(n ast.Node) {
switch n := n.(type) {
case *ast.Ident:
fmt.Println(n.Name)
case *ast.BinaryExpr:
traverse(n.X)
traverse(n.Y)
case *ast.UnaryExpr:
traverse(n.X)
default:
fmt.Println(n)
}
}
識別子:識別子名を出力
2項演算式:各項について再帰的に探索
型で処理を分岐
Playgroundで実行
単項演算式:項を再帰的に探索
30
デモ 2: 識別子の探索
31
https://youtu.be/mpUgaaASvHo
Demo Code: https://gist.github.com/tenntenn/299c226c540fccd8386b7148f55f0884
型チェック
/* 型チェックのためのConfigを初期化 */
cfg := &types.Config{Importer: importer.Default()}
info := &types.Info{
/* TODO: 結果を保持するためのmapを初期化 */
}
pkg, err := cfg.Check("main", fs, []*ast.File{f}, info)
if err != nil {
/* エラー処理 */
}
/* TODO: pkgやinfoを使う処理 */
■ (*types.Config).Check で型チェックを行う
32
types.Info で型チェックの結果を保持する
type Info struct {
// Types maps expressions to their types, and for constant
// expressions, also their values.
Types map[ast.Expr]TypeAndValue
// Defs maps identifiers to the objects they define.
Defs map[*ast.Ident]Object
// Uses maps identifiers to the objects they denote.
Uses map[*ast.Ident]Object
// Implicits maps nodes to their implicitly declared objects, if any.
Implicits map[ast.Node]Object
// Selections maps selector expressions (excluding qualified identifiers)
// to their corresponding selections.
Selections map[*ast.SelectorExpr]*Selection
// Scopes maps ast.Nodes to the scopes they define.
Scopes map[ast.Node]*Scope
// InitOrder is the list of package-level initializers in the order in which
// they must be executed.
InitOrder []*Initializer
}
33
デモ 3: Gopher型の探索
34
https://youtu.be/AuSDtmiMaXI
Demo Code: https://gist.github.com/tenntenn/134d6965f75efe5eb6f6edf7b0ebe509
Goにおける静的解析
〜応用編〜
35
実際のツール開発で必要なことの例
36
■ パッケージ名からソースコードの一覧を取得する
● 1ファイルを対象とすることはあまりない
● その環境でビルド対象のファイルを対象にしたい
○ ビルドタグなどでビルド対象を決めている場合
■ 抽象構文木の複雑なトラバース
● 親ノードの情報を元に処理する
● 抽象構文木に変更をいれる
パッケージ名からファイル一覧を取得
■ パッケージ名からソースディレクトリを取得
● go listを用いてパッケージ名からディレクトリ一覧を取得
■ ビルドに必要な情報を集める
● go/buildパッケージを用いる
● ImportDirで取得した*build.Packageにファイル一覧情報がある
37
$ go list -f "{{.Dir}}" | grep -v vendor
pkg, err := build.ImportDir(dir, build.IgnoreVendor)
パースする際に不要なファイルを除外
■ ビルド対象のものだけをパースする
● *build.PacakgeのGoFilesに含まれているものだけ
● parser.ParseDirの第3引数はフィルター関数
○ trueを返すものだけパースする
38
parser.ParseDir(fset, dir, func(fi os.FileInfo) bool {
for _, df := range pkg.GoFiles {
if gf == fi.Name() {
return true
}
}
return false
}, 0)
抽象構文木の変更
39
■ 抽象構文木を探索&条件マッチするノードの置き換え
● 2項演算式中の第2項だけを変更する
● 1ノードだけみるast.Inspectやast.Walkでは難しい!
○ go/ast: provide AST Rewrite functionality (ast.Walk is not good enough)
+
X Y
BinaryExpr
Ident
+
X 2
BasicLit
astutil.Apply関数
■ 抽象構文木を変更するための関数
● golang.org/x/tools/go/ast/astutilパッケージで提供
● preとpostというノードに適用する関数を渡す
○ pre: 子ノードを処理する前に呼ばれる関数
○ post: 子ノードを処理した後に呼ばれる関数
● 変更した結果をresultとして返す
○ ルートが変更された場合はrootとresultが変わる
40
参考:astutil.Applyで抽象構文木を置き換える
func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node)
ApplyFunc型とCursor型
■ ApplyFunc型
● astutil.Apply関数に各ノードに再帰的に適用される関数
■ Cursor型
● 現在注目しているノードに関する情報を保持する型
● ノードの情報を取得するメソッド
○ Node、Index、Parent、Name
● ノードの操作を行うメソッド
○ Replace、Delete、InsertBefore、InsertAfter
41
type ApplyFunc func(*Cursor) bool
ノードの情報を取得するメソッド
■ Node() ast.Node
● 現在注目のノード取得する
■ Parent() ast.Node
● 注目ノードの親ノードを取得
■ Name() string
● 親ノードにどういう名前でノードを管理されているか
○ 例:BinaryExprの場合、2つの項はXとY
■ Index() int
● 親ノードでスライスとして管理していた場合にそのインデックス
○ 例:関数の引数など
● Nameメソッドだけで区別できない場合に使う
42
ノードを変更するメソッド
■ Replace(n ast.Node)
● 現在注目のノードを指定したノードで入れ替える
■ InsertBefore(n ast.Node)
● スライスで管理されているノードが対象
● 現在注目のノードの前にノードを追加する
■ InsertAfter(n ast.Node)
● 現在注目のノードの後ろにノードを追加する
■ Delete()
● 現在注目のノードを削除する
43
ノードの更新の例
44
expr, err := parser.ParseExpr(`x+y`)
if err != nil { log.Fatal(err) }
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if _, ok := cr.Parent().(*ast.BinaryExpr); !ok { return true }
if cr.Name() == "Y" {
cr.Replace(&ast.BasicLit{Kind:token.INT, Value:"2"})
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
ノードを操作する際の注意点
■ ノードの操作は破壊的に行われる
● コピーが作られるわけではない
● Apply関数の戻り値はちゃんと受け取る
■ ノードの操作は即時反映される
● preとpostは実行された瞬間にそのノードに適用される
45
ノードの削除の例(失敗例)
46
■ 第1引数だけを削除したい
expr, err := parser.ParseExpr(`func(x, y int){}(10, 20)`)
if err != nil { log.Fatal(err) }
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if cr.Name() == "Args" && cr.Index() == 0 {
cr.Delete()
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
ノードの削除の例(修正版)
47
■ 第1引数を一度だけ削除する
expr, err := parser.ParseExpr(`func(x, y int){}(10, 20)`)
if err != nil { log.Fatal(err) }
var once sync.Once
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if cr.Name() == "Args" && cr.Index() == 0 {
once.Do(cr.Delete)
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
まとめ
■ 静的解析は開発ツールと相性がいい
● 標準のツールでも使われている
● 自作することが可能
■ Goで静的解析を行うのは簡単
● 静的型付け、シンプルな文法、goパッケージ
■ goパッケージで簡単に静的解析を行える
● 字句解析、構文解析、型チェック
48
Thank you!
twitter: @tenntenn
Qiita: tenntenn
connpass: tenntenn
49

More Related Content

What's hot

例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
「速」を落とさないコードレビュー
「速」を落とさないコードレビュー「速」を落とさないコードレビュー
「速」を落とさないコードレビューTakafumi ONAKA
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)lestrrat
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
Go静的解析ハンズオン
Go静的解析ハンズオンGo静的解析ハンズオン
Go静的解析ハンズオンTakuya Ueda
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?Yoshitaka Kawashima
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409稔 小林
 
実践的な設計って、なんだろう?
実践的な設計って、なんだろう?実践的な設計って、なんだろう?
実践的な設計って、なんだろう?増田 亨
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるpospome
 
オトナのTDD(テスト駆動開発)入門
オトナのTDD(テスト駆動開発)入門オトナのTDD(テスト駆動開発)入門
オトナのTDD(テスト駆動開発)入門Yoshinori Yamanouchi
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうRyuji Tsutsui
 
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMPYusuke Kagata
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使うKazuhiro Suga
 
HttpClient詳解、或いは非同期の落とし穴について
HttpClient詳解、或いは非同期の落とし穴についてHttpClient詳解、或いは非同期の落とし穴について
HttpClient詳解、或いは非同期の落とし穴についてYoshifumi Kawai
 
OpenVRやOpenXRの基本的なことを調べてみた
OpenVRやOpenXRの基本的なことを調べてみたOpenVRやOpenXRの基本的なことを調べてみた
OpenVRやOpenXRの基本的なことを調べてみたTakahiro Miyaura
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかKoichiro Matsuoka
 

What's hot (20)

例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
「速」を落とさないコードレビュー
「速」を落とさないコードレビュー「速」を落とさないコードレビュー
「速」を落とさないコードレビュー
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Go静的解析ハンズオン
Go静的解析ハンズオンGo静的解析ハンズオン
Go静的解析ハンズオン
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409
 
実践的な設計って、なんだろう?
実践的な設計って、なんだろう?実践的な設計って、なんだろう?
実践的な設計って、なんだろう?
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
 
オトナのTDD(テスト駆動開発)入門
オトナのTDD(テスト駆動開発)入門オトナのTDD(テスト駆動開発)入門
オトナのTDD(テスト駆動開発)入門
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介
 
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使う
 
HttpClient詳解、或いは非同期の落とし穴について
HttpClient詳解、或いは非同期の落とし穴についてHttpClient詳解、或いは非同期の落とし穴について
HttpClient詳解、或いは非同期の落とし穴について
 
OpenVRやOpenXRの基本的なことを調べてみた
OpenVRやOpenXRの基本的なことを調べてみたOpenVRやOpenXRの基本的なことを調べてみた
OpenVRやOpenXRの基本的なことを調べてみた
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 

Similar to 静的解析を使った開発ツールの開発

マスター・オブ・goパッケージ
マスター・オブ・goパッケージマスター・オブ・goパッケージ
マスター・オブ・goパッケージTakuya Ueda
 
Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用Takuya Ueda
 
ひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指すひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指すAromaBlack
 
エキスパートGo
エキスパートGoエキスパートGo
エキスパートGoTakuya Ueda
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
Go Friday 傑作選
Go Friday 傑作選Go Friday 傑作選
Go Friday 傑作選Takuya Ueda
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Takuya Ueda
 
LLdeade Python Language Update
LLdeade Python Language UpdateLLdeade Python Language Update
LLdeade Python Language UpdateAtsushi Shibata
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526 masahitojp
 
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12Takanori Suzuki
 
実用裏方 Perl 入門
実用裏方 Perl 入門実用裏方 Perl 入門
実用裏方 Perl 入門keroyonn
 
みんなのPython勉強会#77 パッケージングしよう
みんなのPython勉強会#77 パッケージングしようみんなのPython勉強会#77 パッケージングしよう
みんなのPython勉強会#77 パッケージングしようAtsushi Odagiri
 
GAE/Goとsyncパッケージ
GAE/GoとsyncパッケージGAE/Goとsyncパッケージ
GAE/GoとsyncパッケージTakuya Ueda
 
Python Kyoto study
Python Kyoto studyPython Kyoto study
Python Kyoto studyNaoya Inada
 
明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理Yuto Matsukubo
 
エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法Takuya Ueda
 
Play meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesPlay meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesk4200
 

Similar to 静的解析を使った開発ツールの開発 (20)

マスター・オブ・goパッケージ
マスター・オブ・goパッケージマスター・オブ・goパッケージ
マスター・オブ・goパッケージ
 
Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用
 
ひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指すひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指す
 
エキスパートGo
エキスパートGoエキスパートGo
エキスパートGo
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
Go Friday 傑作選
Go Friday 傑作選Go Friday 傑作選
Go Friday 傑作選
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
ECMAScript没proposal追悼式
ECMAScript没proposal追悼式ECMAScript没proposal追悼式
ECMAScript没proposal追悼式
 
LLdeade Python Language Update
LLdeade Python Language UpdateLLdeade Python Language Update
LLdeade Python Language Update
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526
 
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
 
Subprocess no susume
Subprocess no susumeSubprocess no susume
Subprocess no susume
 
実用裏方 Perl 入門
実用裏方 Perl 入門実用裏方 Perl 入門
実用裏方 Perl 入門
 
みんなのPython勉強会#77 パッケージングしよう
みんなのPython勉強会#77 パッケージングしようみんなのPython勉強会#77 パッケージングしよう
みんなのPython勉強会#77 パッケージングしよう
 
GAE/Goとsyncパッケージ
GAE/GoとsyncパッケージGAE/Goとsyncパッケージ
GAE/Goとsyncパッケージ
 
Python Kyoto study
Python Kyoto studyPython Kyoto study
Python Kyoto study
 
明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理
 
Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 
エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法
 
Play meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesPlay meetup-2-dev-best-practices
Play meetup-2-dev-best-practices
 

More from Takuya Ueda

Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Takuya Ueda
 
WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with GoTakuya Ueda
 
そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めようTakuya Ueda
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新Takuya Ueda
 
Go1.8 for Google App Engine
Go1.8 for Google App EngineGo1.8 for Google App Engine
Go1.8 for Google App EngineTakuya Ueda
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発Takuya Ueda
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in GoTakuya Ueda
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話Takuya Ueda
 
オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選Takuya Ueda
 
Gopher Fest 2017参加レポート
Gopher Fest 2017参加レポートGopher Fest 2017参加レポート
Gopher Fest 2017参加レポートTakuya Ueda
 
Google Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめGoogle Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめTakuya Ueda
 
Cloud functionsの紹介
Cloud functionsの紹介Cloud functionsの紹介
Cloud functionsの紹介Takuya Ueda
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するTakuya Ueda
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介Takuya Ueda
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化Takuya Ueda
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Takuya Ueda
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingTakuya Ueda
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法Takuya Ueda
 
Goでwebアプリを開発してみよう
Goでwebアプリを開発してみようGoでwebアプリを開発してみよう
Goでwebアプリを開発してみようTakuya Ueda
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門Takuya Ueda
 

More from Takuya Ueda (20)

Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −
 
WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with Go
 
そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めよう
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新
 
Go1.8 for Google App Engine
Go1.8 for Google App EngineGo1.8 for Google App Engine
Go1.8 for Google App Engine
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in Go
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
 
オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選
 
Gopher Fest 2017参加レポート
Gopher Fest 2017参加レポートGopher Fest 2017参加レポート
Gopher Fest 2017参加レポート
 
Google Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめGoogle Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめ
 
Cloud functionsの紹介
Cloud functionsの紹介Cloud functionsの紹介
Cloud functionsの紹介
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現する
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse Binding
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法
 
Goでwebアプリを開発してみよう
Goでwebアプリを開発してみようGoでwebアプリを開発してみよう
Goでwebアプリを開発してみよう
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門
 

Recently uploaded

持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦Sadao Tokuyama
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 

Recently uploaded (12)

持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 
2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 

静的解析を使った開発ツールの開発