internal/tokeninternal: AddExistingFiles: tweaks for proposal
This CL clarifies AddExistingFiles in preparation for its
proposal as an upstream change. The two helpers FileSetFor
and CloneFileSet are demonstrably mere convenience functions.
Updates golang/go#73205
Change-Id: I9b83dc46575417ac074d91f3d5bed942b522da6b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/663596
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/internal/tokeninternal/tokeninternal.go b/internal/tokeninternal/tokeninternal.go
index 0a73e2e..549bb18 100644
--- a/internal/tokeninternal/tokeninternal.go
+++ b/internal/tokeninternal/tokeninternal.go
@@ -9,6 +9,7 @@
import (
"fmt"
"go/token"
+ "slices"
"sort"
"sync"
"sync/atomic"
@@ -18,7 +19,29 @@
// AddExistingFiles adds the specified files to the FileSet if they
// are not already present. It panics if any pair of files in the
// resulting FileSet would overlap.
+//
+// TODO(adonovan): add this a method to FileSet; see
+// https://github.com/golang/go/issues/73205
func AddExistingFiles(fset *token.FileSet, files []*token.File) {
+
+ // This function cannot be implemented as:
+ //
+ // for _, file := range files {
+ // if prev := fset.File(token.Pos(file.Base())); prev != nil {
+ // if prev != file {
+ // panic("FileSet contains a different file at the same base")
+ // }
+ // continue
+ // }
+ // file2 := fset.AddFile(file.Name(), file.Base(), file.Size())
+ // file2.SetLines(file.Lines())
+ // }
+ //
+ // because all calls to AddFile must be in increasing order.
+ // AddExistingFiles lets us augment an existing FileSet
+ // sequentially, so long as all sets of files have disjoint
+ // ranges.
+
// Punch through the FileSet encapsulation.
type tokenFileSet struct {
// This type remained essentially consistent from go1.16 to go1.21.
@@ -83,10 +106,7 @@
// of their Base.
func FileSetFor(files ...*token.File) *token.FileSet {
fset := token.NewFileSet()
- for _, f := range files {
- f2 := fset.AddFile(f.Name(), f.Base(), f.Size())
- f2.SetLines(f.Lines())
- }
+ AddExistingFiles(fset, files)
return fset
}
@@ -94,12 +114,5 @@
// create copies of the token.Files in fset: they are added to the resulting
// FileSet unmodified.
func CloneFileSet(fset *token.FileSet) *token.FileSet {
- var files []*token.File
- fset.Iterate(func(f *token.File) bool {
- files = append(files, f)
- return true
- })
- newFileSet := token.NewFileSet()
- AddExistingFiles(newFileSet, files)
- return newFileSet
+ return FileSetFor(slices.Collect(fset.Iterate)...)
}