diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 5dafb1d..d69641c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -36,7 +36,7 @@ jobs: - name: Modver if: ${{ github.event_name == 'pull_request' }} - uses: bobg/modver@v2.12.1 + uses: bobg/modver@v2.13.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} pull_request_url: https://github.com/${{ github.repository }}/pull/${{ github.event.number }} diff --git a/_testdata/1/bar.go b/_testdata/1/bar.go index e079f8b..a548194 100644 --- a/_testdata/1/bar.go +++ b/_testdata/1/bar.go @@ -1,8 +1,10 @@ type one2 struct{} -func (one2) x() {} +func (one2) x() int { + return 42 +} -func one2func() func() { +func one2func() func() int { var y one2 return y.x } diff --git a/_testdata/bug27/go.mod b/_testdata/bug27/go.mod new file mode 100644 index 0000000..d2fac6f --- /dev/null +++ b/_testdata/bug27/go.mod @@ -0,0 +1,3 @@ +module bug27 + +go 1.23 diff --git a/_testdata/bug27/main.go b/_testdata/bug27/main.go new file mode 100644 index 0000000..c95a0b8 --- /dev/null +++ b/_testdata/bug27/main.go @@ -0,0 +1,8 @@ +package main + +import "crypto/tls" + +func main() { + var foo tls.QUICSessionTicketOptions + print(foo.Extra) +} diff --git a/expr.go b/expr.go index 07094b3..cbf1ab5 100644 --- a/expr.go +++ b/expr.go @@ -211,9 +211,42 @@ func (p *pkgScanner) selectorExpr(expr *ast.SelectorExpr, isCallFun bool) (bool, return isMax, err } - if obj, ok := p.info.Uses[expr.Sel]; ok && obj != nil { - var typ string - if sig, ok := obj.Type().(*types.Signature); ok { + if sel, ok := p.info.Selections[expr]; ok { + obj := sel.Obj() + if obj == nil { + return false, nil + } + + typ := sel.Recv() + if ptr, ok := typ.(*types.Pointer); ok { + typ = ptr.Elem() + } + typestr := typ.String() + if dot := strings.LastIndex(typestr, "."); dot >= 0 { + typestr = typestr[dot+1:] + } + + pkg := obj.Pkg() + if pkg == nil { + return false, nil + } + pkgpath := pkg.Path() + + switch sel.Kind() { + case types.FieldVal: + v := p.s.lookup(pkgpath, expr.Sel.Name, typestr) + if v == 0 { + return false, nil + } + + selResult := posResult{ + version: v, + pos: p.fset.Position(expr.Pos()), + desc: fmt.Sprintf(`"%s".%s.%s`, pkgpath, typestr, expr.Sel.Name), + } + return p.result(selResult), nil + + case types.MethodVal: if !isCallFun { p.result(posResult{ version: 1, @@ -221,21 +254,31 @@ func (p *pkgScanner) selectorExpr(expr *ast.SelectorExpr, isCallFun bool) (bool, desc: "method used as value", }) } - if recv := sig.Recv(); recv != nil { - recvtype := recv.Type().String() - if lastDot := strings.LastIndex(recvtype, "."); lastDot >= 0 { - typ = recvtype[lastDot+1:] + fallthrough + + case types.MethodExpr: + if v := p.s.lookup(pkgpath, expr.Sel.Name, typestr); v > 0 { + selResult := posResult{ + version: v, + pos: p.fset.Position(expr.Pos()), + desc: fmt.Sprintf(`"%s".%s`, pkgpath, expr.Sel.Name), + } + if p.result(selResult) { + return true, nil } } } + return false, nil + } + if obj, ok := p.info.Uses[expr.Sel]; ok && obj != nil { pkg := obj.Pkg() if pkg == nil { return false, nil } pkgpath := pkg.Path() - if v := p.s.lookup(pkgpath, expr.Sel.Name, typ); v > 0 { + if v := p.s.lookup(pkgpath, expr.Sel.Name, ""); v > 0 { selResult := posResult{ version: v, pos: p.fset.Position(expr.Pos()), @@ -245,40 +288,9 @@ func (p *pkgScanner) selectorExpr(expr *ast.SelectorExpr, isCallFun bool) (bool, return true, nil } } - return false, nil - } - - sel, ok := p.info.Selections[expr] - if !ok { - return false, nil - } - obj := sel.Obj() - if obj == nil { - return false, nil } - pkg := obj.Pkg() - if pkg == nil { - return false, nil - } - pkgpath := pkg.Path() - - typ := sel.Recv() - if ptr, ok := typ.(*types.Pointer); ok { - typ = ptr.Elem() - } - typestr := typ.String() - v := p.s.lookup(pkgpath, expr.Sel.Name, typestr) - if v == 0 { - return false, nil - } - - selResult := posResult{ - version: v, - pos: p.fset.Position(expr.Pos()), - desc: fmt.Sprintf(`"%s".%s.%s`, pkgpath, typestr, expr.Sel.Name), - } - return p.result(selResult), nil + return false, nil } func (p *pkgScanner) indexExpr(expr *ast.IndexExpr) (bool, error) { diff --git a/regression_test.go b/regression_test.go index 49e241c..edb1c20 100644 --- a/regression_test.go +++ b/regression_test.go @@ -14,6 +14,7 @@ func TestBug14(t *testing.T) { } } +// https://github.com/bobg/mingo/issues/26 func TestBug26(t *testing.T) { var s Scanner res, err := s.ScanDir("_testdata/bug26") @@ -24,3 +25,15 @@ func TestBug26(t *testing.T) { t.Errorf("got %d, want 18", v) } } + +// https://github.com/bobg/mingo/issues/27 +func TestBug27(t *testing.T) { + var s Scanner + res, err := s.ScanDir("_testdata/bug27") + if err != nil { + t.Fatal(err) + } + if v := res.Version(); v != 23 { + t.Errorf("got %d, want 23", v) + } +}