Upgrade to Pro — share decks privately, control downloads, hide ads and more …

package名と変数名がかぶっているのをとにかく検出したい / I need detect to conflicts of identifier for Go

mackee
June 18, 2019

package名と変数名がかぶっているのをとにかく検出したい / I need detect to conflicts of identifier for Go

mackee

June 18, 2019
Tweet

More Decks by mackee

Other Decks in Programming

Transcript

  1. Ͳ͏͍͏͜ͱ͔ package main import ( "os" "errors" ) func main()

    { // Ҿ਺͔Β࣮ߦ͢Δ܅ΛऔΓग़͢ runner := NewRunners(os.Args[1:]) 2
  2. errors := make([]error, 0, len(runner)) for _, r := range

    runners { result, err := runner.Run() if err != nil { errors = append(errors, err) } if result == nil { errors = append( errors, errors.New("result is nil"), ) } 3
  3. 1ߦา͍ͨΒ๨ΕͯΔ errors = append( errors, errors.New("result is nil"), ) •

    ౰વ͜Ε͸ίϯύΠϧ͕௨Βͳ͍ • errorsύοέʔδ͸طʹ࢖͑ͳ͘ͳ͍ͬͯΔͨΊ 4
  4. ͦͷଞղܾ͍ͨ͠έʔεstruct໊ͱม਺໊͕͔ͿΔ type sheet struct { // ... } func NewSheet()

    *sheet { return &sheet{} } func (s *sheet) String() string { // ... } 7
  5. ศརͳέʔε΋͋Δ Ұ෦ͷείʔϓ͚ͩlogΛผͷ΋ͷʹஔ͖׵͑Δͱ͔(ͦͦ͜͜अѱ import "log" // ͜ͷϝιουͷத͚ͩϑΝΠϧʹॻ͘ func Do() { log

    := log.New(logfile, "Do(): ", log.LstdFlags) // ্ͷ1ߦΛՃ͑Δ͚ͩͰଞͷߦ͸ॻ͖׵͑ͳ͍͍ͯ͘ log.Println("print something") } 12
  6. ྨࣅ඼ • golang.org/x/tools/go/analysis/passes/shadow/ cmd/shadow • ม਺ͷshadowingΛݕ஌ͯ͘͠ΕΔ func BadRead(f *os.File, buf

    []byte) error { var err error for { n, err := f.Read(buf) // shadows the function variable 'err' if err != nil { break // causes return of wrong value } foo(buf) } return err } 20
  7. x/tools/analysisΛ࢖͍ͬͯΔίʔυ package conflictident import ( "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/passes/inspect" "golang.org/x/tools/go/ast/inspector" ) var

    Analyzer = &analysis.Analyzer{ Name: "conflictident", Doc: Doc, Run: run, Requires: []*analysis.Analyzer{ inspect.Analyzer, }, } 23
  8. x/tools/analysisΛ࢖͍ͬͯΔίʔυ func run(pass *analysis.Pass) (interface{}, error) { ins := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

    nodeFilter := []ast.Node{ // ͜͜ʹཉ͍͠ASTͷϊʔυೖΕΑ͏ } ins.WithStack(nodeFilter, func(n ast.Node, push bool, stack []ast.Node) bool { // ϑΟϧλʹઃఆͨ͠ASTͷϊʔυ͕΍ͬͯ͘Δͧ ͦΕΛݟ͍͍ͯײ͡ʹग़ྗ͠Α͏ }) } 24
  9. testdata/src/pkgident/pkgident.go package pkgident import ( "path" ) func hoge() {

    _ = path.ErrBadPattern } func main() { path, fuga := 1, 1 // want "conflict identifier name of 'path' by testdata/src/pkgident/pkgident.go:4:2." _, _ = path, fuga } func p(path string) { // want "conflict identifier name of 'path' by testdata/src/pkgident/pkgident.go:4:2." } 32
  10. conflic&dent_test.go package conflictident_test import ( "testing" "github.com/mackee/conflictident" "golang.org/x/tools/go/analysis/analysistest" ) func

    Test(t *testing.T) { testdata := analysistest.TestData() analysistest.Run(t, testdata, conflictident.Analyzer, "varspec", "funcarg") } 33