err)}まずはsample.goというファイルを指定してparser.ParseFileにより構文解析を行います。}}ここで、「あれ、まず字句解析しないの?」と思った方もいらっしゃるかもしれません。実はgo/parserパッケージが内部で字句解析を行うため、直接字句解析を行うことはあまりないのです。続いて、構文解析した結果により作られた抽象構文木を扱います。})ast.Inspectは抽象構文木のノードをトラバースする関数です。}で、抽象構文木の各ノードに対して一律の処理をかけます。実際にどのような処理をするか見ていきましょう。true}まずはast.Node型のノードをast.BinaryExpr型に変換しています。ast.BinaryExprは+や==などのような二項演算子を表す型です。falseのような箇所を検出したいので、この型に変換できない場合は無視して次に進みます。(なぜ最初にast.BinaryExp型に変換できるノードを探しているのかは下で説明します)ast.BinaryExprは以下のような構造体です。Op)との対応が見て取れると思います。図を見てわかる通り、二項演算では演算子が親ノード、オペランドが子ノードになるため、このステップではまずast.BinaryExp型に変換できるノードを探していました。続いて、上記の結果返ってきたast.BinaryExp型の値に対して処理をかけます。yのような部分だけ検出したいので、まずオペレーターOpがtoken.Token型の==と等しいか調べています。オペレーターが==だった場合に、次は各オペランドをast.Identという型に変換しているのがわかるかと思います。ここでIdentが何かというと、識別子を表します。上図のように、字句解析のあとの変数名や関数名、bool値は識別子を表すast.Ident型、1や"dog"など数値リテラルや文字リテラルはast.BasicLit型になります。今回はある変数をboolと比較している箇所を評価したいため、その条件に合致するようなオペランド対を探しています。あとは、該当するような箇所があったらその旨を出力して終わりです。実際にsample.goにこのlinterをかけた結果を見てみましょう。!isAvailableご覧のように、sample.go内でbool値と直接比較している箇所を検出できています。終わりに今回は、標準の静的解析パッケージであるgoパッケージを使って簡単な静的解析ツールを試作してみました。goパッケージを使えば、lintの他にもコードの自動生成や自動フォーマットをすることもできます。このパッケージのソースコードを読むことでコンパイラや言語処理系の勉強にもなるので、静的解析はGoの中でも面白いトピックの一つなのではないでしょうか。)の開発チームによるブログです。Groupの大木です。Developerをしている東口です。Groupのマネージャーをしている山田です。12/1から始まっ...Archiveスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。