From 3314879ed2e356bf6bcf930022a64668cbb7a252 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 26 Aug 2020 21:57:08 -0700 Subject: [PATCH] [dev.go2go] go/printer: don't write "type" keyword in type parameter lists if brackets are used When the printer mode UseBrackets is set, use the new unified parameter list syntax: use []'s for type parameters without the "type" keyword. This will also change gofmt behavior accordingly. Fixes #41053. Change-Id: Ibaf490ea9ed178684bea34da5b57afa823a6829f Reviewed-on: https://go-review.googlesource.com/c/go/+/250998 Run-TryBot: Robert Griesemer TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- src/go/printer/nodes.go | 4 ++-- src/go/printer/printer.go | 2 +- src/go/printer/testdata/genericsB.golden | 25 +++++++++++------------- src/go/printer/testdata/genericsB.input | 25 +++++++++++------------- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go index 6dc24520e0..fbf3d14f78 100644 --- a/src/go/printer/nodes.go +++ b/src/go/printer/nodes.go @@ -325,7 +325,7 @@ func (p *printer) parameters(isTypeParam bool, fields *ast.FieldList) { openTok, closeTok = token.LBRACK, token.RBRACK } p.print(fields.Opening, openTok) - if isTypeParam { + if isTypeParam && p.Mode&UseBrackets == 0 { p.print(token.TYPE) } if len(fields.List) > 0 { @@ -352,7 +352,7 @@ func (p *printer) parameters(isTypeParam bool, fields *ast.FieldList) { if needsLinebreak && p.linebreak(parLineBeg, 0, ws, true) > 0 { // break line if the opening "(" or previous parameter ended on a different line ws = ignore - } else if isTypeParam && len(par.Names) > 0 || i > 0 { + } else if isTypeParam && len(par.Names) > 0 && p.Mode&UseBrackets == 0 || i > 0 { p.print(blank) } // parameter names diff --git a/src/go/printer/printer.go b/src/go/printer/printer.go index df2a9d9ea7..777e4be07e 100644 --- a/src/go/printer/printer.go +++ b/src/go/printer/printer.go @@ -1277,7 +1277,7 @@ const ( UseSpaces // use spaces instead of tabs for alignment SourcePos // emit //line directives to preserve original source positions StdFormat // apply standard formatting changes (exact byte output may change between versions of Go) - UseBrackets // use square brackets instead of parentheses for type parameters + UseBrackets // use square brackets instead of parentheses for type parameters (implies unified parameter syntax) ) // A Config node controls the output of Fprint. diff --git a/src/go/printer/testdata/genericsB.golden b/src/go/printer/testdata/genericsB.golden index a1f4d9a09a..5f09934ac2 100644 --- a/src/go/printer/testdata/genericsB.golden +++ b/src/go/printer/testdata/genericsB.golden @@ -4,27 +4,24 @@ package generics -type T[type] struct{} -type T[type P] struct{} -type T[type P1, P2, P3] struct{} +type T[P any] struct{} +type T[P1, P2, P3 any] struct{} -type T[type P C] struct{} -type T[type P1, P2, P3, C] struct{} +type T[P C] struct{} +type T[P1, P2, P3, C] struct{} -type T[type P C[P]] struct{} -type T[type P1, P2, P3 C[P1, P2, P3]] struct{} +type T[P C[P]] struct{} +type T[P1, P2, P3 C[P1, P2, P3]] struct{} -func f[type]() -func f[type P](x P) -func f[type P1, P2, P3](x1 P1, x2 P2, x3 P3) struct{} +func f[P any](x P) +func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{} -func f[type]() -func f[type P interface{}](x P) -func f[type P1, P2, P3 interface { +func f[P interface{}](x P) +func f[P1, P2, P3 interface { m1(P1) type P2, P3 }](x1 P1, x2 P2, x3 P3) struct{} -func f[type P](T1[P], T2[P]) T3[P] +func f[P any](T1[P], T2[P]) T3[P] func (x T[P]) m() func (T[P]) m(x T[P]) P diff --git a/src/go/printer/testdata/genericsB.input b/src/go/printer/testdata/genericsB.input index 102163eb40..f137c21e32 100644 --- a/src/go/printer/testdata/genericsB.input +++ b/src/go/printer/testdata/genericsB.input @@ -4,24 +4,21 @@ package generics -type T[type] struct{} -type T[type P] struct{} -type T[type P1, P2, P3] struct{} +type T[P any] struct{} +type T[P1, P2, P3 any] struct{} -type T[type P C] struct{} -type T[type P1, P2, P3, C] struct{} +type T[P C] struct{} +type T[P1, P2, P3, C] struct{} -type T[type P C[P]] struct{} -type T[type P1, P2, P3 C[P1, P2, P3]] struct{} +type T[P C[P]] struct{} +type T[P1, P2, P3 C[P1, P2, P3]] struct{} -func f[type]() -func f[type P](x P) -func f[type P1, P2, P3](x1 P1, x2 P2, x3 P3) struct{} +func f[P any](x P) +func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{} -func f[type]() -func f[type P interface{}](x P) -func f[type P1, P2, P3 interface{ m1(P1); type P2, P3 }](x1 P1, x2 P2, x3 P3) struct{} -func f[type P](T1[P], T2[P]) T3[P] +func f[P interface{}](x P) +func f[P1, P2, P3 interface{ m1(P1); type P2, P3 }](x1 P1, x2 P2, x3 P3) struct{} +func f[P any](T1[P], T2[P]) T3[P] func (x T[P]) m() func ((T[P])) m(x T[P]) P