diff --git a/README.md b/README.md index 546706a..d572972 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Enforce a stricter format than `gofmt`, while being backwards compatible. That is, `gofumpt` is happy with a subset of the formats that `gofmt` is happy with. -The tool is a fork of `gofmt` as of Go 1.21, and requires Go 1.20 or later. +The tool is a fork of `gofmt` as of Go 1.22, and requires Go 1.21 or later. It can be used as a drop-in replacement to format your Go code, and running `gofmt` after `gofumpt` should produce no changes. For example: @@ -15,7 +15,7 @@ For example: gofumpt -l -w . Some of the Go source files in this repository belong to the Go project. -The project includes copies of `go/printer` and `go/doc/comment` as of Go 1.21 +The project includes copies of `go/printer` and `go/doc/comment` as of Go 1.22 to ensure consistent formatting independent of what Go version is being used. The [added formatting rules](#Added-rules) are implemented in the `format` package. diff --git a/internal/govendor/diff/diff.go b/internal/govendor/diff/diff.go index 0aeeb75..6a40b23 100644 --- a/internal/govendor/diff/diff.go +++ b/internal/govendor/diff/diff.go @@ -74,7 +74,7 @@ func Diff(oldName string, old []byte, newName string, new []byte) []byte { continue } - // Expand matching lines as far possible, + // Expand matching lines as far as possible, // establishing that x[start.x:end.x] == y[start.y:end.y]. // Note that on the first (or last) iteration we may (or definitely do) // have an empty match: start.x==end.x and start.y==end.y. diff --git a/internal/govendor/go/doc/comment/html.go b/internal/govendor/go/doc/comment/html.go index bc076f6..9244509 100644 --- a/internal/govendor/go/doc/comment/html.go +++ b/internal/govendor/go/doc/comment/html.go @@ -10,13 +10,13 @@ import ( "strconv" ) -// An htmlPrinter holds the state needed for printing a Doc as HTML. +// An htmlPrinter holds the state needed for printing a [Doc] as HTML. type htmlPrinter struct { *Printer tight bool } -// HTML returns an HTML formatting of the Doc. +// HTML returns an HTML formatting of the [Doc]. // See the [Printer] documentation for ways to customize the HTML output. func (p *Printer) HTML(d *Doc) []byte { hp := &htmlPrinter{Printer: p} diff --git a/internal/govendor/go/doc/comment/parse.go b/internal/govendor/go/doc/comment/parse.go index 372577b..bd42c55 100644 --- a/internal/govendor/go/doc/comment/parse.go +++ b/internal/govendor/go/doc/comment/parse.go @@ -5,7 +5,7 @@ package comment import ( - "sort" + "slices" "strings" "unicode" "unicode/utf8" @@ -176,7 +176,7 @@ type DocLink struct { func (*DocLink) text() {} // A Parser is a doc comment parser. -// The fields in the struct can be filled in before calling Parse +// The fields in the struct can be filled in before calling [Parser.Parse] // in order to customize the details of the parsing process. type Parser struct { // Words is a map of Go identifier words that @@ -260,14 +260,12 @@ func (d *parseDoc) lookupPkg(pkg string) (importPath string, ok bool) { } func isStdPkg(path string) bool { - // TODO(rsc): Use sort.Find once we don't have to worry about - // copying this code into older Go environments. - i := sort.Search(len(stdPkgs), func(i int) bool { return stdPkgs[i] >= path }) - return i < len(stdPkgs) && stdPkgs[i] == path + _, ok := slices.BinarySearch(stdPkgs, path) + return ok } // DefaultLookupPackage is the default package lookup -// function, used when [Parser].LookupPackage is nil. +// function, used when [Parser.LookupPackage] is nil. // It recognizes names of the packages from the standard // library with single-element import paths, such as math, // which would otherwise be impossible to name. @@ -281,7 +279,7 @@ func DefaultLookupPackage(name string) (importPath string, ok bool) { return "", false } -// Parse parses the doc comment text and returns the *Doc form. +// Parse parses the doc comment text and returns the *[Doc] form. // Comment markers (/* // and */) in the text must have already been removed. func (p *Parser) Parse(text string) *Doc { lines := unindent(strings.Split(text, "\n")) diff --git a/internal/govendor/go/doc/comment/print.go b/internal/govendor/go/doc/comment/print.go index e1c070d..a6ae821 100644 --- a/internal/govendor/go/doc/comment/print.go +++ b/internal/govendor/go/doc/comment/print.go @@ -150,7 +150,7 @@ type commentPrinter struct { *Printer } -// Comment returns the standard Go formatting of the Doc, +// Comment returns the standard Go formatting of the [Doc], // without any comment markers. func (p *Printer) Comment(d *Doc) []byte { cp := &commentPrinter{Printer: p} diff --git a/internal/govendor/go/doc/comment/text.go b/internal/govendor/go/doc/comment/text.go index 6f9c2e2..4e4214e 100644 --- a/internal/govendor/go/doc/comment/text.go +++ b/internal/govendor/go/doc/comment/text.go @@ -21,7 +21,7 @@ type textPrinter struct { width int } -// Text returns a textual formatting of the Doc. +// Text returns a textual formatting of the [Doc]. // See the [Printer] documentation for ways to customize the text output. func (p *Printer) Text(d *Doc) []byte { tp := &textPrinter{ diff --git a/internal/govendor/go/format/format.go b/internal/govendor/go/format/format.go index 5540686..63e65e9 100644 --- a/internal/govendor/go/format/format.go +++ b/internal/govendor/go/format/format.go @@ -43,11 +43,11 @@ const parserMode = parser.ParseComments | parser.SkipObjectResolution // Node formats node in canonical gofmt style and writes the result to dst. // -// The node type must be *ast.File, *printer.CommentedNode, []ast.Decl, -// []ast.Stmt, or assignment-compatible to ast.Expr, ast.Decl, ast.Spec, -// or ast.Stmt. Node does not modify node. Imports are not sorted for +// The node type must be *[ast.File], *[printer.CommentedNode], [][ast.Decl], +// [][ast.Stmt], or assignment-compatible to [ast.Expr], [ast.Decl], [ast.Spec], +// or [ast.Stmt]. Node does not modify node. Imports are not sorted for // nodes representing partial source files (for instance, if the node is -// not an *ast.File or a *printer.CommentedNode not wrapping an *ast.File). +// not an *[ast.File] or a *[printer.CommentedNode] not wrapping an *[ast.File]). // // The function may return early (before the entire result is written) // and return a formatting error, for instance due to an incorrect AST. diff --git a/internal/govendor/go/printer/nodes.go b/internal/govendor/go/printer/nodes.go index a58525b..b8c7ded 100644 --- a/internal/govendor/go/printer/nodes.go +++ b/internal/govendor/go/printer/nodes.go @@ -44,10 +44,7 @@ import ( // linebreaks. At the moment there is no easy way to know about // future (not yet interspersed) comments in this function. func (p *printer) linebreak(line, min int, ws whiteSpace, newSection bool) (nbreaks int) { - n := nlimit(line - p.pos.Line) - if n < min { - n = min - } + n := max(nlimit(line-p.pos.Line), min) if n > 0 { p.print(ws) if newSection { @@ -670,9 +667,7 @@ func walkBinary(e *ast.BinaryExpr) (has4, has5 bool, maxProblem int) { h4, h5, mp := walkBinary(l) has4 = has4 || h4 has5 = has5 || h5 - if maxProblem < mp { - maxProblem = mp - } + maxProblem = max(maxProblem, mp) } switch r := e.Y.(type) { @@ -685,9 +680,7 @@ func walkBinary(e *ast.BinaryExpr) (has4, has5 bool, maxProblem int) { h4, h5, mp := walkBinary(r) has4 = has4 || h4 has5 = has5 || h5 - if maxProblem < mp { - maxProblem = mp - } + maxProblem = max(maxProblem, mp) case *ast.StarExpr: if e.Op == token.QUO { // `*/` @@ -699,9 +692,7 @@ func walkBinary(e *ast.BinaryExpr) (has4, has5 bool, maxProblem int) { case "/*", "&&", "&^": maxProblem = 5 case "++", "--": - if maxProblem < 4 { - maxProblem = 4 - } + maxProblem = max(maxProblem, 4) } } return @@ -983,15 +974,24 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) { if len(x.Args) > 1 { depth++ } - var wasIndented bool - if _, ok := x.Fun.(*ast.FuncType); ok { - // conversions to literal function types require parentheses around the type + + // Conversions to literal function types or <-chan + // types require parentheses around the type. + paren := false + switch t := x.Fun.(type) { + case *ast.FuncType: + paren = true + case *ast.ChanType: + paren = t.Dir == ast.RECV + } + if paren { p.print(token.LPAREN) - wasIndented = p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth) + } + wasIndented := p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth) + if paren { p.print(token.RPAREN) - } else { - wasIndented = p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth) } + p.setPos(x.Lparen) p.print(token.LPAREN) if x.Ellipsis.IsValid() { @@ -1739,7 +1739,7 @@ func (p *printer) genDecl(d *ast.GenDecl) { p.setPos(d.Pos()) p.print(d.Tok, blank) - if d.Lparen.IsValid() || len(d.Specs) > 1 { + if d.Lparen.IsValid() || len(d.Specs) != 1 { // group of parenthesized declarations p.setPos(d.Lparen) p.print(token.LPAREN) diff --git a/internal/govendor/go/printer/printer.go b/internal/govendor/go/printer/printer.go index 2ab0278..11c056d 100644 --- a/internal/govendor/go/printer/printer.go +++ b/internal/govendor/go/printer/printer.go @@ -860,10 +860,7 @@ func (p *printer) writeWhitespace(n int) { // nlimit limits n to maxNewlines. func nlimit(n int) int { - if n > maxNewlines { - n = maxNewlines - } - return n + return min(n, maxNewlines) } func mayCombine(prev token.Token, next byte) (b bool) { @@ -1412,7 +1409,7 @@ func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node any, nodeS } // A CommentedNode bundles an AST node and corresponding comments. -// It may be provided as argument to any of the Fprint functions. +// It may be provided as argument to any of the [Fprint] functions. type CommentedNode struct { Node any // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt Comments []*ast.CommentGroup @@ -1420,14 +1417,14 @@ type CommentedNode struct { // Fprint "pretty-prints" an AST node to output for a given configuration cfg. // Position information is interpreted relative to the file set fset. -// The node type must be *ast.File, *CommentedNode, []ast.Decl, []ast.Stmt, -// or assignment-compatible to ast.Expr, ast.Decl, ast.Spec, or ast.Stmt. +// The node type must be *[ast.File], *[CommentedNode], [][ast.Decl], [][ast.Stmt], +// or assignment-compatible to [ast.Expr], [ast.Decl], [ast.Spec], or [ast.Stmt]. func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node any) error { return cfg.fprint(output, fset, node, make(map[ast.Node]int)) } // Fprint "pretty-prints" an AST node to output. -// It calls Config.Fprint with default settings. +// It calls [Config.Fprint] with default settings. // Note that gofmt uses tabs for indentation but spaces for alignment; // use format.Node (package mvdan.cc/gofumpt/internal/govendor/go/format) for output that matches gofmt. func Fprint(output io.Writer, fset *token.FileSet, node any) error { diff --git a/internal/govendor/version.txt b/internal/govendor/version.txt index 010ab74..3c9a034 100644 --- a/internal/govendor/version.txt +++ b/internal/govendor/version.txt @@ -1 +1 @@ -go1.21.0 +go1.22.0