Skip to content

Commit a99ff24

Browse files
committed
cmd/compile/internal/syntax: print type parameters and type lists
types2 uses the syntax printer to print expressions (for tracing or error messages), so we need to (at least) print type lists in interfaces. While at it, also implement the printing of type parameter lists. Fixes #44766. Change-Id: I36a4a7152d9bef7251af264b5c7890aca88d8dc3 Reviewed-on: https://go-review.googlesource.com/c/go/+/298549 Trust: Robert Griesemer <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 9d3718e commit a99ff24

File tree

2 files changed

+79
-15
lines changed

2 files changed

+79
-15
lines changed

src/cmd/compile/internal/syntax/printer.go

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -481,10 +481,10 @@ func (p *printer) printRawNode(n Node) {
481481
if len(n.FieldList) > 0 {
482482
if p.linebreaks {
483483
p.print(newline, indent)
484-
p.printFieldList(n.FieldList, n.TagList)
484+
p.printFieldList(n.FieldList, n.TagList, _Semi)
485485
p.print(outdent, newline)
486486
} else {
487-
p.printFieldList(n.FieldList, n.TagList)
487+
p.printFieldList(n.FieldList, n.TagList, _Semi)
488488
}
489489
}
490490
p.print(_Rbrace)
@@ -494,20 +494,40 @@ func (p *printer) printRawNode(n Node) {
494494
p.printSignature(n)
495495

496496
case *InterfaceType:
497+
// separate type list and method list
498+
var types []Expr
499+
var methods []*Field
500+
for _, f := range n.MethodList {
501+
if f.Name != nil && f.Name.Value == "type" {
502+
types = append(types, f.Type)
503+
} else {
504+
// method or embedded interface
505+
methods = append(methods, f)
506+
}
507+
}
508+
509+
multiLine := len(n.MethodList) > 0 && p.linebreaks
497510
p.print(_Interface)
498-
if len(n.MethodList) > 0 && p.linebreaks {
511+
if multiLine {
499512
p.print(blank)
500513
}
501514
p.print(_Lbrace)
502-
if len(n.MethodList) > 0 {
503-
if p.linebreaks {
504-
p.print(newline, indent)
505-
p.printMethodList(n.MethodList)
506-
p.print(outdent, newline)
507-
} else {
508-
p.printMethodList(n.MethodList)
515+
if multiLine {
516+
p.print(newline, indent)
517+
}
518+
if len(types) > 0 {
519+
p.print(_Type, blank)
520+
p.printExprList(types)
521+
if len(methods) > 0 {
522+
p.print(_Semi, blank)
509523
}
510524
}
525+
if len(methods) > 0 {
526+
p.printMethodList(methods)
527+
}
528+
if multiLine {
529+
p.print(outdent, newline)
530+
}
511531
p.print(_Rbrace)
512532

513533
case *MapType:
@@ -667,7 +687,13 @@ func (p *printer) printRawNode(n Node) {
667687
if n.Group == nil {
668688
p.print(_Type, blank)
669689
}
670-
p.print(n.Name, blank)
690+
p.print(n.Name)
691+
if n.TParamList != nil {
692+
p.print(_Lbrack)
693+
p.printFieldList(n.TParamList, nil, _Comma)
694+
p.print(_Rbrack)
695+
}
696+
p.print(blank)
671697
if n.Alias {
672698
p.print(_Assign, blank)
673699
}
@@ -696,6 +722,11 @@ func (p *printer) printRawNode(n Node) {
696722
p.print(_Rparen, blank)
697723
}
698724
p.print(n.Name)
725+
if n.TParamList != nil {
726+
p.print(_Lbrack)
727+
p.printFieldList(n.TParamList, nil, _Comma)
728+
p.print(_Rbrack)
729+
}
699730
p.printSignature(n.Type)
700731
if n.Body != nil {
701732
p.print(blank, n.Body)
@@ -746,14 +777,14 @@ func (p *printer) printFields(fields []*Field, tags []*BasicLit, i, j int) {
746777
}
747778
}
748779

749-
func (p *printer) printFieldList(fields []*Field, tags []*BasicLit) {
780+
func (p *printer) printFieldList(fields []*Field, tags []*BasicLit, sep token) {
750781
i0 := 0
751782
var typ Expr
752783
for i, f := range fields {
753784
if f.Name == nil || f.Type != typ {
754785
if i0 < i {
755786
p.printFields(fields, tags, i0, i)
756-
p.print(_Semi, newline)
787+
p.print(sep, newline)
757788
i0 = i
758789
}
759790
typ = f.Type

src/cmd/compile/internal/syntax/printer_test.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,21 @@ var stringTests = []string{
6161
"package p",
6262
"package p; type _ int; type T1 = struct{}; type ( _ *struct{}; T2 = float32 )",
6363

64+
// generic type declarations
65+
"package p; type _[T any] struct{}",
66+
"package p; type _[A, B, C interface{m()}] struct{}",
67+
"package p; type _[T any, A, B, C interface{m()}, X, Y, Z interface{type int}] struct{}",
68+
69+
// generic function declarations
70+
"package p; func _[T any]()",
71+
"package p; func _[A, B, C interface{m()}]()",
72+
"package p; func _[T any, A, B, C interface{m()}, X, Y, Z interface{type int}]()",
73+
74+
// methods with generic receiver types
75+
"package p; func (R[T]) _()",
76+
"package p; func (*R[A, B, C]) _()",
77+
"package p; func (_ *R[A, B, C]) _()",
78+
6479
// channels
6580
"package p; type _ chan chan int",
6681
"package p; type _ chan (<-chan int)",
@@ -79,7 +94,7 @@ var stringTests = []string{
7994

8095
func TestPrintString(t *testing.T) {
8196
for _, want := range stringTests {
82-
ast, err := Parse(nil, strings.NewReader(want), nil, nil, 0)
97+
ast, err := Parse(nil, strings.NewReader(want), nil, nil, AllowGenerics)
8398
if err != nil {
8499
t.Error(err)
85100
continue
@@ -116,6 +131,24 @@ var exprTests = [][2]string{
116131
{"func(x int) complex128 { return 0 }", "func(x int) complex128 {…}"},
117132
{"[]int{1, 2, 3}", "[]int{…}"},
118133

134+
// type expressions
135+
dup("[1 << 10]byte"),
136+
dup("[]int"),
137+
dup("*int"),
138+
dup("struct{x int}"),
139+
dup("func()"),
140+
dup("func(int, float32) string"),
141+
dup("interface{m()}"),
142+
dup("interface{m() string; n(x int)}"),
143+
dup("interface{type int}"),
144+
dup("interface{type int, float64, string}"),
145+
dup("interface{type int; m()}"),
146+
dup("interface{type int, float64, string; m() string; n(x int)}"),
147+
dup("map[string]int"),
148+
dup("chan E"),
149+
dup("<-chan E"),
150+
dup("chan<- E"),
151+
119152
// non-type expressions
120153
dup("(x)"),
121154
dup("x.f"),
@@ -172,7 +205,7 @@ var exprTests = [][2]string{
172205
func TestShortString(t *testing.T) {
173206
for _, test := range exprTests {
174207
src := "package p; var _ = " + test[0]
175-
ast, err := Parse(nil, strings.NewReader(src), nil, nil, 0)
208+
ast, err := Parse(nil, strings.NewReader(src), nil, nil, AllowGenerics)
176209
if err != nil {
177210
t.Errorf("%s: %s", test[0], err)
178211
continue

0 commit comments

Comments
 (0)