diff --git a/godoc/analysis/analysis.go b/godoc/analysis/analysis.go index 54611e87d96..54d692a59ec 100644 --- a/godoc/analysis/analysis.go +++ b/godoc/analysis/analysis.go @@ -62,15 +62,15 @@ type Link interface { // FileInfo holds analysis information for the source file view. // Clients must not mutate it. type FileInfo struct { - Data []interface{} // JSON serializable values - Links []Link // HTML link markup + Data []any // JSON serializable values + Links []Link // HTML link markup } // A fileInfo is the server's store of hyperlinks and JSON data for a // particular file. type fileInfo struct { mu sync.Mutex - data []interface{} // JSON objects + data []any // JSON objects links []Link sorted bool hasErrors bool // TODO(adonovan): surface this in the UI diff --git a/godoc/godoc.go b/godoc/godoc.go index a9d806f7e8b..ac6ab23a0a1 100644 --- a/godoc/godoc.go +++ b/godoc/godoc.go @@ -190,13 +190,13 @@ func (p *Presentation) infoSnippet_htmlFunc(info SpotInfo) string { return `no snippet text available` } -func (p *Presentation) nodeFunc(info *PageInfo, node interface{}) string { +func (p *Presentation) nodeFunc(info *PageInfo, node any) string { var buf bytes.Buffer p.writeNode(&buf, info, info.FSet, node) return buf.String() } -func (p *Presentation) node_htmlFunc(info *PageInfo, node interface{}, linkify bool) string { +func (p *Presentation) node_htmlFunc(info *PageInfo, node any, linkify bool) string { var buf1 bytes.Buffer p.writeNode(&buf1, info, info.FSet, node) @@ -477,9 +477,9 @@ func srcBreadcrumbFunc(relpath string) string { return buf.String() } -func newPosLink_urlFunc(srcPosLinkFunc func(s string, line, low, high int) string) func(info *PageInfo, n interface{}) string { +func newPosLink_urlFunc(srcPosLinkFunc func(s string, line, low, high int) string) func(info *PageInfo, n any) string { // n must be an ast.Node or a *doc.Note - return func(info *PageInfo, n interface{}) string { + return func(info *PageInfo, n any) string { var pos, end token.Pos switch n := n.(type) { @@ -839,7 +839,7 @@ func replaceLeadingIndentation(body, oldIndent, newIndent string) string { // The provided fset must be non-nil. The pageInfo is optional. If // present, the pageInfo is used to add comments to struct fields to // say which version of Go introduced them. -func (p *Presentation) writeNode(w io.Writer, pageInfo *PageInfo, fset *token.FileSet, x interface{}) { +func (p *Presentation) writeNode(w io.Writer, pageInfo *PageInfo, fset *token.FileSet, x any) { // convert trailing tabs into spaces using a tconv filter // to ensure a good outcome in most browsers (there may still // be tabs in comments and strings, but converting those into @@ -918,7 +918,7 @@ var slashSlash = []byte("//") // WriteNode writes x to w. // TODO(bgarcia) Is this method needed? It's just a wrapper for p.writeNode. -func (p *Presentation) WriteNode(w io.Writer, fset *token.FileSet, x interface{}) { +func (p *Presentation) WriteNode(w io.Writer, fset *token.FileSet, x any) { p.writeNode(w, nil, fset, x) } diff --git a/godoc/index.go b/godoc/index.go index 377837a0b36..05a1a9441ee 100644 --- a/godoc/index.go +++ b/godoc/index.go @@ -71,10 +71,10 @@ import ( // InterfaceSlice is a helper type for sorting interface // slices according to some slice-specific sort criteria. -type comparer func(x, y interface{}) bool +type comparer func(x, y any) bool type interfaceSlice struct { - slice []interface{} + slice []any less comparer } @@ -87,7 +87,7 @@ type interfaceSlice struct { // runs. For instance, a RunList containing pairs (x, y) may be compressed // into a RunList containing pair runs (x, {y}) where each run consists of // a list of y's with the same x. -type RunList []interface{} +type RunList []any func (h RunList) sort(less comparer) { sort.Sort(&interfaceSlice{h, less}) @@ -99,7 +99,7 @@ func (p *interfaceSlice) Swap(i, j int) { p.slice[i], p.slice[j] = p.slice[ // Compress entries which are the same according to a sort criteria // (specified by less) into "runs". -func (h RunList) reduce(less comparer, newRun func(h RunList) interface{}) RunList { +func (h RunList) reduce(less comparer, newRun func(h RunList) any) RunList { if len(h) == 0 { return nil } @@ -143,10 +143,10 @@ func (k KindRun) Less(i, j int) bool { return k[i].Lori() < k[j].Lori() } func (k KindRun) Swap(i, j int) { k[i], k[j] = k[j], k[i] } // FileRun contents are sorted by Kind for the reduction into KindRuns. -func lessKind(x, y interface{}) bool { return x.(SpotInfo).Kind() < y.(SpotInfo).Kind() } +func lessKind(x, y any) bool { return x.(SpotInfo).Kind() < y.(SpotInfo).Kind() } // newKindRun allocates a new KindRun from the SpotInfo run h. -func newKindRun(h RunList) interface{} { +func newKindRun(h RunList) any { run := make(KindRun, len(h)) for i, x := range h { run[i] = x.(SpotInfo) @@ -214,7 +214,7 @@ type FileRun struct { } // Spots are sorted by file path for the reduction into FileRuns. -func lessSpot(x, y interface{}) bool { +func lessSpot(x, y any) bool { fx := x.(Spot).File fy := y.(Spot).File // same as "return fx.Path() < fy.Path()" but w/o computing the file path first @@ -224,7 +224,7 @@ func lessSpot(x, y interface{}) bool { } // newFileRun allocates a new FileRun from the Spot run h. -func newFileRun(h RunList) interface{} { +func newFileRun(h RunList) any { file := h[0].(Spot).File // reduce the list of Spots into a list of KindRuns @@ -257,12 +257,12 @@ func (p *PakRun) Less(i, j int) bool { return p.Files[i].File.Name < p.Files[j]. func (p *PakRun) Swap(i, j int) { p.Files[i], p.Files[j] = p.Files[j], p.Files[i] } // FileRuns are sorted by package for the reduction into PakRuns. -func lessFileRun(x, y interface{}) bool { +func lessFileRun(x, y any) bool { return x.(*FileRun).File.Pak.less(y.(*FileRun).File.Pak) } // newPakRun allocates a new PakRun from the *FileRun run h. -func newPakRun(h RunList) interface{} { +func newPakRun(h RunList) any { pak := h[0].(*FileRun).File.Pak files := make([]*FileRun, len(h)) for i, x := range h { @@ -280,7 +280,7 @@ func newPakRun(h RunList) interface{} { type HitList []*PakRun // PakRuns are sorted by package. -func lessPakRun(x, y interface{}) bool { return x.(*PakRun).Pak.less(y.(*PakRun).Pak) } +func lessPakRun(x, y any) bool { return x.(*PakRun).Pak.less(y.(*PakRun).Pak) } func reduce(h0 RunList) HitList { // reduce a list of Spots into a list of FileRuns @@ -325,10 +325,10 @@ type AltWords struct { } // wordPairs are sorted by their canonical spelling. -func lessWordPair(x, y interface{}) bool { return x.(*wordPair).canon < y.(*wordPair).canon } +func lessWordPair(x, y any) bool { return x.(*wordPair).canon < y.(*wordPair).canon } // newAltWords allocates a new AltWords from the *wordPair run h. -func newAltWords(h RunList) interface{} { +func newAltWords(h RunList) any { canon := h[0].(*wordPair).canon alts := make([]string, len(h)) for i, x := range h { @@ -1159,7 +1159,7 @@ func (x *Index) WriteTo(w io.Writer) (n int64, err error) { return 0, err } if fulltext { - encode := func(x interface{}) error { + encode := func(x any) error { return gob.NewEncoder(w).Encode(x) } if err := x.fset.Write(encode); err != nil { @@ -1199,7 +1199,7 @@ func (x *Index) ReadFrom(r io.Reader) (n int64, err error) { x.opts = fx.Opts if fx.Fulltext { x.fset = token.NewFileSet() - decode := func(x interface{}) error { + decode := func(x any) error { return gob.NewDecoder(r).Decode(x) } if err := x.fset.Read(decode); err != nil { diff --git a/godoc/search.go b/godoc/search.go index 33e4febfaaa..a0afb8bf97b 100644 --- a/godoc/search.go +++ b/godoc/search.go @@ -36,7 +36,7 @@ func (c *Corpus) Lookup(query string) SearchResult { // identifier search if r, err := index.Lookup(query); err == nil { result = r - } else if err != nil && !c.IndexFullText { + } else if !c.IndexFullText { // ignore the error if full text search is enabled // since the query may be a valid regular expression result.Alert = "Error in query string: " + err.Error() @@ -127,7 +127,7 @@ func (p *Presentation) HandleSearch(w http.ResponseWriter, r *http.Request) { func (p *Presentation) serveSearchDesc(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/opensearchdescription+xml") - data := map[string]interface{}{ + data := map[string]any{ "BaseURL": fmt.Sprintf("http://%s", r.Host), } applyTemplateToResponseWriter(w, p.SearchDescXML, &data) diff --git a/godoc/server.go b/godoc/server.go index afb28e2e187..92d1ec48d61 100644 --- a/godoc/server.go +++ b/godoc/server.go @@ -502,7 +502,7 @@ func packageExports(fset *token.FileSet, pkg *ast.Package) { } } -func applyTemplate(t *template.Template, name string, data interface{}) []byte { +func applyTemplate(t *template.Template, name string, data any) []byte { var buf bytes.Buffer if err := t.Execute(&buf, data); err != nil { log.Printf("%s.Execute: %s", name, err) @@ -529,7 +529,7 @@ func (w *writerCapturesErr) Write(p []byte) (int, error) { // they come from the template processing and not the Writer; this avoid // polluting log files with error messages due to networking issues, such as // client disconnects and http HEAD protocol violations. -func applyTemplateToResponseWriter(rw http.ResponseWriter, t *template.Template, data interface{}) { +func applyTemplateToResponseWriter(rw http.ResponseWriter, t *template.Template, data any) { w := &writerCapturesErr{w: rw} err := t.Execute(w, data) // There are some cases where template.Execute does not return an error when @@ -839,7 +839,7 @@ func (p *Presentation) ServeText(w http.ResponseWriter, text []byte) { w.Write(text) } -func marshalJSON(x interface{}) []byte { +func marshalJSON(x any) []byte { var data []byte var err error const indentJSON = false // for easier debugging diff --git a/godoc/spec.go b/godoc/spec.go index 9ec94278db5..c8142363e9b 100644 --- a/godoc/spec.go +++ b/godoc/spec.go @@ -38,7 +38,7 @@ func (p *ebnfParser) next() { p.lit = p.scanner.TokenText() } -func (p *ebnfParser) printf(format string, args ...interface{}) { +func (p *ebnfParser) printf(format string, args ...any) { p.flush() fmt.Fprintf(p.out, format, args...) } diff --git a/godoc/template.go b/godoc/template.go index 1e4e42e30e5..4418bea09b5 100644 --- a/godoc/template.go +++ b/godoc/template.go @@ -55,7 +55,7 @@ func (c *Corpus) contents(name string) string { } // stringFor returns a textual representation of the arg, formatted according to its nature. -func stringFor(arg interface{}) string { +func stringFor(arg any) string { switch arg := arg.(type) { case int: return fmt.Sprintf("%d", arg) @@ -70,7 +70,7 @@ func stringFor(arg interface{}) string { return "" } -func (p *Presentation) code(file string, arg ...interface{}) (s string, err error) { +func (p *Presentation) code(file string, arg ...any) (s string, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("%v", r) @@ -85,7 +85,7 @@ func (p *Presentation) code(file string, arg ...interface{}) (s string, err erro command = fmt.Sprintf("code %q", file) case 1: command = fmt.Sprintf("code %q %s", file, stringFor(arg[0])) - text = p.Corpus.oneLine(file, text, arg[0]) + text = p.Corpus.oneLine(file, arg[0]) case 2: command = fmt.Sprintf("code %q %s %s", file, stringFor(arg[0]), stringFor(arg[1])) text = p.Corpus.multipleLines(file, text, arg[0], arg[1]) @@ -105,7 +105,7 @@ func (p *Presentation) code(file string, arg ...interface{}) (s string, err erro } // parseArg returns the integer or string value of the argument and tells which it is. -func parseArg(arg interface{}, file string, max int) (ival int, sval string, isInt bool) { +func parseArg(arg any, file string, max int) (ival int, sval string, isInt bool) { switch n := arg.(type) { case int: if n <= 0 || n > max { @@ -120,7 +120,7 @@ func parseArg(arg interface{}, file string, max int) (ival int, sval string, isI } // oneLine returns the single line generated by a two-argument code invocation. -func (c *Corpus) oneLine(file, text string, arg interface{}) string { +func (c *Corpus) oneLine(file string, arg any) string { lines := strings.SplitAfter(c.contents(file), "\n") line, pattern, isInt := parseArg(arg, file, len(lines)) if isInt { @@ -130,7 +130,7 @@ func (c *Corpus) oneLine(file, text string, arg interface{}) string { } // multipleLines returns the text generated by a three-argument code invocation. -func (c *Corpus) multipleLines(file, text string, arg1, arg2 interface{}) string { +func (c *Corpus) multipleLines(file, text string, arg1, arg2 any) string { lines := strings.SplitAfter(c.contents(file), "\n") line1, pattern1, isInt1 := parseArg(arg1, file, len(lines)) line2, pattern2, isInt2 := parseArg(arg2, file, len(lines)) diff --git a/godoc/util/util.go b/godoc/util/util.go index c08ca785fed..21390556e7f 100644 --- a/godoc/util/util.go +++ b/godoc/util/util.go @@ -18,18 +18,18 @@ import ( // access to it and records the time the value was last set. type RWValue struct { mutex sync.RWMutex - value interface{} + value any timestamp time.Time // time of last set() } -func (v *RWValue) Set(value interface{}) { +func (v *RWValue) Set(value any) { v.mutex.Lock() v.value = value v.timestamp = time.Now() v.mutex.Unlock() } -func (v *RWValue) Get() (interface{}, time.Time) { +func (v *RWValue) Get() (any, time.Time) { v.mutex.RLock() defer v.mutex.RUnlock() return v.value, v.timestamp diff --git a/godoc/vfs/emptyvfs.go b/godoc/vfs/emptyvfs.go index 521bf71a51b..4ab5c7c649e 100644 --- a/godoc/vfs/emptyvfs.go +++ b/godoc/vfs/emptyvfs.go @@ -84,6 +84,6 @@ func (e *emptyVFS) IsDir() bool { return true } -func (e *emptyVFS) Sys() interface{} { +func (e *emptyVFS) Sys() any { return nil } diff --git a/godoc/vfs/mapfs/mapfs.go b/godoc/vfs/mapfs/mapfs.go index 9d0f465eb5e..06fb4f09543 100644 --- a/godoc/vfs/mapfs/mapfs.go +++ b/godoc/vfs/mapfs/mapfs.go @@ -158,9 +158,9 @@ func (fi mapFI) Mode() os.FileMode { } return 0444 } -func (fi mapFI) Name() string { return pathpkg.Base(fi.name) } -func (fi mapFI) Size() int64 { return int64(fi.size) } -func (fi mapFI) Sys() interface{} { return nil } +func (fi mapFI) Name() string { return pathpkg.Base(fi.name) } +func (fi mapFI) Size() int64 { return int64(fi.size) } +func (fi mapFI) Sys() any { return nil } type nopCloser struct { io.ReadSeeker diff --git a/godoc/vfs/namespace.go b/godoc/vfs/namespace.go index 23dd9794312..2566051a293 100644 --- a/godoc/vfs/namespace.go +++ b/godoc/vfs/namespace.go @@ -275,7 +275,7 @@ func (d dirInfo) Size() int64 { return 0 } func (d dirInfo) Mode() os.FileMode { return os.ModeDir | 0555 } func (d dirInfo) ModTime() time.Time { return startTime } func (d dirInfo) IsDir() bool { return true } -func (d dirInfo) Sys() interface{} { return nil } +func (d dirInfo) Sys() any { return nil } var startTime = time.Now() diff --git a/godoc/vfs/zipfs/zipfs.go b/godoc/vfs/zipfs/zipfs.go index 14c9820a1c7..cdf231a1abd 100644 --- a/godoc/vfs/zipfs/zipfs.go +++ b/godoc/vfs/zipfs/zipfs.go @@ -68,7 +68,7 @@ func (fi zipFI) IsDir() bool { return fi.file == nil } -func (fi zipFI) Sys() interface{} { +func (fi zipFI) Sys() any { return nil } diff --git a/present/args.go b/present/args.go index b4f7503b6da..17b9d4e87e8 100644 --- a/present/args.go +++ b/present/args.go @@ -96,7 +96,7 @@ func addrToByteRange(addr string, start int, data []byte) (lo, hi int, err error j = i } pattern := addr[1:i] - lo, hi, err = addrRegexp(data, lo, hi, dir, pattern) + lo, hi, err = addrRegexp(data, hi, dir, pattern) prevc = c addr = addr[j:] continue @@ -202,7 +202,7 @@ func addrNumber(data []byte, lo, hi int, dir byte, n int, charOffset bool) (int, // addrRegexp searches for pattern in the given direction starting at lo, hi. // The direction dir is '+' (search forward from hi) or '-' (search backward from lo). // Backward searches are unimplemented. -func addrRegexp(data []byte, lo, hi int, dir byte, pattern string) (int, int, error) { +func addrRegexp(data []byte, hi int, dir byte, pattern string) (int, int, error) { // We want ^ and $ to work as in sam/acme, so use ?m. re, err := regexp.Compile("(?m:" + pattern + ")") if err != nil { diff --git a/present/code.go b/present/code.go index f00f1f49d0b..d98f8384414 100644 --- a/present/code.go +++ b/present/code.go @@ -238,8 +238,8 @@ func codeLines(src []byte, start, end int) (lines []codeLine) { return } -func parseArgs(name string, line int, args []string) (res []interface{}, err error) { - res = make([]interface{}, len(args)) +func parseArgs(name string, line int, args []string) (res []any, err error) { + res = make([]any, len(args)) for i, v := range args { if len(v) == 0 { return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v) diff --git a/present/parse.go b/present/parse.go index 162a382b060..8b41dd2df52 100644 --- a/present/parse.go +++ b/present/parse.go @@ -15,6 +15,7 @@ import ( "net/url" "os" "regexp" + "slices" "strings" "time" "unicode" @@ -166,7 +167,7 @@ type Elem interface { // renderElem implements the elem template function, used to render // sub-templates. func renderElem(t *template.Template, e Elem) (template.HTML, error) { - var data interface{} = e + var data any = e if s, ok := e.(Section); ok { data = struct { Section @@ -191,7 +192,7 @@ func init() { // execTemplate is a helper to execute a template and return the output as a // template.HTML value. -func execTemplate(t *template.Template, name string, data interface{}) (template.HTML, error) { +func execTemplate(t *template.Template, name string, data any) (template.HTML, error) { b := new(bytes.Buffer) err := t.ExecuteTemplate(b, name, data) if err != nil { @@ -394,7 +395,7 @@ func parseSections(ctx *Context, name, prefix string, lines *Lines, number []int } } section := Section{ - Number: append(append([]int{}, number...), i), + Number: append(slices.Clone(number), i), Title: title, ID: id, } diff --git a/refactor/importgraph/graph.go b/refactor/importgraph/graph.go index d2d8f098b3f..c24ff882c7b 100644 --- a/refactor/importgraph/graph.go +++ b/refactor/importgraph/graph.go @@ -68,7 +68,7 @@ func Build(ctxt *build.Context) (forward, reverse Graph, errors map[string]error err error } - ch := make(chan interface{}) + ch := make(chan any) go func() { sema := make(chan int, 20) // I/O concurrency limiting semaphore diff --git a/refactor/rename/check.go b/refactor/rename/check.go index 8350ad7bc32..4a058321ca4 100644 --- a/refactor/rename/check.go +++ b/refactor/rename/check.go @@ -19,7 +19,7 @@ import ( ) // errorf reports an error (e.g. conflict) and prevents file modification. -func (r *renamer) errorf(pos token.Pos, format string, args ...interface{}) { +func (r *renamer) errorf(pos token.Pos, format string, args ...any) { r.hadConflicts = true reportError(r.iprog.Fset.Position(pos), fmt.Sprintf(format, args...)) }