Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit 985a38b

Browse files
authored
Support Go 1.18 methods with type parameters (#91)
1 parent bd57b48 commit 985a38b

File tree

4 files changed

+80
-13
lines changed

4 files changed

+80
-13
lines changed

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ module github.com/axw/gocov
22

33
go 1.12
44

5-
require golang.org/x/tools v0.0.0-20190617190820-da514acc4774
5+
require (
6+
github.com/stretchr/testify v1.7.1
7+
golang.org/x/tools v0.0.0-20190617190820-da514acc4774
8+
)

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
6+
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
7+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
18
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
29
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
310
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
411
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
512
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
613
golang.org/x/tools v0.0.0-20190617190820-da514acc4774 h1:CQVOmarCBFzTx0kbOU0ru54Cvot8SdSrNYjZPhQl+gk=
714
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
15+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
16+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
17+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
18+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

gocov/convert.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,30 @@ type FuncVisitor struct {
189189
funcs []*FuncExtent
190190
}
191191

192+
func functionName(f *ast.FuncDecl) string {
193+
name := f.Name.Name
194+
if f.Recv == nil {
195+
return name
196+
} else {
197+
// Function name is prepended with "T." if there is a receiver, where
198+
// T is the type of the receiver, dereferenced if it is a pointer.
199+
return exprName(f.Recv.List[0].Type) + "." + name
200+
}
201+
}
202+
203+
func exprName(x ast.Expr) string {
204+
switch y := x.(type) {
205+
case *ast.StarExpr:
206+
return exprName(y.X)
207+
case *ast.IndexExpr:
208+
return fmt.Sprintf("%s[%s]", exprName(y.X), exprName(y.Index))
209+
case *ast.Ident:
210+
return y.Name
211+
default:
212+
return ""
213+
}
214+
}
215+
192216
// Visit implements the ast.Visitor interface.
193217
func (v *FuncVisitor) Visit(node ast.Node) ast.Visitor {
194218
var body *ast.BlockStmt
@@ -198,18 +222,7 @@ func (v *FuncVisitor) Visit(node ast.Node) ast.Visitor {
198222
body = n.Body
199223
case *ast.FuncDecl:
200224
body = n.Body
201-
name = n.Name.Name
202-
// Function name is prepended with "T." if there is a receiver, where
203-
// T is the type of the receiver, dereferenced if it is a pointer.
204-
if n.Recv != nil {
205-
field := n.Recv.List[0]
206-
switch recv := field.Type.(type) {
207-
case *ast.StarExpr:
208-
name = recv.X.(*ast.Ident).Name + "." + name
209-
case *ast.Ident:
210-
name = recv.Name + "." + name
211-
}
212-
}
225+
name = functionName(n)
213226
}
214227
if body != nil {
215228
start := v.fset.Position(node.Pos())

gocov/convert_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package main
2+
3+
import (
4+
"go/ast"
5+
"go/parser"
6+
"go/token"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestExprName(t *testing.T) {
13+
source := `
14+
package foo
15+
16+
func Function() {}
17+
func (x Foo) Method() {}
18+
func (x *Foo) PtrMethod() {}
19+
func (x *Foo[T]) GenericMethod() {}
20+
`
21+
22+
fset := token.NewFileSet()
23+
parsed, err := parser.ParseFile(fset, "", source, 0)
24+
if err != nil {
25+
t.Fatal(err)
26+
}
27+
28+
function0 := parsed.Decls[0].(*ast.FuncDecl)
29+
assert.Equal(t, "Function", functionName(function0))
30+
31+
function1 := parsed.Decls[1].(*ast.FuncDecl)
32+
assert.Equal(t, "Foo.Method", functionName(function1))
33+
34+
function2 := parsed.Decls[2].(*ast.FuncDecl)
35+
assert.Equal(t, "Foo.PtrMethod", functionName(function2))
36+
37+
function3 := parsed.Decls[3].(*ast.FuncDecl)
38+
assert.Equal(t, "Foo[T].GenericMethod", functionName(function3))
39+
40+
}

0 commit comments

Comments
 (0)