Skip to content

Commit d3e4b13

Browse files
committed
format: deep compare nodes without go/scanner
We can trick go/format into printing in "compact" form, and then bytes.Equal is enough for our needs.
1 parent 23c4785 commit d3e4b13

File tree

1 file changed

+8
-26
lines changed

1 file changed

+8
-26
lines changed

format/format.go

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"fmt"
1212
"go/ast"
1313
"go/parser"
14-
"go/scanner"
1514
"go/token"
1615
goversion "go/version"
1716
"os"
@@ -1093,42 +1092,25 @@ func (f *fumpter) shouldMergeAdjacentFields(f1, f2 *ast.Field) bool {
10931092

10941093
// Only merge if the types that the syntax nodes represent are equal,
10951094
// e.g. two *ast.Ident nodes "int" are equal, but the two *ast.Ident nodes
1096-
// "string" and "bool" are not.
1095+
// "string" and "bool" are not. We use reflection to quickly discard most cases.
1096+
//
1097+
// We use an empty [token.FileSet] so that positions are ignored when printing,
1098+
// and two syntax nodes with different uses of newlines end up the same.
10971099
//
10981100
// Note that we could in theory use go/types here, but in practice gofumpt
10991101
// needs to be fast, hence it shouldn't rely on expensive typechecking.
11001102
if reflect.TypeOf(f1.Type) != reflect.TypeOf(f2.Type) {
11011103
return false
11021104
}
1105+
emptyFset := token.NewFileSet()
11031106
var b1, b2 bytes.Buffer
1104-
if err := format.Node(&b1, f.fset, f1.Type); err != nil {
1107+
if err := format.Node(&b1, emptyFset, f1.Type); err != nil {
11051108
return false
11061109
}
1107-
if err := format.Node(&b2, f.fset, f2.Type); err != nil {
1110+
if err := format.Node(&b2, emptyFset, f2.Type); err != nil {
11081111
return false
11091112
}
1110-
return equalTokens(b1.Bytes(), b2.Bytes())
1111-
}
1112-
1113-
func equalTokens(a, b []byte) bool {
1114-
if bytes.Equal(a, b) {
1115-
return true
1116-
}
1117-
1118-
var s1, s2 scanner.Scanner
1119-
fset := token.NewFileSet()
1120-
s1.Init(fset.AddFile("", fset.Base(), len(a)), a, nil, 0)
1121-
s2.Init(fset.AddFile("", fset.Base(), len(b)), b, nil, 0)
1122-
for {
1123-
_, tok1, lit1 := s1.Scan()
1124-
_, tok2, lit2 := s2.Scan()
1125-
if tok1 != tok2 || lit1 != lit2 {
1126-
return false
1127-
}
1128-
if tok1 == token.EOF {
1129-
return true
1130-
}
1131-
}
1113+
return bytes.Equal(b1.Bytes(), b2.Bytes())
11321114
}
11331115

11341116
var posType = reflect.TypeOf(token.NoPos)

0 commit comments

Comments
 (0)