🪺

静的解析ツール作った

2023/01/29に公開

静的解析で package 内で type として定義されているものの情報をまとめてくれるツールです
静的解析の際に役立つかも?
静的解析の際に struct の タグ とかコメントとかまとめて出力してくれると楽だなーと思って作りました

似たようなツールありそうだから車輪の再発明になってしまったかも...
静的解析の簡単な復習も兼ねて作りました
go/types パッケージで事足りる気もする...

たぶん色々考慮もれ等あるけれど一旦それっぽくできたのでリリースしました

ブツと使い方

https://github.com/maru44/stst

使い方は簡単で、golang.org/x/tools/go/packages.Package を NewParser に渡して *stst.Parser のインスタンスを作成し、*stst.ParserParse もしくは ParseFile メソッドで実行、 []*stst.Schema が結果として返されます

example.go
package main

import (
	"fmt"

	"github.com/k0kubun/pp"
	"github.com/maru44/stst"
	"golang.org/x/tools/go/packages"
)

func main() {
	ps := loadPackages("github.com/maru44/stst/tests/data/aaa")

	var schemas []*stst.Schema
	for _, pk := range ps {
		p := stst.NewParser(pk)
		s := p.Parse()
		schemas = append(schemas, s...)
	}
	pp.Println(schemas)
}

func loadPackages(ps ...string) []*packages.Package {
	cfg := &packages.Config{
		Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo,
	}
	pkgs, err := packages.Load(cfg, ps...)
	if err != nil {
		panic(err)
	}
	return pkgs
}

結果はこんな感じのが返ってきます

schemas = []*stst.Schema{
  &stst.Schema{
    Name:   "Intf",
    Fields: []*stst.Field{
      &stst.Field{
        Name:                "Hello",
        Func:                &stst.Func{
          Args:    []*stst.Field{},
          Results: []*stst.Field{
            &stst.Field{
              Name: "string",
              Type: &stst.Type{
                Underlying: "string",
                TypeName:   "string",
              },
            },
          },
        },
      },
    },
    Type: &stst.Type{
      Underlying: "github.com/maru44/stst/tests/data/aaa.Intf",
      PkgID:    "github.com/maru44/stst/tests/data/aaa",
      PkgPlusName: "aaa.Intf",
      TypeName:   "Intf",
    },
    IsInterface:  true,
  },
  &stst.Schema{
    Name:   "IntSample",
    Type:   &stst.Type{
      Underlying: "int",
      TypeName:   "int",
    },
  },
  &stst.Schema{
    Name:   "Sample",
    Fields: []*stst.Field{
      &stst.Field{
        Name: "Str",
        Type: &stst.Type{
          Underlying: "string",
          TypeName:   "string",
        },
        Tags:                []*stst.Tag{
          &stst.Tag{
            Key:    "tag0",
            Values: []string{
              "xxx",
            },
            RawValue: "xxx",
          },
          &stst.Tag{
            Key:    "tag1",
            Values: []string{
              "yyy",
              "zzz",
            },
            RawValue: "yyy,zzz",
          },
        },
        Comment: []string{
          "// comment",
        },
      },
    },
    Type: &stst.Type{
      Underlying: "github.com/maru44/stst/tests/data/aaa.Sample",
      PkgID:    "github.com/maru44/stst/tests/data/aaa",
      PkgPlusName: "aaa.Sample",
      TypeName:   "Sample",
    },
  },
  &stst.Schema{
    Name:   "prefixes",
    Type:   &stst.Type{
      Underlying: "github.com/maru44/stst/tests/data/aaa.prefixes",
      PkgID:    "github.com/maru44/stst/tests/data/aaa",
      PkgPlusName: "aaa.prefixes",
      TypeName:   "prefixes",
    },
    TypePrefixes: []stst.TypePrefix{
      "[]",
      "*",
      "[]",
      "[]",
      "[]",
      "*",
    },
  },
}

まとめ

静的解析やっぱりおもろいですね
需要あれば使ってください 🙇

もし、似たようなもっと良いツールあったら教えてください 🙇

GitHubで編集を提案

Discussion