Skip to content

Commit

Permalink
[dev.typeparams] cmd/gofmt: add the -G flag to allow generic code
Browse files Browse the repository at this point in the history
Add support for type parameters to cmd/gofmt, gated behind the -G flag.

The test was based on a test from go/printer, slightly modified to
exercise more formatting.

Change-Id: I489bcb3ad06e1ed4e6d9f5bc79825e60dcfe9953
Reviewed-on: https://go-review.googlesource.com/c/go/+/291011
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
  • Loading branch information
findleyr committed Feb 10, 2021
1 parent ddec18c commit df23540
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/cmd/gofmt/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ The flags are:
Do not print reformatted sources to standard output.
If a file's formatting is different from gofmt's, print its name
to standard output.
-G
Allow generic code, using type parameters.
See golang.org/issues/43651 for more information.
-r rule
Apply the rewrite rule to the source before reformatting.
-s
Expand Down
16 changes: 10 additions & 6 deletions src/cmd/gofmt/gofmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ import (

var (
// main operation modes
list = flag.Bool("l", false, "list files whose formatting differs from gofmt's")
write = flag.Bool("w", false, "write result to (source) file instead of stdout")
rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')")
simplifyAST = flag.Bool("s", false, "simplify code")
doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
allErrors = flag.Bool("e", false, "report all errors (not just the first 10 on different lines)")
list = flag.Bool("l", false, "list files whose formatting differs from gofmt's")
write = flag.Bool("w", false, "write result to (source) file instead of stdout")
rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')")
simplifyAST = flag.Bool("s", false, "simplify code")
doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
allErrors = flag.Bool("e", false, "report all errors (not just the first 10 on different lines)")
allowTypeParams = flag.Bool("G", false, "allow generic code")

// debugging
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file")
Expand Down Expand Up @@ -71,6 +72,9 @@ func initParserMode() {
if *allErrors {
parserMode |= parser.AllErrors
}
if *allowTypeParams {
parserMode |= parser.ParseTypeParams
}
}

func isGoFile(f fs.DirEntry) bool {
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/gofmt/gofmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ func runTest(t *testing.T, in, out string) {
case "-stdin":
// fake flag - pretend input is from stdin
stdin = true
case "-G":
*allowTypeParams = true
default:
t.Errorf("unrecognized flag name: %s", name)
}
Expand Down
35 changes: 35 additions & 0 deletions src/cmd/gofmt/testdata/typeparams.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//gofmt -G

package typeparams

type T[P any] struct{}
type T[P1, P2, P3 any] struct{}

type T[P C] struct{}
type T[P1, P2, P3 C] struct{}

type T[P C[P]] struct{}
type T[P1, P2, P3 C[P1, P2, P3]] struct{}

func f[P any](x P)
func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}

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

func _() {
type _ []T[P]
var _ []T[P]
_ = []T[P]{}
}
32 changes: 32 additions & 0 deletions src/cmd/gofmt/testdata/typeparams.input
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//gofmt -G

package typeparams

type T[ P any] struct{}
type T[P1, P2, P3 any] struct{}

type T[P C] struct{}
type T[P1,P2, P3 C] struct{}

type T[P C[P]] struct{}
type T[P1, P2, P3 C[P1,P2,P3]] struct{}

func f[P any](x P)
func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}

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

func _() {
type _ []T[P]
var _ []T[P]
_ = []T[P]{}
}

0 comments on commit df23540

Please sign in to comment.