Skip to content

Commit 13cf844

Browse files
committed
go/ast/astutil: fix panic when rewriting multi-argument type instances
Use the typeparams helper package to fix AST rewriting in go/ast/astutil when encountering the new ListExpr type. This is liable to break in the future when the go/ast API changes, but at least it will be easy to find by virtue of using internal/typeparams. Fixes golang/vscode-go#1551 Change-Id: Id34bbcdede9024ed9818bef6d73a19e993dd76a8 Reviewed-on: https://go-review.googlesource.com/c/tools/+/326131 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org>
1 parent 937957b commit 13cf844

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

go/ast/astutil/rewrite.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"go/ast"
1010
"reflect"
1111
"sort"
12+
13+
"golang.org/x/tools/internal/typeparams"
1214
)
1315

1416
// An ApplyFunc is invoked by Apply for each node n, even if n is nil,
@@ -437,7 +439,11 @@ func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.
437439
}
438440

439441
default:
440-
panic(fmt.Sprintf("Apply: unexpected node type %T", n))
442+
if typeparams.IsListExpr(n) {
443+
a.applyList(n, "ElemList")
444+
} else {
445+
panic(fmt.Sprintf("Apply: unexpected node type %T", n))
446+
}
441447
}
442448

443449
if a.post != nil && !a.post(&a.cursor) {

go/ast/astutil/rewrite_test.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ import (
1313
"testing"
1414

1515
"golang.org/x/tools/go/ast/astutil"
16+
"golang.org/x/tools/internal/typeparams"
1617
)
1718

18-
var rewriteTests = [...]struct {
19+
type rewriteTest struct {
1920
name string
2021
orig, want string
2122
pre, post astutil.ApplyFunc
22-
}{
23+
}
24+
25+
var rewriteTests = []rewriteTest{
2326
{name: "nop", orig: "package p\n", want: "package p\n"},
2427

2528
{name: "replace",
@@ -190,6 +193,34 @@ var z int
190193
},
191194
}
192195

196+
func init() {
197+
if typeparams.Enabled {
198+
rewriteTests = append(rewriteTests, rewriteTest{
199+
name: "replace",
200+
orig: `package p
201+
202+
type T[P1, P2 any] int
203+
204+
type R T[int, string]
205+
`,
206+
want: `package p
207+
208+
type T[P1, P2 any] int32
209+
210+
type R T[int32, string]
211+
`,
212+
post: func(c *astutil.Cursor) bool {
213+
if ident, ok := c.Node().(*ast.Ident); ok {
214+
if ident.Name == "int" {
215+
c.Replace(ast.NewIdent("int32"))
216+
}
217+
}
218+
return true
219+
},
220+
})
221+
}
222+
}
223+
193224
func valspec(name, typ string) *ast.ValueSpec {
194225
return &ast.ValueSpec{Names: []*ast.Ident{ast.NewIdent(name)},
195226
Type: ast.NewIdent(typ),

internal/typeparams/typeparams.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,5 @@ func GetInferred(info *types.Info, e ast.Expr) ([]types.Type, *types.Signature)
101101
return nil, nil
102102
}
103103
inf := info.Inferred[e]
104-
return inf.Targs, inf.Sig
104+
return inf.TArgs, inf.Sig
105105
}

0 commit comments

Comments
 (0)